Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendir.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/fs/vfat/dir.c 00005 * PURPOSE: VFAT Filesystem : directory control 00006 * UPDATE HISTORY: 00007 19-12-1998 : created 00008 00009 */ 00010 00011 #define NDEBUG 00012 #include "vfat.h" 00013 00014 00015 // function like DosDateTimeToFileTime 00016 BOOLEAN 00017 FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime) 00018 { 00019 PDOSTIME pdtime = (PDOSTIME) &DosTime; 00020 PDOSDATE pddate = (PDOSDATE) &DosDate; 00021 TIME_FIELDS TimeFields; 00022 LARGE_INTEGER LocalTime; 00023 00024 if (SystemTime == NULL) 00025 return FALSE; 00026 00027 TimeFields.Milliseconds = 0; 00028 TimeFields.Second = pdtime->Second * 2; 00029 TimeFields.Minute = pdtime->Minute; 00030 TimeFields.Hour = pdtime->Hour; 00031 00032 TimeFields.Day = pddate->Day; 00033 TimeFields.Month = pddate->Month; 00034 TimeFields.Year = (CSHORT)(DeviceExt->BaseDateYear + pddate->Year); 00035 00036 RtlTimeFieldsToTime (&TimeFields, &LocalTime); 00037 ExLocalTimeToSystemTime(&LocalTime, SystemTime); 00038 00039 return TRUE; 00040 } 00041 00042 // function like FileTimeToDosDateTime 00043 BOOLEAN 00044 FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, USHORT *pDosDate, USHORT *pDosTime) 00045 { 00046 PDOSTIME pdtime = (PDOSTIME) pDosTime; 00047 PDOSDATE pddate = (PDOSDATE) pDosDate; 00048 TIME_FIELDS TimeFields; 00049 LARGE_INTEGER LocalTime; 00050 00051 if (SystemTime == NULL) 00052 return FALSE; 00053 00054 ExSystemTimeToLocalTime (SystemTime, &LocalTime); 00055 RtlTimeToTimeFields (&LocalTime, &TimeFields); 00056 00057 if (pdtime) 00058 { 00059 pdtime->Second = TimeFields.Second / 2; 00060 pdtime->Minute = TimeFields.Minute; 00061 pdtime->Hour = TimeFields.Hour; 00062 } 00063 00064 if (pddate) 00065 { 00066 pddate->Day = TimeFields.Day; 00067 pddate->Month = TimeFields.Month; 00068 pddate->Year = (USHORT) (TimeFields.Year - DeviceExt->BaseDateYear); 00069 } 00070 00071 return TRUE; 00072 } 00073 00074 #define ULONG_ROUND_UP(x) ROUND_UP((x), (sizeof(ULONG))) 00075 00076 static NTSTATUS 00077 VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext, 00078 PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength) 00079 { 00080 if ((sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength) 00081 return STATUS_BUFFER_OVERFLOW; 00082 pInfo->FileNameLength = DirContext->LongNameU.Length; 00083 pInfo->NextEntryOffset = 00084 ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length); 00085 RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length); 00086 return STATUS_SUCCESS; 00087 } 00088 00089 static NTSTATUS 00090 VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext, 00091 PDEVICE_EXTENSION DeviceExt, 00092 PFILE_DIRECTORY_INFORMATION pInfo, 00093 ULONG BufferLength) 00094 { 00095 if ((sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength) 00096 return STATUS_BUFFER_OVERFLOW; 00097 pInfo->FileNameLength = DirContext->LongNameU.Length; 00098 pInfo->NextEntryOffset = 00099 ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length); 00100 RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length); 00101 // pInfo->FileIndex=; 00102 if (DeviceExt->Flags & VCB_IS_FATX) 00103 { 00104 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate, 00105 DirContext->DirEntry.FatX.CreationTime, 00106 &pInfo->CreationTime); 00107 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate, 00108 DirContext->DirEntry.FatX.AccessTime, 00109 &pInfo->LastAccessTime); 00110 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate, 00111 DirContext->DirEntry.FatX.UpdateTime, 00112 &pInfo->LastWriteTime); 00113 pInfo->ChangeTime = pInfo->LastWriteTime; 00114 if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY) 00115 { 00116 pInfo->EndOfFile.QuadPart = 0; 00117 pInfo->AllocationSize.QuadPart = 0; 00118 } 00119 else 00120 { 00121 pInfo->EndOfFile.u.HighPart = 0; 00122 pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize; 00123 /* Make allocsize a rounded up multiple of BytesPerCluster */ 00124 pInfo->AllocationSize.u.HighPart = 0; 00125 pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster); 00126 } 00127 pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f; 00128 } 00129 else 00130 { 00131 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate, 00132 DirContext->DirEntry.Fat.CreationTime, 00133 &pInfo->CreationTime); 00134 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 0, 00135 &pInfo->LastAccessTime); 00136 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate, 00137 DirContext->DirEntry.Fat.UpdateTime, 00138 &pInfo->LastWriteTime); 00139 pInfo->ChangeTime = pInfo->LastWriteTime; 00140 if (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY) 00141 { 00142 pInfo->EndOfFile.QuadPart = 0; 00143 pInfo->AllocationSize.QuadPart = 0; 00144 } 00145 else 00146 { 00147 pInfo->EndOfFile.u.HighPart = 0; 00148 pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize; 00149 /* Make allocsize a rounded up multiple of BytesPerCluster */ 00150 pInfo->AllocationSize.u.HighPart = 0; 00151 pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster); 00152 } 00153 pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f; 00154 } 00155 00156 return STATUS_SUCCESS; 00157 } 00158 00159 static NTSTATUS 00160 VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext, 00161 PDEVICE_EXTENSION DeviceExt, 00162 PFILE_FULL_DIR_INFORMATION pInfo, 00163 ULONG BufferLength) 00164 { 00165 if ((sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength) 00166 return STATUS_BUFFER_OVERFLOW; 00167 pInfo->FileNameLength = DirContext->LongNameU.Length; 00168 pInfo->NextEntryOffset = 00169 ULONG_ROUND_UP (sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length); 00170 RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length); 00171 // pInfo->FileIndex=; 00172 if (DeviceExt->Flags & VCB_IS_FATX) 00173 { 00174 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate, 00175 DirContext->DirEntry.FatX.CreationTime, 00176 &pInfo->CreationTime); 00177 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate, 00178 DirContext->DirEntry.FatX.AccessTime, 00179 &pInfo->LastAccessTime); 00180 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate, 00181 DirContext->DirEntry.FatX.UpdateTime, 00182 &pInfo->LastWriteTime); 00183 pInfo->ChangeTime = pInfo->LastWriteTime; 00184 pInfo->EndOfFile.u.HighPart = 0; 00185 pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize; 00186 /* Make allocsize a rounded up multiple of BytesPerCluster */ 00187 pInfo->AllocationSize.u.HighPart = 0; 00188 pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster); 00189 pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f; 00190 } 00191 else 00192 { 00193 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate, 00194 DirContext->DirEntry.Fat.CreationTime, 00195 &pInfo->CreationTime); 00196 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 00197 0, &pInfo->LastAccessTime); 00198 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate, 00199 DirContext->DirEntry.Fat.UpdateTime, 00200 &pInfo->LastWriteTime); 00201 pInfo->ChangeTime = pInfo->LastWriteTime; 00202 pInfo->EndOfFile.u.HighPart = 0; 00203 pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize; 00204 /* Make allocsize a rounded up multiple of BytesPerCluster */ 00205 pInfo->AllocationSize.u.HighPart = 0; 00206 pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster); 00207 pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f; 00208 } 00209 // pInfo->EaSize=; 00210 return STATUS_SUCCESS; 00211 } 00212 00213 static NTSTATUS 00214 VfatGetFileBothInformation (PVFAT_DIRENTRY_CONTEXT DirContext, 00215 PDEVICE_EXTENSION DeviceExt, 00216 PFILE_BOTH_DIR_INFORMATION pInfo, 00217 ULONG BufferLength) 00218 { 00219 if ((sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength) 00220 return STATUS_BUFFER_OVERFLOW; 00221 00222 if (DeviceExt->Flags & VCB_IS_FATX) 00223 { 00224 pInfo->FileNameLength = DirContext->LongNameU.Length; 00225 RtlCopyMemory(pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length); 00226 pInfo->NextEntryOffset = 00227 ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length); 00228 pInfo->ShortName[0] = 0; 00229 pInfo->ShortNameLength = 0; 00230 // pInfo->FileIndex=; 00231 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate, 00232 DirContext->DirEntry.FatX.CreationTime, 00233 &pInfo->CreationTime); 00234 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate, 00235 DirContext->DirEntry.FatX.AccessTime, 00236 &pInfo->LastAccessTime); 00237 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate, 00238 DirContext->DirEntry.FatX.UpdateTime, 00239 &pInfo->LastWriteTime); 00240 pInfo->ChangeTime = pInfo->LastWriteTime; 00241 if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY) 00242 { 00243 pInfo->EndOfFile.QuadPart = 0; 00244 pInfo->AllocationSize.QuadPart = 0; 00245 } 00246 else 00247 { 00248 pInfo->EndOfFile.u.HighPart = 0; 00249 pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize; 00250 /* Make allocsize a rounded up multiple of BytesPerCluster */ 00251 pInfo->AllocationSize.u.HighPart = 0; 00252 pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster); 00253 } 00254 pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f; 00255 } 00256 else 00257 { 00258 pInfo->FileNameLength = DirContext->LongNameU.Length; 00259 pInfo->NextEntryOffset = 00260 ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length); 00261 RtlCopyMemory(pInfo->ShortName, DirContext->ShortNameU.Buffer, DirContext->ShortNameU.Length); 00262 pInfo->ShortNameLength = (CCHAR)DirContext->ShortNameU.Length; 00263 RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length); 00264 // pInfo->FileIndex=; 00265 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate, 00266 DirContext->DirEntry.Fat.CreationTime, 00267 &pInfo->CreationTime); 00268 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 0, 00269 &pInfo->LastAccessTime); 00270 FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate, 00271 DirContext->DirEntry.Fat.UpdateTime, 00272 &pInfo->LastWriteTime); 00273 pInfo->ChangeTime = pInfo->LastWriteTime; 00274 if (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY) 00275 { 00276 pInfo->EndOfFile.QuadPart = 0; 00277 pInfo->AllocationSize.QuadPart = 0; 00278 } 00279 else 00280 { 00281 pInfo->EndOfFile.u.HighPart = 0; 00282 pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize; 00283 /* Make allocsize a rounded up multiple of BytesPerCluster */ 00284 pInfo->AllocationSize.u.HighPart = 0; 00285 pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster); 00286 } 00287 pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f; 00288 } 00289 pInfo->EaSize=0; 00290 return STATUS_SUCCESS; 00291 } 00292 00293 static NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext) 00294 { 00295 NTSTATUS RC = STATUS_SUCCESS; 00296 long BufferLength = 0; 00297 PUNICODE_STRING pSearchPattern = NULL; 00298 FILE_INFORMATION_CLASS FileInformationClass; 00299 unsigned char *Buffer = NULL; 00300 PFILE_NAMES_INFORMATION Buffer0 = NULL; 00301 PVFATFCB pFcb; 00302 PVFATCCB pCcb; 00303 BOOLEAN FirstQuery = FALSE; 00304 BOOLEAN FirstCall = TRUE; 00305 VFAT_DIRENTRY_CONTEXT DirContext; 00306 WCHAR LongNameBuffer[LONGNAME_MAX_LENGTH + 1]; 00307 WCHAR ShortNameBuffer[13]; 00308 00309 PIO_STACK_LOCATION Stack = IrpContext->Stack; 00310 00311 pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2; 00312 pFcb = (PVFATFCB) IrpContext->FileObject->FsContext; 00313 00314 // determine Buffer for result : 00315 BufferLength = Stack->Parameters.QueryDirectory.Length; 00316 #if 0 00317 /* Do not probe the user buffer until SEH is available */ 00318 if (IrpContext->Irp->RequestorMode != KernelMode && 00319 IrpContext->Irp->MdlAddress == NULL && 00320 IrpContext->Irp->UserBuffer != NULL) 00321 { 00322 ProbeForWrite(IrpContext->Irp->UserBuffer, BufferLength, 1); 00323 } 00324 #endif 00325 Buffer = VfatGetUserBuffer(IrpContext->Irp); 00326 00327 if (!ExAcquireResourceSharedLite(&pFcb->MainResource, 00328 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) 00329 { 00330 RC = VfatLockUserBuffer(IrpContext->Irp, BufferLength, IoWriteAccess); 00331 if (NT_SUCCESS(RC)) 00332 { 00333 RC = STATUS_PENDING; 00334 } 00335 return RC; 00336 } 00337 00338 /* Obtain the callers parameters */ 00339 #ifdef _MSC_VER 00340 /* HACKHACK: Bug in the MS ntifs.h header: 00341 * FileName is really a PUNICODE_STRING, not a PSTRING */ 00342 pSearchPattern = (PUNICODE_STRING)Stack->Parameters.QueryDirectory.FileName; 00343 #else 00344 pSearchPattern = Stack->Parameters.QueryDirectory.FileName; 00345 #endif 00346 FileInformationClass = 00347 Stack->Parameters.QueryDirectory.FileInformationClass; 00348 if (pSearchPattern) 00349 { 00350 if (!pCcb->SearchPattern.Buffer) 00351 { 00352 FirstQuery = TRUE; 00353 pCcb->SearchPattern.MaximumLength = pSearchPattern->Length + sizeof(WCHAR); 00354 pCcb->SearchPattern.Buffer = ExAllocatePoolWithTag(NonPagedPool, pCcb->SearchPattern.MaximumLength, TAG_VFAT); 00355 if (!pCcb->SearchPattern.Buffer) 00356 { 00357 ExReleaseResourceLite(&pFcb->MainResource); 00358 return STATUS_INSUFFICIENT_RESOURCES; 00359 } 00360 RtlCopyUnicodeString(&pCcb->SearchPattern, pSearchPattern); 00361 pCcb->SearchPattern.Buffer[pCcb->SearchPattern.Length / sizeof(WCHAR)] = 0; 00362 } 00363 } 00364 else if (!pCcb->SearchPattern.Buffer) 00365 { 00366 FirstQuery = TRUE; 00367 pCcb->SearchPattern.MaximumLength = 2 * sizeof(WCHAR); 00368 pCcb->SearchPattern.Buffer = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), TAG_VFAT); 00369 if (!pCcb->SearchPattern.Buffer) 00370 { 00371 ExReleaseResourceLite(&pFcb->MainResource); 00372 return STATUS_INSUFFICIENT_RESOURCES; 00373 } 00374 pCcb->SearchPattern.Buffer[0] = L'*'; 00375 pCcb->SearchPattern.Buffer[1] = 0; 00376 pCcb->SearchPattern.Length = sizeof(WCHAR); 00377 } 00378 00379 if (IrpContext->Stack->Flags & SL_INDEX_SPECIFIED) 00380 { 00381 DirContext.DirIndex = pCcb->Entry = Stack->Parameters.QueryDirectory.FileIndex; 00382 } 00383 else if (FirstQuery || (IrpContext->Stack->Flags & SL_RESTART_SCAN)) 00384 { 00385 DirContext.DirIndex = pCcb->Entry = 0; 00386 } 00387 else 00388 { 00389 DirContext.DirIndex = pCcb->Entry; 00390 } 00391 00392 DPRINT ("Buffer=%p tofind=%wZ\n", Buffer, &pCcb->SearchPattern); 00393 00394 DirContext.LongNameU.Buffer = LongNameBuffer; 00395 DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer); 00396 DirContext.ShortNameU.Buffer = ShortNameBuffer; 00397 DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer); 00398 00399 while (RC == STATUS_SUCCESS && BufferLength > 0) 00400 { 00401 RC = FindFile (IrpContext->DeviceExt, pFcb, 00402 &pCcb->SearchPattern, &DirContext, FirstCall); 00403 pCcb->Entry = DirContext.DirIndex; 00404 DPRINT ("Found %wZ, RC=%x, entry %x\n", &DirContext.LongNameU, RC, pCcb->Entry); 00405 FirstCall = FALSE; 00406 if (NT_SUCCESS (RC)) 00407 { 00408 switch (FileInformationClass) 00409 { 00410 case FileNameInformation: 00411 RC = VfatGetFileNameInformation (&DirContext, 00412 (PFILE_NAMES_INFORMATION) Buffer, 00413 BufferLength); 00414 break; 00415 case FileDirectoryInformation: 00416 RC = VfatGetFileDirectoryInformation (&DirContext, 00417 IrpContext->DeviceExt, 00418 (PFILE_DIRECTORY_INFORMATION) Buffer, 00419 BufferLength); 00420 break; 00421 case FileFullDirectoryInformation: 00422 RC = VfatGetFileFullDirectoryInformation (&DirContext, 00423 IrpContext->DeviceExt, 00424 (PFILE_FULL_DIR_INFORMATION) Buffer, 00425 BufferLength); 00426 break; 00427 case FileBothDirectoryInformation: 00428 RC = VfatGetFileBothInformation (&DirContext, 00429 IrpContext->DeviceExt, 00430 (PFILE_BOTH_DIR_INFORMATION) Buffer, 00431 BufferLength); 00432 break; 00433 default: 00434 RC = STATUS_INVALID_INFO_CLASS; 00435 } 00436 if (RC == STATUS_BUFFER_OVERFLOW || RC == STATUS_INVALID_INFO_CLASS) 00437 { 00438 break; 00439 } 00440 } 00441 else 00442 { 00443 if (FirstQuery) 00444 { 00445 RC = STATUS_NO_SUCH_FILE; 00446 } 00447 else 00448 { 00449 RC = STATUS_NO_MORE_FILES; 00450 } 00451 break; 00452 } 00453 Buffer0 = (PFILE_NAMES_INFORMATION) Buffer; 00454 Buffer0->FileIndex = DirContext.DirIndex; 00455 pCcb->Entry = ++DirContext.DirIndex; 00456 BufferLength -= Buffer0->NextEntryOffset; 00457 if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY) 00458 { 00459 break; 00460 } 00461 Buffer += Buffer0->NextEntryOffset; 00462 } 00463 if (Buffer0) 00464 { 00465 Buffer0->NextEntryOffset = 0; 00466 RC = STATUS_SUCCESS; 00467 IrpContext->Irp->IoStatus.Information = Stack->Parameters.QueryDirectory.Length - BufferLength; 00468 00469 } 00470 ExReleaseResourceLite(&pFcb->MainResource); 00471 return RC; 00472 } 00473 00474 00475 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext) 00476 /* 00477 * FUNCTION: directory control : read/write directory informations 00478 */ 00479 { 00480 NTSTATUS RC = STATUS_SUCCESS; 00481 IrpContext->Irp->IoStatus.Information = 0; 00482 switch (IrpContext->MinorFunction) 00483 { 00484 case IRP_MN_QUERY_DIRECTORY: 00485 RC = DoQuery (IrpContext); 00486 break; 00487 case IRP_MN_NOTIFY_CHANGE_DIRECTORY: 00488 DPRINT (" vfat, dir : change\n"); 00489 RC = STATUS_NOT_IMPLEMENTED; 00490 break; 00491 default: 00492 // error 00493 DbgPrint ("unexpected minor function %x in VFAT driver\n", 00494 IrpContext->MinorFunction); 00495 RC = STATUS_INVALID_DEVICE_REQUEST; 00496 break; 00497 } 00498 if (RC == STATUS_PENDING) 00499 { 00500 RC = VfatQueueRequest(IrpContext); 00501 } 00502 else 00503 { 00504 IrpContext->Irp->IoStatus.Status = RC; 00505 IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); 00506 VfatFreeIrpContext(IrpContext); 00507 } 00508 return RC; 00509 } 00510 00511 Generated on Thu May 24 2012 04:18:24 for ReactOS by
1.7.6.1
|