Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendirctl.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: drivers/filesastems/npfs/dirctl.c 00005 * PURPOSE: Named pipe filesystem 00006 * PROGRAMMER: Eric Kohl 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include "npfs.h" 00012 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* FUNCTIONS *****************************************************************/ 00017 00018 static NTSTATUS 00019 NpfsQueryDirectory(PNPFS_CCB Ccb, 00020 PIRP Irp, 00021 PULONG Size) 00022 { 00023 PIO_STACK_LOCATION Stack; 00024 ULONG BufferLength = 0; 00025 PUNICODE_STRING SearchPattern = NULL; 00026 FILE_INFORMATION_CLASS FileInformationClass; 00027 ULONG FileIndex = 0; 00028 PUCHAR Buffer = NULL; 00029 BOOLEAN First = FALSE; 00030 PLIST_ENTRY CurrentEntry; 00031 PNPFS_VCB Vcb; 00032 PNPFS_FCB PipeFcb; 00033 ULONG PipeIndex; 00034 NTSTATUS Status = STATUS_SUCCESS; 00035 PFILE_NAMES_INFORMATION NamesBuffer; 00036 PFILE_DIRECTORY_INFORMATION DirectoryBuffer; 00037 PFILE_FULL_DIR_INFORMATION FullDirBuffer; 00038 PFILE_BOTH_DIR_INFORMATION BothDirBuffer; 00039 ULONG InfoSize = 0; 00040 ULONG NameLength; 00041 ULONG CurrentOffset = 0; 00042 ULONG LastOffset = 0; 00043 PULONG NextEntryOffset; 00044 00045 Stack = IoGetCurrentIrpStackLocation(Irp); 00046 00047 /* Obtain the callers parameters */ 00048 BufferLength = Stack->Parameters.QueryDirectory.Length; 00049 SearchPattern = Stack->Parameters.QueryDirectory.FileName; 00050 FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass; 00051 FileIndex = Stack->Parameters.QueryDirectory.FileIndex; 00052 00053 DPRINT("SearchPattern: %p '%wZ'\n", SearchPattern, SearchPattern); 00054 00055 /* Determine Buffer for result */ 00056 if (Irp->MdlAddress) 00057 { 00058 Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); 00059 } 00060 else 00061 { 00062 Buffer = Irp->UserBuffer; 00063 } 00064 00065 /* Build the search pattern string */ 00066 DPRINT("Ccb->u.Directory.SearchPattern.Buffer: %p\n", Ccb->u.Directory.SearchPattern.Buffer); 00067 if (Ccb->u.Directory.SearchPattern.Buffer == NULL) 00068 { 00069 First = TRUE; 00070 00071 if (SearchPattern != NULL) 00072 { 00073 Ccb->u.Directory.SearchPattern.Buffer = 00074 ExAllocatePoolWithTag(NonPagedPool, 00075 SearchPattern->Length + sizeof(WCHAR), 00076 TAG_NPFS_NAMEBLOCK); 00077 if (Ccb->u.Directory.SearchPattern.Buffer == NULL) 00078 { 00079 return STATUS_INSUFFICIENT_RESOURCES; 00080 } 00081 00082 Ccb->u.Directory.SearchPattern.Length = SearchPattern->Length; 00083 Ccb->u.Directory.SearchPattern.MaximumLength = SearchPattern->Length + sizeof(WCHAR); 00084 RtlCopyMemory(Ccb->u.Directory.SearchPattern.Buffer, 00085 SearchPattern->Buffer, 00086 SearchPattern->Length); 00087 Ccb->u.Directory.SearchPattern.Buffer[SearchPattern->Length / sizeof(WCHAR)] = 0; 00088 } 00089 else 00090 { 00091 Ccb->u.Directory.SearchPattern.Buffer = 00092 ExAllocatePoolWithTag(NonPagedPool, 00093 2 * sizeof(WCHAR), 00094 TAG_NPFS_NAMEBLOCK); 00095 if (Ccb->u.Directory.SearchPattern.Buffer == NULL) 00096 { 00097 return STATUS_INSUFFICIENT_RESOURCES; 00098 } 00099 00100 Ccb->u.Directory.SearchPattern.Length = sizeof(WCHAR); 00101 Ccb->u.Directory.SearchPattern.MaximumLength = 2 * sizeof(WCHAR); 00102 Ccb->u.Directory.SearchPattern.Buffer[0] = L'*'; 00103 Ccb->u.Directory.SearchPattern.Buffer[1] = 0; 00104 } 00105 } 00106 DPRINT("Search pattern: '%wZ'\n", &Ccb->u.Directory.SearchPattern); 00107 00108 /* Determine the file index */ 00109 if (First || (Stack->Flags & SL_RESTART_SCAN)) 00110 { 00111 FileIndex = 0; 00112 } 00113 else if ((Stack->Flags & SL_INDEX_SPECIFIED) == 0) 00114 { 00115 FileIndex = Ccb->u.Directory.FileIndex + 1; 00116 } 00117 DPRINT("FileIndex: %lu\n", FileIndex); 00118 00119 DPRINT("Buffer = %p tofind = %wZ\n", Buffer, &Ccb->u.Directory.SearchPattern); 00120 00121 switch (FileInformationClass) 00122 { 00123 case FileDirectoryInformation: 00124 InfoSize = sizeof(FILE_DIRECTORY_INFORMATION) - sizeof(WCHAR); 00125 break; 00126 00127 case FileFullDirectoryInformation: 00128 InfoSize = sizeof(FILE_FULL_DIR_INFORMATION) - sizeof(WCHAR); 00129 break; 00130 00131 case FileBothDirectoryInformation: 00132 InfoSize = sizeof(FILE_BOTH_DIR_INFORMATION) - sizeof(WCHAR); 00133 break; 00134 00135 case FileNamesInformation: 00136 InfoSize = sizeof(FILE_NAMES_INFORMATION) - sizeof(WCHAR); 00137 break; 00138 00139 default: 00140 DPRINT1("Invalid information class: %lu\n", FileInformationClass); 00141 return STATUS_INVALID_INFO_CLASS; 00142 } 00143 00144 PipeIndex = 0; 00145 00146 Vcb = Ccb->Fcb->Vcb; 00147 CurrentEntry = Vcb->PipeListHead.Flink; 00148 while (CurrentEntry != &Vcb->PipeListHead && 00149 Status == STATUS_SUCCESS) 00150 { 00151 /* Get the FCB of the next pipe */ 00152 PipeFcb = CONTAINING_RECORD(CurrentEntry, 00153 NPFS_FCB, 00154 PipeListEntry); 00155 00156 /* Make sure it is a pipe FCB */ 00157 ASSERT(PipeFcb->Type == FCB_PIPE); 00158 00159 DPRINT("PipeName: %wZ\n", &PipeFcb->PipeName); 00160 00161 if (FsRtlIsNameInExpression(&Ccb->u.Directory.SearchPattern, 00162 &PipeFcb->PipeName, 00163 TRUE, 00164 NULL)) 00165 { 00166 DPRINT("Found pipe: %wZ\n", &PipeFcb->PipeName); 00167 00168 if (PipeIndex >= FileIndex) 00169 { 00170 /* Determine whether or not the full pipe name fits into the buffer */ 00171 if (InfoSize + PipeFcb->PipeName.Length > BufferLength) 00172 { 00173 NameLength = BufferLength - InfoSize; 00174 Status = STATUS_BUFFER_OVERFLOW; 00175 } 00176 else 00177 { 00178 NameLength = PipeFcb->PipeName.Length; 00179 Status = STATUS_SUCCESS; 00180 } 00181 00182 /* Initialize the information struct */ 00183 RtlZeroMemory(&Buffer[CurrentOffset], InfoSize); 00184 00185 switch (FileInformationClass) 00186 { 00187 case FileDirectoryInformation: 00188 DirectoryBuffer = (PFILE_DIRECTORY_INFORMATION)&Buffer[CurrentOffset]; 00189 DirectoryBuffer->FileIndex = PipeIndex; 00190 DirectoryBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL; 00191 DirectoryBuffer->EndOfFile.QuadPart = PipeFcb->CurrentInstances; 00192 DirectoryBuffer->AllocationSize.LowPart = PipeFcb->MaximumInstances; 00193 DirectoryBuffer->FileNameLength = NameLength; 00194 RtlCopyMemory(DirectoryBuffer->FileName, 00195 PipeFcb->PipeName.Buffer, 00196 NameLength); 00197 break; 00198 00199 case FileFullDirectoryInformation: 00200 FullDirBuffer = (PFILE_FULL_DIR_INFORMATION)&Buffer[CurrentOffset]; 00201 FullDirBuffer->FileIndex = PipeIndex; 00202 FullDirBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL; 00203 FullDirBuffer->EndOfFile.QuadPart = PipeFcb->CurrentInstances; 00204 FullDirBuffer->AllocationSize.LowPart = PipeFcb->MaximumInstances; 00205 FullDirBuffer->FileNameLength = NameLength; 00206 RtlCopyMemory(FullDirBuffer->FileName, 00207 PipeFcb->PipeName.Buffer, 00208 NameLength); 00209 break; 00210 00211 case FileBothDirectoryInformation: 00212 BothDirBuffer = (PFILE_BOTH_DIR_INFORMATION)&Buffer[CurrentOffset]; 00213 BothDirBuffer->NextEntryOffset = 0; 00214 BothDirBuffer->FileIndex = PipeIndex; 00215 BothDirBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL; 00216 BothDirBuffer->EndOfFile.QuadPart = PipeFcb->CurrentInstances; 00217 BothDirBuffer->AllocationSize.LowPart = PipeFcb->MaximumInstances; 00218 BothDirBuffer->FileNameLength = NameLength; 00219 RtlCopyMemory(BothDirBuffer->FileName, 00220 PipeFcb->PipeName.Buffer, 00221 NameLength); 00222 break; 00223 00224 case FileNamesInformation: 00225 NamesBuffer = (PFILE_NAMES_INFORMATION)&Buffer[CurrentOffset]; 00226 NamesBuffer->FileIndex = PipeIndex; 00227 NamesBuffer->FileNameLength = NameLength; 00228 RtlCopyMemory(NamesBuffer->FileName, 00229 PipeFcb->PipeName.Buffer, 00230 NameLength); 00231 break; 00232 00233 default: 00234 /* Should never happen! */ 00235 ASSERT(FALSE); 00236 break; 00237 } 00238 00239 DPRINT("CurrentOffset: %lu\n", CurrentOffset); 00240 00241 /* Store the current pipe index in the CCB */ 00242 Ccb->u.Directory.FileIndex = PipeIndex; 00243 00244 /* Get the pointer to the previous entries NextEntryOffset */ 00245 NextEntryOffset = (PULONG)&Buffer[LastOffset]; 00246 00247 /* Set the previous entries NextEntryOffset */ 00248 *NextEntryOffset = CurrentOffset - LastOffset; 00249 00250 /* Return the used buffer size */ 00251 *Size = CurrentOffset + InfoSize + NameLength; 00252 00253 /* Leave, if there is no space left in the buffer */ 00254 if (Status == STATUS_BUFFER_OVERFLOW) 00255 return Status; 00256 00257 /* Leave, if we should return only one entry */ 00258 if (Stack->Flags & SL_RETURN_SINGLE_ENTRY) 00259 return STATUS_SUCCESS; 00260 00261 /* Store the current offset for the next round */ 00262 LastOffset = CurrentOffset; 00263 00264 /* Set the offset for the next entry */ 00265 CurrentOffset += ROUND_UP(InfoSize + NameLength, sizeof(ULONG)); 00266 } 00267 00268 PipeIndex++; 00269 } 00270 00271 CurrentEntry = CurrentEntry->Flink; 00272 } 00273 00274 /* Return STATUS_NO_MORE_FILES if no matching pipe name was found */ 00275 if (CurrentOffset == 0) 00276 Status = STATUS_NO_MORE_FILES; 00277 00278 return Status; 00279 } 00280 00281 00282 NTSTATUS NTAPI 00283 NpfsDirectoryControl(PDEVICE_OBJECT DeviceObject, 00284 PIRP Irp) 00285 { 00286 PIO_STACK_LOCATION IoStack; 00287 PFILE_OBJECT FileObject; 00288 PNPFS_CCB Ccb; 00289 //PNPFS_FCB Fcb; 00290 NTSTATUS Status; 00291 ULONG Size = 0; 00292 00293 DPRINT("NpfsDirectoryControl() called\n"); 00294 00295 IoStack = IoGetCurrentIrpStackLocation(Irp); 00296 00297 FileObject = IoStack->FileObject; 00298 00299 if (NpfsGetCcb(FileObject, &Ccb) != CCB_DIRECTORY) 00300 { 00301 Status = STATUS_INVALID_PARAMETER; 00302 00303 Irp->IoStatus.Status = Status; 00304 Irp->IoStatus.Information = 0; 00305 00306 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00307 00308 return Status; 00309 } 00310 00311 //Fcb = Ccb->Fcb; 00312 00313 switch (IoStack->MinorFunction) 00314 { 00315 case IRP_MN_QUERY_DIRECTORY: 00316 Status = NpfsQueryDirectory(Ccb, 00317 Irp, 00318 &Size); 00319 break; 00320 00321 case IRP_MN_NOTIFY_CHANGE_DIRECTORY: 00322 DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n"); 00323 Status = STATUS_NOT_IMPLEMENTED; 00324 break; 00325 00326 default: 00327 DPRINT1("NPFS: MinorFunction %d\n", IoStack->MinorFunction); 00328 Status = STATUS_INVALID_DEVICE_REQUEST; 00329 break; 00330 } 00331 00332 Irp->IoStatus.Status = Status; 00333 Irp->IoStatus.Information = Size; 00334 00335 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00336 00337 return Status; 00338 } 00339 00340 /* EOF */ Generated on Sat May 26 2012 04:26:05 for ReactOS by
1.7.6.1
|