2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/vfat/dir.c
5 * PURPOSE: VFAT Filesystem : directory control
15 // function like DosDateTimeToFileTime
17 FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt
, USHORT DosDate
, USHORT DosTime
, PLARGE_INTEGER SystemTime
)
19 PDOSTIME pdtime
= (PDOSTIME
) &DosTime
;
20 PDOSDATE pddate
= (PDOSDATE
) &DosDate
;
21 TIME_FIELDS TimeFields
;
22 LARGE_INTEGER LocalTime
;
24 if (SystemTime
== NULL
)
27 TimeFields
.Milliseconds
= 0;
28 TimeFields
.Second
= pdtime
->Second
* 2;
29 TimeFields
.Minute
= pdtime
->Minute
;
30 TimeFields
.Hour
= pdtime
->Hour
;
32 TimeFields
.Day
= pddate
->Day
;
33 TimeFields
.Month
= pddate
->Month
;
34 TimeFields
.Year
= (CSHORT
)(DeviceExt
->BaseDateYear
+ pddate
->Year
);
36 RtlTimeFieldsToTime (&TimeFields
, &LocalTime
);
37 ExLocalTimeToSystemTime(&LocalTime
, SystemTime
);
42 // function like FileTimeToDosDateTime
44 FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt
, PLARGE_INTEGER SystemTime
, USHORT
*pDosDate
, USHORT
*pDosTime
)
46 PDOSTIME pdtime
= (PDOSTIME
) pDosTime
;
47 PDOSDATE pddate
= (PDOSDATE
) pDosDate
;
48 TIME_FIELDS TimeFields
;
49 LARGE_INTEGER LocalTime
;
51 if (SystemTime
== NULL
)
54 ExSystemTimeToLocalTime (SystemTime
, &LocalTime
);
55 RtlTimeToTimeFields (&LocalTime
, &TimeFields
);
59 pdtime
->Second
= TimeFields
.Second
/ 2;
60 pdtime
->Minute
= TimeFields
.Minute
;
61 pdtime
->Hour
= TimeFields
.Hour
;
66 pddate
->Day
= TimeFields
.Day
;
67 pddate
->Month
= TimeFields
.Month
;
68 pddate
->Year
= (USHORT
) (TimeFields
.Year
- DeviceExt
->BaseDateYear
);
74 #define ULONG_ROUND_UP(x) ROUND_UP((x), (sizeof(ULONG)))
77 VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext
,
78 PFILE_NAMES_INFORMATION pInfo
, ULONG BufferLength
)
80 if ((sizeof (FILE_DIRECTORY_INFORMATION
) + DirContext
->LongNameU
.Length
) > BufferLength
)
81 return STATUS_BUFFER_OVERFLOW
;
82 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
83 pInfo
->NextEntryOffset
=
84 ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION
) + DirContext
->LongNameU
.Length
);
85 RtlCopyMemory (pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
86 return STATUS_SUCCESS
;
90 VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext
,
91 PDEVICE_EXTENSION DeviceExt
,
92 PFILE_DIRECTORY_INFORMATION pInfo
,
95 if ((sizeof (FILE_DIRECTORY_INFORMATION
) + DirContext
->LongNameU
.Length
) > BufferLength
)
96 return STATUS_BUFFER_OVERFLOW
;
97 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
98 pInfo
->NextEntryOffset
=
99 ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION
) + DirContext
->LongNameU
.Length
);
100 RtlCopyMemory (pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
101 // pInfo->FileIndex=;
102 if (DeviceExt
->Flags
& VCB_IS_FATX
)
104 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.CreationDate
,
105 DirContext
->DirEntry
.FatX
.CreationTime
,
106 &pInfo
->CreationTime
);
107 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.AccessDate
,
108 DirContext
->DirEntry
.FatX
.AccessTime
,
109 &pInfo
->LastAccessTime
);
110 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.UpdateDate
,
111 DirContext
->DirEntry
.FatX
.UpdateTime
,
112 &pInfo
->LastWriteTime
);
113 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
114 if (DirContext
->DirEntry
.FatX
.Attrib
& FILE_ATTRIBUTE_DIRECTORY
)
116 pInfo
->EndOfFile
.QuadPart
= 0;
117 pInfo
->AllocationSize
.QuadPart
= 0;
121 pInfo
->EndOfFile
.u
.HighPart
= 0;
122 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.FatX
.FileSize
;
123 /* Make allocsize a rounded up multiple of BytesPerCluster */
124 pInfo
->AllocationSize
.u
.HighPart
= 0;
125 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.FatX
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
127 pInfo
->FileAttributes
= DirContext
->DirEntry
.FatX
.Attrib
& 0x3f;
131 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.CreationDate
,
132 DirContext
->DirEntry
.Fat
.CreationTime
,
133 &pInfo
->CreationTime
);
134 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.AccessDate
, 0,
135 &pInfo
->LastAccessTime
);
136 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.UpdateDate
,
137 DirContext
->DirEntry
.Fat
.UpdateTime
,
138 &pInfo
->LastWriteTime
);
139 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
140 if (DirContext
->DirEntry
.Fat
.Attrib
& FILE_ATTRIBUTE_DIRECTORY
)
142 pInfo
->EndOfFile
.QuadPart
= 0;
143 pInfo
->AllocationSize
.QuadPart
= 0;
147 pInfo
->EndOfFile
.u
.HighPart
= 0;
148 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.Fat
.FileSize
;
149 /* Make allocsize a rounded up multiple of BytesPerCluster */
150 pInfo
->AllocationSize
.u
.HighPart
= 0;
151 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.Fat
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
153 pInfo
->FileAttributes
= DirContext
->DirEntry
.Fat
.Attrib
& 0x3f;
156 return STATUS_SUCCESS
;
160 VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext
,
161 PDEVICE_EXTENSION DeviceExt
,
162 PFILE_FULL_DIR_INFORMATION pInfo
,
165 if ((sizeof (FILE_FULL_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
) > BufferLength
)
166 return STATUS_BUFFER_OVERFLOW
;
167 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
168 pInfo
->NextEntryOffset
=
169 ULONG_ROUND_UP (sizeof (FILE_FULL_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
);
170 RtlCopyMemory (pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
171 // pInfo->FileIndex=;
172 if (DeviceExt
->Flags
& VCB_IS_FATX
)
174 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.CreationDate
,
175 DirContext
->DirEntry
.FatX
.CreationTime
,
176 &pInfo
->CreationTime
);
177 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.AccessDate
,
178 DirContext
->DirEntry
.FatX
.AccessTime
,
179 &pInfo
->LastAccessTime
);
180 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.UpdateDate
,
181 DirContext
->DirEntry
.FatX
.UpdateTime
,
182 &pInfo
->LastWriteTime
);
183 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
184 pInfo
->EndOfFile
.u
.HighPart
= 0;
185 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.FatX
.FileSize
;
186 /* Make allocsize a rounded up multiple of BytesPerCluster */
187 pInfo
->AllocationSize
.u
.HighPart
= 0;
188 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.FatX
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
189 pInfo
->FileAttributes
= DirContext
->DirEntry
.FatX
.Attrib
& 0x3f;
193 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.CreationDate
,
194 DirContext
->DirEntry
.Fat
.CreationTime
,
195 &pInfo
->CreationTime
);
196 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.AccessDate
,
197 0, &pInfo
->LastAccessTime
);
198 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.UpdateDate
,
199 DirContext
->DirEntry
.Fat
.UpdateTime
,
200 &pInfo
->LastWriteTime
);
201 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
202 pInfo
->EndOfFile
.u
.HighPart
= 0;
203 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.Fat
.FileSize
;
204 /* Make allocsize a rounded up multiple of BytesPerCluster */
205 pInfo
->AllocationSize
.u
.HighPart
= 0;
206 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.Fat
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
207 pInfo
->FileAttributes
= DirContext
->DirEntry
.Fat
.Attrib
& 0x3f;
210 return STATUS_SUCCESS
;
214 VfatGetFileBothInformation (PVFAT_DIRENTRY_CONTEXT DirContext
,
215 PDEVICE_EXTENSION DeviceExt
,
216 PFILE_BOTH_DIR_INFORMATION pInfo
,
219 if ((sizeof (FILE_BOTH_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
) > BufferLength
)
220 return STATUS_BUFFER_OVERFLOW
;
222 if (DeviceExt
->Flags
& VCB_IS_FATX
)
224 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
225 RtlCopyMemory(pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
226 pInfo
->NextEntryOffset
=
227 ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
);
228 pInfo
->ShortName
[0] = 0;
229 pInfo
->ShortNameLength
= 0;
230 // pInfo->FileIndex=;
231 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.CreationDate
,
232 DirContext
->DirEntry
.FatX
.CreationTime
,
233 &pInfo
->CreationTime
);
234 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.AccessDate
,
235 DirContext
->DirEntry
.FatX
.AccessTime
,
236 &pInfo
->LastAccessTime
);
237 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.UpdateDate
,
238 DirContext
->DirEntry
.FatX
.UpdateTime
,
239 &pInfo
->LastWriteTime
);
240 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
241 if (DirContext
->DirEntry
.FatX
.Attrib
& FILE_ATTRIBUTE_DIRECTORY
)
243 pInfo
->EndOfFile
.QuadPart
= 0;
244 pInfo
->AllocationSize
.QuadPart
= 0;
248 pInfo
->EndOfFile
.u
.HighPart
= 0;
249 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.FatX
.FileSize
;
250 /* Make allocsize a rounded up multiple of BytesPerCluster */
251 pInfo
->AllocationSize
.u
.HighPart
= 0;
252 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.FatX
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
254 pInfo
->FileAttributes
= DirContext
->DirEntry
.FatX
.Attrib
& 0x3f;
258 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
259 pInfo
->NextEntryOffset
=
260 ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
);
261 RtlCopyMemory(pInfo
->ShortName
, DirContext
->ShortNameU
.Buffer
, DirContext
->ShortNameU
.Length
);
262 pInfo
->ShortNameLength
= (CCHAR
)DirContext
->ShortNameU
.Length
;
263 RtlCopyMemory (pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
264 // pInfo->FileIndex=;
265 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.CreationDate
,
266 DirContext
->DirEntry
.Fat
.CreationTime
,
267 &pInfo
->CreationTime
);
268 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.AccessDate
, 0,
269 &pInfo
->LastAccessTime
);
270 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.UpdateDate
,
271 DirContext
->DirEntry
.Fat
.UpdateTime
,
272 &pInfo
->LastWriteTime
);
273 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
274 if (DirContext
->DirEntry
.Fat
.Attrib
& FILE_ATTRIBUTE_DIRECTORY
)
276 pInfo
->EndOfFile
.QuadPart
= 0;
277 pInfo
->AllocationSize
.QuadPart
= 0;
281 pInfo
->EndOfFile
.u
.HighPart
= 0;
282 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.Fat
.FileSize
;
283 /* Make allocsize a rounded up multiple of BytesPerCluster */
284 pInfo
->AllocationSize
.u
.HighPart
= 0;
285 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.Fat
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
287 pInfo
->FileAttributes
= DirContext
->DirEntry
.Fat
.Attrib
& 0x3f;
290 return STATUS_SUCCESS
;
293 static NTSTATUS
DoQuery (PVFAT_IRP_CONTEXT IrpContext
)
295 NTSTATUS RC
= STATUS_SUCCESS
;
296 long BufferLength
= 0;
297 PUNICODE_STRING pSearchPattern
= NULL
;
298 FILE_INFORMATION_CLASS FileInformationClass
;
299 unsigned char *Buffer
= NULL
;
300 PFILE_NAMES_INFORMATION Buffer0
= NULL
;
303 BOOLEAN FirstQuery
= FALSE
;
304 BOOLEAN FirstCall
= TRUE
;
305 VFAT_DIRENTRY_CONTEXT DirContext
;
306 WCHAR LongNameBuffer
[LONGNAME_MAX_LENGTH
+ 1];
307 WCHAR ShortNameBuffer
[13];
309 PIO_STACK_LOCATION Stack
= IrpContext
->Stack
;
311 pCcb
= (PVFATCCB
) IrpContext
->FileObject
->FsContext2
;
312 pFcb
= (PVFATFCB
) IrpContext
->FileObject
->FsContext
;
314 // determine Buffer for result :
315 BufferLength
= Stack
->Parameters
.QueryDirectory
.Length
;
317 /* Do not probe the user buffer until SEH is available */
318 if (IrpContext
->Irp
->RequestorMode
!= KernelMode
&&
319 IrpContext
->Irp
->MdlAddress
== NULL
&&
320 IrpContext
->Irp
->UserBuffer
!= NULL
)
322 ProbeForWrite(IrpContext
->Irp
->UserBuffer
, BufferLength
, 1);
325 Buffer
= VfatGetUserBuffer(IrpContext
->Irp
);
327 if (!ExAcquireResourceSharedLite(&pFcb
->MainResource
,
328 (BOOLEAN
)(IrpContext
->Flags
& IRPCONTEXT_CANWAIT
)))
330 RC
= VfatLockUserBuffer(IrpContext
->Irp
, BufferLength
, IoWriteAccess
);
338 /* Obtain the callers parameters */
340 /* HACKHACK: Bug in the MS ntifs.h header:
341 * FileName is really a PUNICODE_STRING, not a PSTRING */
342 pSearchPattern
= (PUNICODE_STRING
)Stack
->Parameters
.QueryDirectory
.FileName
;
344 pSearchPattern
= Stack
->Parameters
.QueryDirectory
.FileName
;
346 FileInformationClass
=
347 Stack
->Parameters
.QueryDirectory
.FileInformationClass
;
350 if (!pCcb
->SearchPattern
.Buffer
)
353 pCcb
->SearchPattern
.MaximumLength
= pSearchPattern
->Length
+ sizeof(WCHAR
);
354 pCcb
->SearchPattern
.Buffer
= ExAllocatePool(NonPagedPool
, pCcb
->SearchPattern
.MaximumLength
);
355 if (!pCcb
->SearchPattern
.Buffer
)
357 ExReleaseResourceLite(&pFcb
->MainResource
);
358 return STATUS_INSUFFICIENT_RESOURCES
;
360 RtlCopyUnicodeString(&pCcb
->SearchPattern
, pSearchPattern
);
361 pCcb
->SearchPattern
.Buffer
[pCcb
->SearchPattern
.Length
/ sizeof(WCHAR
)] = 0;
364 else if (!pCcb
->SearchPattern
.Buffer
)
367 pCcb
->SearchPattern
.MaximumLength
= 2 * sizeof(WCHAR
);
368 pCcb
->SearchPattern
.Buffer
= ExAllocatePool(NonPagedPool
, 2 * sizeof(WCHAR
));
369 if (!pCcb
->SearchPattern
.Buffer
)
371 ExReleaseResourceLite(&pFcb
->MainResource
);
372 return STATUS_INSUFFICIENT_RESOURCES
;
374 pCcb
->SearchPattern
.Buffer
[0] = L
'*';
375 pCcb
->SearchPattern
.Buffer
[1] = 0;
376 pCcb
->SearchPattern
.Length
= sizeof(WCHAR
);
379 if (IrpContext
->Stack
->Flags
& SL_INDEX_SPECIFIED
)
381 DirContext
.DirIndex
= pCcb
->Entry
= Stack
->Parameters
.QueryDirectory
.FileIndex
;
383 else if (FirstQuery
|| (IrpContext
->Stack
->Flags
& SL_RESTART_SCAN
))
385 DirContext
.DirIndex
= pCcb
->Entry
= 0;
389 DirContext
.DirIndex
= pCcb
->Entry
;
392 DPRINT ("Buffer=%x tofind=%wZ\n", Buffer
, &pCcb
->SearchPattern
);
394 DirContext
.LongNameU
.Buffer
= LongNameBuffer
;
395 DirContext
.LongNameU
.MaximumLength
= sizeof(LongNameBuffer
);
396 DirContext
.ShortNameU
.Buffer
= ShortNameBuffer
;
397 DirContext
.ShortNameU
.MaximumLength
= sizeof(ShortNameBuffer
);
399 while (RC
== STATUS_SUCCESS
&& BufferLength
> 0)
401 RC
= FindFile (IrpContext
->DeviceExt
, pFcb
,
402 &pCcb
->SearchPattern
, &DirContext
, FirstCall
);
403 pCcb
->Entry
= DirContext
.DirIndex
;
404 DPRINT ("Found %wZ, RC=%x, entry %x\n", &DirContext
.LongNameU
, RC
, pCcb
->Entry
);
408 switch (FileInformationClass
)
410 case FileNameInformation
:
411 RC
= VfatGetFileNameInformation (&DirContext
,
412 (PFILE_NAMES_INFORMATION
) Buffer
,
415 case FileDirectoryInformation
:
416 RC
= VfatGetFileDirectoryInformation (&DirContext
,
417 IrpContext
->DeviceExt
,
418 (PFILE_DIRECTORY_INFORMATION
) Buffer
,
421 case FileFullDirectoryInformation
:
422 RC
= VfatGetFileFullDirectoryInformation (&DirContext
,
423 IrpContext
->DeviceExt
,
424 (PFILE_FULL_DIR_INFORMATION
) Buffer
,
427 case FileBothDirectoryInformation
:
428 RC
= VfatGetFileBothInformation (&DirContext
,
429 IrpContext
->DeviceExt
,
430 (PFILE_BOTH_DIR_INFORMATION
) Buffer
,
434 RC
= STATUS_INVALID_INFO_CLASS
;
436 if (RC
== STATUS_BUFFER_OVERFLOW
)
445 RC
= STATUS_NO_SUCH_FILE
;
449 RC
= STATUS_NO_MORE_FILES
;
453 Buffer0
= (PFILE_NAMES_INFORMATION
) Buffer
;
454 Buffer0
->FileIndex
= DirContext
.DirIndex
;
455 pCcb
->Entry
= ++DirContext
.DirIndex
;
456 BufferLength
-= Buffer0
->NextEntryOffset
;
457 if (IrpContext
->Stack
->Flags
& SL_RETURN_SINGLE_ENTRY
)
461 Buffer
+= Buffer0
->NextEntryOffset
;
465 Buffer0
->NextEntryOffset
= 0;
467 IrpContext
->Irp
->IoStatus
.Information
= Stack
->Parameters
.QueryDirectory
.Length
- BufferLength
;
470 ExReleaseResourceLite(&pFcb
->MainResource
);
475 NTSTATUS
VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext
)
477 * FUNCTION: directory control : read/write directory informations
480 NTSTATUS RC
= STATUS_SUCCESS
;
482 IrpContext
->Irp
->IoStatus
.Information
= 0;
483 switch (IrpContext
->MinorFunction
)
485 case IRP_MN_QUERY_DIRECTORY
:
486 RC
= DoQuery (IrpContext
);
488 case IRP_MN_NOTIFY_CHANGE_DIRECTORY
:
489 DPRINT (" vfat, dir : change\n");
490 RC
= STATUS_NOT_IMPLEMENTED
;
494 DbgPrint ("unexpected minor function %x in VFAT driver\n",
495 IrpContext
->MinorFunction
);
496 RC
= STATUS_INVALID_DEVICE_REQUEST
;
499 if (RC
== STATUS_PENDING
)
501 RC
= VfatQueueRequest(IrpContext
);
505 IrpContext
->Irp
->IoStatus
.Status
= RC
;
506 IoCompleteRequest (IrpContext
->Irp
, IO_NO_INCREMENT
);
507 VfatFreeIrpContext(IrpContext
);