4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS kernel
6 * FILE: drivers/fs/vfat/dir.c
7 * PURPOSE: VFAT Filesystem : directory control
17 // function like DosDateTimeToFileTime
19 FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt
, USHORT DosDate
, USHORT DosTime
, PLARGE_INTEGER SystemTime
)
21 PDOSTIME pdtime
= (PDOSTIME
) &DosTime
;
22 PDOSDATE pddate
= (PDOSDATE
) &DosDate
;
23 TIME_FIELDS TimeFields
;
24 LARGE_INTEGER LocalTime
;
26 if (SystemTime
== NULL
)
29 TimeFields
.Milliseconds
= 0;
30 TimeFields
.Second
= pdtime
->Second
* 2;
31 TimeFields
.Minute
= pdtime
->Minute
;
32 TimeFields
.Hour
= pdtime
->Hour
;
34 TimeFields
.Day
= pddate
->Day
;
35 TimeFields
.Month
= pddate
->Month
;
36 TimeFields
.Year
= (CSHORT
)(DeviceExt
->BaseDateYear
+ pddate
->Year
);
38 RtlTimeFieldsToTime (&TimeFields
, &LocalTime
);
39 ExLocalTimeToSystemTime(&LocalTime
, SystemTime
);
44 // function like FileTimeToDosDateTime
46 FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt
, PLARGE_INTEGER SystemTime
, USHORT
*pDosDate
, USHORT
*pDosTime
)
48 PDOSTIME pdtime
= (PDOSTIME
) pDosTime
;
49 PDOSDATE pddate
= (PDOSDATE
) pDosDate
;
50 TIME_FIELDS TimeFields
;
51 LARGE_INTEGER LocalTime
;
53 if (SystemTime
== NULL
)
56 ExSystemTimeToLocalTime (SystemTime
, &LocalTime
);
57 RtlTimeToTimeFields (&LocalTime
, &TimeFields
);
61 pdtime
->Second
= TimeFields
.Second
/ 2;
62 pdtime
->Minute
= TimeFields
.Minute
;
63 pdtime
->Hour
= TimeFields
.Hour
;
68 pddate
->Day
= TimeFields
.Day
;
69 pddate
->Month
= TimeFields
.Month
;
70 pddate
->Year
= (USHORT
) (TimeFields
.Year
- DeviceExt
->BaseDateYear
);
76 #define ULONG_ROUND_UP(x) ROUND_UP((x), (sizeof(ULONG)))
79 VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext
,
80 PFILE_NAMES_INFORMATION pInfo
, ULONG BufferLength
)
82 if ((sizeof (FILE_DIRECTORY_INFORMATION
) + DirContext
->LongNameU
.Length
) > BufferLength
)
83 return STATUS_BUFFER_OVERFLOW
;
84 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
85 pInfo
->NextEntryOffset
=
86 ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION
) + DirContext
->LongNameU
.Length
);
87 RtlCopyMemory (pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
88 return STATUS_SUCCESS
;
92 VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext
,
93 PDEVICE_EXTENSION DeviceExt
,
94 PFILE_DIRECTORY_INFORMATION pInfo
,
97 if ((sizeof (FILE_DIRECTORY_INFORMATION
) + DirContext
->LongNameU
.Length
) > BufferLength
)
98 return STATUS_BUFFER_OVERFLOW
;
99 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
100 pInfo
->NextEntryOffset
=
101 ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION
) + DirContext
->LongNameU
.Length
);
102 RtlCopyMemory (pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
103 // pInfo->FileIndex=;
104 if (DeviceExt
->Flags
& VCB_IS_FATX
)
106 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.CreationDate
,
107 DirContext
->DirEntry
.FatX
.CreationTime
,
108 &pInfo
->CreationTime
);
109 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.AccessDate
,
110 DirContext
->DirEntry
.FatX
.AccessTime
,
111 &pInfo
->LastAccessTime
);
112 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.UpdateDate
,
113 DirContext
->DirEntry
.FatX
.UpdateTime
,
114 &pInfo
->LastWriteTime
);
115 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
116 if (DirContext
->DirEntry
.FatX
.Attrib
& FILE_ATTRIBUTE_DIRECTORY
)
118 pInfo
->EndOfFile
.QuadPart
= 0LL;
119 pInfo
->AllocationSize
.QuadPart
= 0LL;
123 pInfo
->EndOfFile
.u
.HighPart
= 0;
124 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.FatX
.FileSize
;
125 /* Make allocsize a rounded up multiple of BytesPerCluster */
126 pInfo
->AllocationSize
.u
.HighPart
= 0;
127 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.FatX
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
129 pInfo
->FileAttributes
= DirContext
->DirEntry
.FatX
.Attrib
& 0x3f;
133 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.CreationDate
,
134 DirContext
->DirEntry
.Fat
.CreationTime
,
135 &pInfo
->CreationTime
);
136 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.AccessDate
, 0,
137 &pInfo
->LastAccessTime
);
138 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.UpdateDate
,
139 DirContext
->DirEntry
.Fat
.UpdateTime
,
140 &pInfo
->LastWriteTime
);
141 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
142 if (DirContext
->DirEntry
.Fat
.Attrib
& FILE_ATTRIBUTE_DIRECTORY
)
144 pInfo
->EndOfFile
.QuadPart
= 0LL;
145 pInfo
->AllocationSize
.QuadPart
= 0LL;
149 pInfo
->EndOfFile
.u
.HighPart
= 0;
150 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.Fat
.FileSize
;
151 /* Make allocsize a rounded up multiple of BytesPerCluster */
152 pInfo
->AllocationSize
.u
.HighPart
= 0;
153 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.Fat
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
155 pInfo
->FileAttributes
= DirContext
->DirEntry
.Fat
.Attrib
& 0x3f;
158 return STATUS_SUCCESS
;
162 VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext
,
163 PDEVICE_EXTENSION DeviceExt
,
164 PFILE_FULL_DIR_INFORMATION pInfo
,
167 if ((sizeof (FILE_FULL_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
) > BufferLength
)
168 return STATUS_BUFFER_OVERFLOW
;
169 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
170 pInfo
->NextEntryOffset
=
171 ULONG_ROUND_UP (sizeof (FILE_FULL_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
);
172 RtlCopyMemory (pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
173 // pInfo->FileIndex=;
174 if (DeviceExt
->Flags
& VCB_IS_FATX
)
176 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.CreationDate
,
177 DirContext
->DirEntry
.FatX
.CreationTime
,
178 &pInfo
->CreationTime
);
179 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.AccessDate
,
180 DirContext
->DirEntry
.FatX
.AccessTime
,
181 &pInfo
->LastAccessTime
);
182 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.UpdateDate
,
183 DirContext
->DirEntry
.FatX
.UpdateTime
,
184 &pInfo
->LastWriteTime
);
185 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
186 pInfo
->EndOfFile
.u
.HighPart
= 0;
187 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.FatX
.FileSize
;
188 /* Make allocsize a rounded up multiple of BytesPerCluster */
189 pInfo
->AllocationSize
.u
.HighPart
= 0;
190 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.FatX
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
191 pInfo
->FileAttributes
= DirContext
->DirEntry
.FatX
.Attrib
& 0x3f;
195 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.CreationDate
,
196 DirContext
->DirEntry
.Fat
.CreationTime
,
197 &pInfo
->CreationTime
);
198 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.AccessDate
,
199 0, &pInfo
->LastAccessTime
);
200 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.UpdateDate
,
201 DirContext
->DirEntry
.Fat
.UpdateTime
,
202 &pInfo
->LastWriteTime
);
203 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
204 pInfo
->EndOfFile
.u
.HighPart
= 0;
205 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.Fat
.FileSize
;
206 /* Make allocsize a rounded up multiple of BytesPerCluster */
207 pInfo
->AllocationSize
.u
.HighPart
= 0;
208 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.Fat
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
209 pInfo
->FileAttributes
= DirContext
->DirEntry
.Fat
.Attrib
& 0x3f;
212 return STATUS_SUCCESS
;
216 VfatGetFileBothInformation (PVFAT_DIRENTRY_CONTEXT DirContext
,
217 PDEVICE_EXTENSION DeviceExt
,
218 PFILE_BOTH_DIR_INFORMATION pInfo
,
221 if ((sizeof (FILE_BOTH_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
) > BufferLength
)
222 return STATUS_BUFFER_OVERFLOW
;
224 if (DeviceExt
->Flags
& VCB_IS_FATX
)
226 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
227 RtlCopyMemory(pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
228 pInfo
->NextEntryOffset
=
229 ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
);
230 pInfo
->ShortName
[0] = 0;
231 pInfo
->ShortNameLength
= 0;
232 // pInfo->FileIndex=;
233 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.CreationDate
,
234 DirContext
->DirEntry
.FatX
.CreationTime
,
235 &pInfo
->CreationTime
);
236 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.AccessDate
,
237 DirContext
->DirEntry
.FatX
.AccessTime
,
238 &pInfo
->LastAccessTime
);
239 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.FatX
.UpdateDate
,
240 DirContext
->DirEntry
.FatX
.UpdateTime
,
241 &pInfo
->LastWriteTime
);
242 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
243 if (DirContext
->DirEntry
.FatX
.Attrib
& FILE_ATTRIBUTE_DIRECTORY
)
245 pInfo
->EndOfFile
.QuadPart
= 0LL;
246 pInfo
->AllocationSize
.QuadPart
= 0LL;
250 pInfo
->EndOfFile
.u
.HighPart
= 0;
251 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.FatX
.FileSize
;
252 /* Make allocsize a rounded up multiple of BytesPerCluster */
253 pInfo
->AllocationSize
.u
.HighPart
= 0;
254 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.FatX
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
256 pInfo
->FileAttributes
= DirContext
->DirEntry
.FatX
.Attrib
& 0x3f;
260 pInfo
->FileNameLength
= DirContext
->LongNameU
.Length
;
261 pInfo
->NextEntryOffset
=
262 ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_INFORMATION
) + DirContext
->LongNameU
.Length
);
263 RtlCopyMemory(pInfo
->ShortName
, DirContext
->ShortNameU
.Buffer
, DirContext
->ShortNameU
.Length
);
264 pInfo
->ShortNameLength
= (CCHAR
)DirContext
->ShortNameU
.Length
;
265 RtlCopyMemory (pInfo
->FileName
, DirContext
->LongNameU
.Buffer
, DirContext
->LongNameU
.Length
);
266 // pInfo->FileIndex=;
267 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.CreationDate
,
268 DirContext
->DirEntry
.Fat
.CreationTime
,
269 &pInfo
->CreationTime
);
270 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.AccessDate
, 0,
271 &pInfo
->LastAccessTime
);
272 FsdDosDateTimeToSystemTime (DeviceExt
, DirContext
->DirEntry
.Fat
.UpdateDate
,
273 DirContext
->DirEntry
.Fat
.UpdateTime
,
274 &pInfo
->LastWriteTime
);
275 pInfo
->ChangeTime
= pInfo
->LastWriteTime
;
276 if (DirContext
->DirEntry
.Fat
.Attrib
& FILE_ATTRIBUTE_DIRECTORY
)
278 pInfo
->EndOfFile
.QuadPart
= 0LL;
279 pInfo
->AllocationSize
.QuadPart
= 0LL;
283 pInfo
->EndOfFile
.u
.HighPart
= 0;
284 pInfo
->EndOfFile
.u
.LowPart
= DirContext
->DirEntry
.Fat
.FileSize
;
285 /* Make allocsize a rounded up multiple of BytesPerCluster */
286 pInfo
->AllocationSize
.u
.HighPart
= 0;
287 pInfo
->AllocationSize
.u
.LowPart
= ROUND_UP(DirContext
->DirEntry
.Fat
.FileSize
, DeviceExt
->FatInfo
.BytesPerCluster
);
289 pInfo
->FileAttributes
= DirContext
->DirEntry
.Fat
.Attrib
& 0x3f;
292 return STATUS_SUCCESS
;
295 NTSTATUS
DoQuery (PVFAT_IRP_CONTEXT IrpContext
)
297 NTSTATUS RC
= STATUS_SUCCESS
;
298 long BufferLength
= 0;
299 PUNICODE_STRING pSearchPattern
= NULL
;
300 FILE_INFORMATION_CLASS FileInformationClass
;
301 unsigned long FileIndex
= 0;
302 unsigned char *Buffer
= NULL
;
303 PFILE_NAMES_INFORMATION Buffer0
= NULL
;
306 BOOLEAN First
= FALSE
;
308 VFAT_DIRENTRY_CONTEXT DirContext
;
309 WCHAR LongNameBuffer
[LONGNAME_MAX_LENGTH
+ 1];
310 WCHAR ShortNameBuffer
[13];
312 PIO_STACK_LOCATION Stack
= IrpContext
->Stack
;
314 pCcb
= (PVFATCCB
) IrpContext
->FileObject
->FsContext2
;
315 pFcb
= (PVFATFCB
) IrpContext
->FileObject
->FsContext
;
317 // determine Buffer for result :
318 BufferLength
= Stack
->Parameters
.QueryDirectory
.Length
;
320 /* Do not probe the user buffer until SEH is available */
321 if (IrpContext
->Irp
->RequestorMode
!= KernelMode
&&
322 IrpContext
->Irp
->MdlAddress
== NULL
&&
323 IrpContext
->Irp
->UserBuffer
!= NULL
)
325 ProbeForWrite(IrpContext
->Irp
->UserBuffer
, BufferLength
, 1);
328 Buffer
= VfatGetUserBuffer(IrpContext
->Irp
);
330 if (!ExAcquireResourceSharedLite(&pFcb
->MainResource
,
331 (BOOLEAN
)(IrpContext
->Flags
& IRPCONTEXT_CANWAIT
)))
333 RC
= VfatLockUserBuffer(IrpContext
->Irp
, BufferLength
, IoWriteAccess
);
341 /* Obtain the callers parameters */
343 /* HACKHACK: Bug in the MS ntifs.h header:
344 * FileName is really a PUNICODE_STRING, not a PSTRING */
345 pSearchPattern
= (PUNICODE_STRING
)Stack
->Parameters
.QueryDirectory
.FileName
;
347 pSearchPattern
= Stack
->Parameters
.QueryDirectory
.FileName
;
349 FileInformationClass
=
350 Stack
->Parameters
.QueryDirectory
.FileInformationClass
;
351 FileIndex
= Stack
->Parameters
.QueryDirectory
.FileIndex
;
354 if (!pCcb
->SearchPattern
.Buffer
)
357 pCcb
->SearchPattern
.MaximumLength
= pSearchPattern
->Length
+ sizeof(WCHAR
);
358 pCcb
->SearchPattern
.Buffer
= ExAllocatePool(NonPagedPool
, pCcb
->SearchPattern
.MaximumLength
);
359 if (!pCcb
->SearchPattern
.Buffer
)
361 ExReleaseResourceLite(&pFcb
->MainResource
);
362 return STATUS_INSUFFICIENT_RESOURCES
;
364 RtlCopyUnicodeString(&pCcb
->SearchPattern
, pSearchPattern
);
365 pCcb
->SearchPattern
.Buffer
[pCcb
->SearchPattern
.Length
/ sizeof(WCHAR
)] = 0;
368 else if (!pCcb
->SearchPattern
.Buffer
)
371 pCcb
->SearchPattern
.MaximumLength
= 2 * sizeof(WCHAR
);
372 pCcb
->SearchPattern
.Buffer
= ExAllocatePool(NonPagedPool
, 2 * sizeof(WCHAR
));
373 if (!pCcb
->SearchPattern
.Buffer
)
375 ExReleaseResourceLite(&pFcb
->MainResource
);
376 return STATUS_INSUFFICIENT_RESOURCES
;
378 pCcb
->SearchPattern
.Buffer
[0] = L
'*';
379 pCcb
->SearchPattern
.Buffer
[1] = 0;
380 pCcb
->SearchPattern
.Length
= sizeof(WCHAR
);
383 if (IrpContext
->Stack
->Flags
& SL_INDEX_SPECIFIED
)
385 DirContext
.DirIndex
= pCcb
->Entry
= pCcb
->CurrentByteOffset
.u
.LowPart
;
388 else if (First
|| (IrpContext
->Stack
->Flags
& SL_RESTART_SCAN
))
390 DirContext
.DirIndex
= pCcb
->Entry
= 0;
395 DirContext
.DirIndex
= pCcb
->Entry
;
399 DPRINT ("Buffer=%x tofind=%wZ\n", Buffer
, &pCcb
->SearchPattern
);
401 DirContext
.LongNameU
.Buffer
= LongNameBuffer
;
402 DirContext
.LongNameU
.MaximumLength
= sizeof(LongNameBuffer
);
403 DirContext
.ShortNameU
.Buffer
= ShortNameBuffer
;
404 DirContext
.ShortNameU
.MaximumLength
= sizeof(ShortNameBuffer
);
406 while (RC
== STATUS_SUCCESS
&& BufferLength
> 0)
408 RC
= FindFile (IrpContext
->DeviceExt
, pFcb
,
409 &pCcb
->SearchPattern
, &DirContext
, FirstCall
);
410 pCcb
->Entry
= DirContext
.DirIndex
;
411 DPRINT ("Found %wZ, RC=%x, entry %x\n", &DirContext
.LongNameU
, RC
, pCcb
->Entry
);
415 switch (FileInformationClass
)
417 case FileNameInformation
:
418 RC
= VfatGetFileNameInformation (&DirContext
,
419 (PFILE_NAMES_INFORMATION
) Buffer
,
422 case FileDirectoryInformation
:
423 RC
= VfatGetFileDirectoryInformation (&DirContext
,
424 IrpContext
->DeviceExt
,
425 (PFILE_DIRECTORY_INFORMATION
) Buffer
,
428 case FileFullDirectoryInformation
:
429 RC
= VfatGetFileFullDirectoryInformation (&DirContext
,
430 IrpContext
->DeviceExt
,
431 (PFILE_FULL_DIR_INFORMATION
) Buffer
,
434 case FileBothDirectoryInformation
:
435 RC
= VfatGetFileBothInformation (&DirContext
,
436 IrpContext
->DeviceExt
,
437 (PFILE_BOTH_DIR_INFORMATION
) Buffer
,
441 RC
= STATUS_INVALID_INFO_CLASS
;
443 if (RC
== STATUS_BUFFER_OVERFLOW
)
447 Buffer0
->NextEntryOffset
= 0;
456 Buffer0
->NextEntryOffset
= 0;
460 RC
= STATUS_NO_SUCH_FILE
;
464 RC
= STATUS_NO_MORE_FILES
;
468 Buffer0
= (PFILE_NAMES_INFORMATION
) Buffer
;
469 Buffer0
->FileIndex
= FileIndex
++;
470 pCcb
->Entry
= ++DirContext
.DirIndex
;
471 if (IrpContext
->Stack
->Flags
& SL_RETURN_SINGLE_ENTRY
)
475 BufferLength
-= Buffer0
->NextEntryOffset
;
476 Buffer
+= Buffer0
->NextEntryOffset
;
480 Buffer0
->NextEntryOffset
= 0;
486 ExReleaseResourceLite(&pFcb
->MainResource
);
491 NTSTATUS
VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext
)
493 * FUNCTION: directory control : read/write directory informations
496 NTSTATUS RC
= STATUS_SUCCESS
;
498 switch (IrpContext
->MinorFunction
)
500 case IRP_MN_QUERY_DIRECTORY
:
501 RC
= DoQuery (IrpContext
);
503 case IRP_MN_NOTIFY_CHANGE_DIRECTORY
:
504 DPRINT (" vfat, dir : change\n");
505 RC
= STATUS_NOT_IMPLEMENTED
;
509 DbgPrint ("unexpected minor function %x in VFAT driver\n",
510 IrpContext
->MinorFunction
);
511 RC
= STATUS_INVALID_DEVICE_REQUEST
;
514 if (RC
== STATUS_PENDING
)
516 RC
= VfatQueueRequest(IrpContext
);
520 IrpContext
->Irp
->IoStatus
.Status
= RC
;
521 IrpContext
->Irp
->IoStatus
.Information
= 0;
522 IoCompleteRequest (IrpContext
->Irp
, IO_NO_INCREMENT
);
523 VfatFreeIrpContext(IrpContext
);