5 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
6 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
10 unsigned char magic0
, res0
, magic1
;
11 unsigned char OEMName
[8];
12 unsigned short BytesPerSector
;
13 unsigned char SectorsPerCluster
;
14 unsigned short ReservedSectors
;
15 unsigned char FATCount
;
16 unsigned short RootEntries
, Sectors
;
18 unsigned short FATSectors
, SectorsPerTrack
, Heads
;
19 unsigned long HiddenSectors
, SectorsHuge
;
20 unsigned char Drive
, Res1
, Sig
;
21 unsigned long VolumeID
;
22 unsigned char VolumeLabel
[11], SysType
[8];
23 unsigned char Res2
[448];
24 unsigned short Signatur1
;
25 } __attribute__((packed
));
29 unsigned char magic0
, res0
, magic1
; // 0
30 unsigned char OEMName
[8]; // 3
31 unsigned short BytesPerSector
; // 11
32 unsigned char SectorsPerCluster
; // 13
33 unsigned short ReservedSectors
; // 14
34 unsigned char FATCount
; // 16
35 unsigned short RootEntries
, Sectors
; // 17
36 unsigned char Media
; // 21
37 unsigned short FATSectors
, SectorsPerTrack
, Heads
; // 22
38 unsigned long HiddenSectors
, SectorsHuge
; // 28
39 unsigned long FATSectors32
; // 36
40 unsigned short ExtFlag
; // 40
41 unsigned short FSVersion
; // 42
42 unsigned long RootCluster
; // 44
43 unsigned short FSInfoSector
; // 48
44 unsigned short BootBackup
; // 50
45 unsigned char Res3
[12]; // 52
46 unsigned char Drive
; // 64
47 unsigned char Res4
; // 65
48 unsigned char ExtBootSignature
; // 66
49 unsigned long VolumeID
; // 67
50 unsigned char VolumeLabel
[11], SysType
[8]; // 71
51 unsigned char Res2
[420]; // 90
52 unsigned short Signature1
; // 510
53 } __attribute__((packed
));
55 struct _BootSectorFatX
57 unsigned char SysType
[4]; // 0
58 unsigned long VolumeID
; // 4
59 unsigned long SectorsPerCluster
; // 8
60 unsigned short FATCount
; // 12
61 unsigned long Unknown
; // 14
62 unsigned char Unused
[4078]; // 18
63 } __attribute__((packed
));
67 unsigned long ExtBootSignature2
; // 0
68 unsigned char Res6
[480]; // 4
69 unsigned long FSINFOSignature
; // 484
70 unsigned long FreeCluster
; // 488
71 unsigned long NextCluster
; // 492
72 unsigned char Res7
[12]; // 496
73 unsigned long Signatur2
; // 508
74 } __attribute__((packed
));
76 typedef struct _BootSector BootSector
;
78 #define VFAT_CASE_LOWER_BASE 8 // base is lower case
79 #define VFAT_CASE_LOWER_EXT 16 // extension is lower case
81 #define ENTRY_DELETED(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat)))
82 #define ENTRY_VOLUME(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat)))
83 #define ENTRY_END(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat)))
85 #define FAT_ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5)
86 #define FAT_ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0)
87 #define FAT_ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f)
88 #define FAT_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
90 #define FATX_ENTRY_DELETED(DirEntry) ((DirEntry)->FilenameLength == 0xe5)
91 #define FATX_ENTRY_END(DirEntry) ((DirEntry)->FilenameLength == 0xff)
92 #define FATX_ENTRY_LONG(DirEntry) (FALSE)
93 #define FATX_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
95 #define FAT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FAT_DIR_ENTRY))
96 #define FATX_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATX_DIR_ENTRY))
100 unsigned char Filename
[8], Ext
[3];
101 unsigned char Attrib
;
103 unsigned char CreationTimeMs
;
104 unsigned short CreationTime
,CreationDate
,AccessDate
;
105 unsigned short FirstClusterHigh
; // higher
106 unsigned short UpdateTime
; //time create/update
107 unsigned short UpdateDate
; //date create/update
108 unsigned short FirstCluster
;
109 unsigned long FileSize
;
110 } __attribute__((packed
));
112 typedef struct _FATDirEntry FAT_DIR_ENTRY
, *PFAT_DIR_ENTRY
;
116 unsigned char FilenameLength
; // 0
117 unsigned char Attrib
; // 1
118 unsigned char Filename
[42]; // 2
119 unsigned long FirstCluster
; // 44
120 unsigned long FileSize
; // 48
121 unsigned short UpdateTime
; // 52
122 unsigned short UpdateDate
; // 54
123 unsigned short CreationTime
; // 56
124 unsigned short CreationDate
; // 58
125 unsigned short AccessTime
; // 60
126 unsigned short AccessDate
; // 62
127 } __attribute__((packed
));
129 typedef struct _FATXDirEntry FATX_DIR_ENTRY
, *PFATX_DIR_ENTRY
;
137 typedef union _DIR_ENTRY DIR_ENTRY
, *PDIR_ENTRY
;
141 unsigned char id
; // sequence number for slot
142 WCHAR name0_4
[5]; // first 5 characters in name
143 unsigned char attr
; // attribute byte
144 unsigned char reserved
; // always 0
145 unsigned char alias_checksum
; // checksum for 8.3 alias
146 WCHAR name5_10
[6]; // 6 more characters in name
147 unsigned char start
[2]; // starting cluster number
148 WCHAR name11_12
[2]; // last 2 characters in name
149 } __attribute__((packed
));
152 typedef struct _slot slot
;
154 #define BLOCKSIZE 512
162 #define VCB_VOLUME_LOCKED 0x0001
163 #define VCB_DISMOUNT_PENDING 0x0002
164 #define VCB_IS_FATX 0x0004
172 ULONG rootDirectorySectors
;
176 ULONG SectorsPerCluster
;
177 ULONG BytesPerSector
;
178 ULONG BytesPerCluster
;
179 ULONG NumberOfClusters
;
183 } FATINFO
, *PFATINFO
;
186 struct _VFAT_DIRENTRY_CONTEXT
;
188 typedef struct _HASHENTRY
191 struct _VFATFCB
* self
;
192 struct _HASHENTRY
* next
;
196 #define FCB_HASH_TABLE_SIZE 65536
198 typedef struct DEVICE_EXTENSION
*PDEVICE_EXTENSION
;
200 typedef NTSTATUS (*PGET_NEXT_CLUSTER
)(PDEVICE_EXTENSION
,ULONG
,PULONG
);
201 typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER
)(PDEVICE_EXTENSION
,PULONG
);
202 typedef NTSTATUS (*PWRITE_CLUSTER
)(PDEVICE_EXTENSION
,ULONG
,ULONG
,PULONG
);
204 typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY
)(PVOID
*,PVOID
*,struct _VFATFCB
*,struct _VFAT_DIRENTRY_CONTEXT
*,BOOLEAN
);
206 typedef struct DEVICE_EXTENSION
208 ERESOURCE DirResource
;
209 ERESOURCE FatResource
;
211 KSPIN_LOCK FcbListLock
;
212 LIST_ENTRY FcbListHead
;
213 struct _HASHENTRY
* FcbHashTable
[FCB_HASH_TABLE_SIZE
];
215 PDEVICE_OBJECT StorageDevice
;
216 PFILE_OBJECT FATFileObject
;
218 ULONG LastAvailableCluster
;
219 ULONG AvailableClusters
;
220 BOOLEAN AvailableClustersValid
;
222 struct _VFATFCB
* VolumeFcb
;
224 /* Pointers to functions for manipulating FAT. */
225 PGET_NEXT_CLUSTER GetNextCluster
;
226 PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster
;
227 PWRITE_CLUSTER WriteCluster
;
229 /* Pointers to functions for manipulating directory entries. */
230 PGET_NEXT_DIR_ENTRY GetNextDirEntry
;
234 LIST_ENTRY VolumeListEntry
;
235 } DEVICE_EXTENSION
, VCB
, *PVCB
;
239 PDRIVER_OBJECT DriverObject
;
240 PDEVICE_OBJECT DeviceObject
;
242 ERESOURCE VolumeListLock
;
243 LIST_ENTRY VolumeListHead
;
244 NPAGED_LOOKASIDE_LIST FcbLookasideList
;
245 NPAGED_LOOKASIDE_LIST CcbLookasideList
;
246 NPAGED_LOOKASIDE_LIST IrpContextLookasideList
;
247 } VFAT_GLOBAL_DATA
, *PVFAT_GLOBAL_DATA
;
249 extern PVFAT_GLOBAL_DATA VfatGlobalData
;
251 #define FCB_CACHE_INITIALIZED 0x0001
252 #define FCB_DELETE_PENDING 0x0002
253 #define FCB_IS_FAT 0x0004
254 #define FCB_IS_PAGE_FILE 0x0008
255 #define FCB_IS_VOLUME 0x0010
256 #define FCB_IS_DIRTY 0x0020
257 #define FCB_IS_FATX_ENTRY 0x0040
259 typedef struct _VFATFCB
261 /* FCB header required by ROS/NT */
262 FSRTL_COMMON_FCB_HEADER RFCB
;
263 SECTION_OBJECT_POINTERS SectionObjectPointers
;
264 ERESOURCE MainResource
;
265 ERESOURCE PagingIoResource
;
266 /* end FCB header required by ROS/NT */
268 /* directory entry for this file or directory */
271 /* Pointer to attributes in entry */
274 /* long file name, points into PathNameBuffer */
275 UNICODE_STRING LongNameU
;
277 /* short file name */
278 UNICODE_STRING ShortNameU
;
280 /* directory name, points into PathNameBuffer */
281 UNICODE_STRING DirNameU
;
283 /* path + long file name 260 max*/
284 UNICODE_STRING PathNameU
;
286 /* buffer for PathNameU */
287 WCHAR PathNameBuffer
[MAX_PATH
];
289 /* buffer for ShortNameU */
290 WCHAR ShortNameBuffer
[13];
295 /* List of FCB's for this volume */
296 LIST_ENTRY FcbListEntry
;
298 /* pointer to the parent fcb */
299 struct _VFATFCB
* parentFcb
;
301 /* Flags for the fcb */
304 /* pointer to the file object which has initialized the fcb */
305 PFILE_OBJECT FileObject
;
307 /* Directory index for the short name entry */
310 /* Directory index where the long name starts */
313 /* Share access for the file object */
314 SHARE_ACCESS FCBShareAccess
;
316 /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */
317 ULONG OpenHandleCount
;
319 /* Entry into the hash table for the path + long name */
322 /* Entry into the hash table for the path + short name */
325 /* List of byte-range locks for this file */
329 * Optimalization: caching of last read/write cluster+offset pair. Can't
330 * be in VFATCCB because it must be reset everytime the allocated clusters
333 FAST_MUTEX LastMutex
;
336 } VFATFCB
, *PVFATFCB
;
338 typedef struct _VFATCCB
340 LARGE_INTEGER CurrentByteOffset
;
341 /* for DirectoryControl */
343 /* for DirectoryControl */
344 UNICODE_STRING SearchPattern
;
345 } VFATCCB
, *PVFATCCB
;
348 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
351 #define TAG_CCB TAG('V', 'C', 'C', 'B')
352 #define TAG_FCB TAG('V', 'F', 'C', 'B')
353 #define TAG_IRP TAG('V', 'I', 'R', 'P')
355 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
357 typedef struct __DOSTIME
365 typedef struct __DOSDATE
373 #define IRPCONTEXT_CANWAIT 0x0001
374 #define IRPCONTEXT_PENDINGRETURNED 0x0002
379 PDEVICE_OBJECT DeviceObject
;
380 PDEVICE_EXTENSION DeviceExt
;
382 WORK_QUEUE_ITEM WorkQueueItem
;
383 PIO_STACK_LOCATION Stack
;
386 PFILE_OBJECT FileObject
;
389 } VFAT_IRP_CONTEXT
, *PVFAT_IRP_CONTEXT
;
391 typedef struct _VFAT_DIRENTRY_CONTEXT
396 UNICODE_STRING LongNameU
;
397 UNICODE_STRING ShortNameU
;
398 } VFAT_DIRENTRY_CONTEXT
, *PVFAT_DIRENTRY_CONTEXT
;
401 /* ------------------------------------------------------ shutdown.c */
403 NTSTATUS STDCALL
VfatShutdown (PDEVICE_OBJECT DeviceObject
,
406 /* -------------------------------------------------------- volume.c */
408 NTSTATUS
VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext
);
410 NTSTATUS
VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext
);
412 /* ------------------------------------------------------ blockdev.c */
414 NTSTATUS
VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject
,
415 IN PLARGE_INTEGER ReadOffset
,
418 IN BOOLEAN Override
);
420 NTSTATUS
VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext
,
421 IN PLARGE_INTEGER ReadOffset
,
423 IN ULONG BufferOffset
,
426 NTSTATUS
VfatWriteDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext
,
427 IN PLARGE_INTEGER WriteOffset
,
428 IN ULONG WriteLength
,
429 IN ULONG BufferOffset
,
432 NTSTATUS
VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject
,
434 IN PVOID InputBuffer
,
435 IN ULONG InputBufferSize
,
436 IN OUT PVOID OutputBuffer
,
437 IN OUT PULONG pOutputBufferSize
,
438 IN BOOLEAN Override
);
440 /* ----------------------------------------------------------- dir.c */
442 NTSTATUS
VfatDirectoryControl (PVFAT_IRP_CONTEXT
);
444 BOOLEAN
FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt
,
447 PLARGE_INTEGER SystemTime
);
449 BOOLEAN
FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt
,
450 PLARGE_INTEGER SystemTime
,
454 /* -------------------------------------------------------- create.c */
456 NTSTATUS
VfatCreate (PVFAT_IRP_CONTEXT IrpContext
);
458 NTSTATUS
VfatOpenFile (PDEVICE_EXTENSION DeviceExt
,
459 PFILE_OBJECT FileObject
,
460 PVFATFCB
* parentFcb
);
462 NTSTATUS
FindFile (PDEVICE_EXTENSION DeviceExt
,
464 PUNICODE_STRING FileToFindU
,
465 PVFAT_DIRENTRY_CONTEXT DirContext
,
468 VOID
vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry
,
469 PUNICODE_STRING NameU
);
471 NTSTATUS
ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt
,
474 /* --------------------------------------------------------- close.c */
476 NTSTATUS
VfatClose (PVFAT_IRP_CONTEXT IrpContext
);
478 NTSTATUS
VfatCloseFile(PDEVICE_EXTENSION DeviceExt
,
479 PFILE_OBJECT FileObject
);
481 /* ------------------------------------------------------- cleanup.c */
483 NTSTATUS
VfatCleanup (PVFAT_IRP_CONTEXT IrpContext
);
485 /* --------------------------------------------------------- fsctl.c */
487 NTSTATUS
VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext
);
489 /* --------------------------------------------------------- finfo.c */
491 NTSTATUS
VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext
);
493 NTSTATUS
VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext
);
496 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject
,
498 PDEVICE_EXTENSION DeviceExt
,
499 PLARGE_INTEGER AllocationSize
);
501 /* --------------------------------------------------------- iface.c */
503 NTSTATUS STDCALL
DriverEntry (PDRIVER_OBJECT DriverObject
,
504 PUNICODE_STRING RegistryPath
);
506 /* --------------------------------------------------------- dirwr.c */
508 NTSTATUS
VfatAddEntry (PDEVICE_EXTENSION DeviceExt
,
509 PUNICODE_STRING PathNameU
,
512 ULONG RequestedOptions
,
515 NTSTATUS
VfatUpdateEntry (PVFATFCB pFcb
);
517 NTSTATUS
VfatDelEntry(PDEVICE_EXTENSION
, PVFATFCB
);
520 vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt
,
525 /* -------------------------------------------------------- string.c */
528 vfatSplitPathName(PUNICODE_STRING PathNameU
,
529 PUNICODE_STRING DirNameU
,
530 PUNICODE_STRING FileNameU
);
532 BOOLEAN
vfatIsLongIllegal(WCHAR c
);
534 BOOLEAN
wstrcmpjoki (PWSTR s1
,
537 /* ----------------------------------------------------------- fat.c */
539 NTSTATUS
FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt
,
540 ULONG CurrentCluster
,
543 NTSTATUS
FAT12FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt
,
546 NTSTATUS
FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt
,
547 ULONG ClusterToWrite
,
551 NTSTATUS
FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt
,
552 ULONG CurrentCluster
,
555 NTSTATUS
FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt
,
558 NTSTATUS
FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt
,
559 ULONG ClusterToWrite
,
563 NTSTATUS
FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt
,
564 ULONG CurrentCluster
,
567 NTSTATUS
FAT32FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt
,
570 NTSTATUS
FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt
,
571 ULONG ClusterToWrite
,
575 NTSTATUS
OffsetToCluster (PDEVICE_EXTENSION DeviceExt
,
581 ULONGLONG
ClusterToSector (PDEVICE_EXTENSION DeviceExt
,
584 NTSTATUS
GetNextCluster (PDEVICE_EXTENSION DeviceExt
,
585 ULONG CurrentCluster
,
588 NTSTATUS
GetNextClusterExtend (PDEVICE_EXTENSION DeviceExt
,
589 ULONG CurrentCluster
,
592 NTSTATUS
CountAvailableClusters (PDEVICE_EXTENSION DeviceExt
,
593 PLARGE_INTEGER Clusters
);
596 WriteCluster(PDEVICE_EXTENSION DeviceExt
,
597 ULONG ClusterToWrite
,
600 /* ------------------------------------------------------ direntry.c */
602 ULONG
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt
,
603 PDIR_ENTRY pDirEntry
);
605 BOOLEAN
VfatIsDirectoryEmpty(PVFATFCB Fcb
);
607 NTSTATUS
FATGetNextDirEntry(PVOID
* pContext
,
610 IN PVFAT_DIRENTRY_CONTEXT DirContext
,
613 NTSTATUS
FATXGetNextDirEntry(PVOID
* pContext
,
616 IN PVFAT_DIRENTRY_CONTEXT DirContext
,
619 /* ----------------------------------------------------------- fcb.c */
621 PVFATFCB
vfatNewFCB (PDEVICE_EXTENSION pVCB
,
622 PUNICODE_STRING pFileNameU
);
624 VOID
vfatDestroyFCB (PVFATFCB pFCB
);
626 VOID
vfatDestroyCCB(PVFATCCB pCcb
);
628 VOID
vfatGrabFCB (PDEVICE_EXTENSION pVCB
,
631 VOID
vfatReleaseFCB (PDEVICE_EXTENSION pVCB
,
634 VOID
vfatAddFCBToTable (PDEVICE_EXTENSION pVCB
,
637 PVFATFCB
vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt
,
638 PUNICODE_STRING pFileNameU
);
640 PVFATFCB
vfatMakeRootFCB (PDEVICE_EXTENSION pVCB
);
642 PVFATFCB
vfatOpenRootFCB (PDEVICE_EXTENSION pVCB
);
644 BOOLEAN
vfatFCBIsDirectory (PVFATFCB FCB
);
646 BOOLEAN
vfatFCBIsRoot(PVFATFCB FCB
);
648 NTSTATUS
vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb
,
650 PFILE_OBJECT fileObject
);
652 NTSTATUS
vfatDirFindFile (PDEVICE_EXTENSION pVCB
,
654 PUNICODE_STRING FileToFindU
,
657 NTSTATUS
vfatGetFCBForFile (PDEVICE_EXTENSION pVCB
,
658 PVFATFCB
*pParentFCB
,
660 PUNICODE_STRING pFileNameU
);
662 NTSTATUS
vfatMakeFCBFromDirEntry (PVCB vcb
,
663 PVFATFCB directoryFCB
,
664 PVFAT_DIRENTRY_CONTEXT DirContext
,
667 /* ------------------------------------------------------------ rw.c */
669 NTSTATUS
VfatRead (PVFAT_IRP_CONTEXT IrpContext
);
671 NTSTATUS
VfatWrite (PVFAT_IRP_CONTEXT IrpContext
);
673 NTSTATUS
NextCluster(PDEVICE_EXTENSION DeviceExt
,
675 PULONG CurrentCluster
,
678 /* ----------------------------------------------------------- misc.c */
680 NTSTATUS
VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext
);
682 PVFAT_IRP_CONTEXT
VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject
,
685 VOID
VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext
);
687 NTSTATUS STDCALL
VfatBuildRequest (PDEVICE_OBJECT DeviceObject
,
690 PVOID
VfatGetUserBuffer(IN PIRP
);
692 NTSTATUS
VfatLockUserBuffer(IN PIRP
, IN ULONG
,
696 VfatSetExtendedAttributes(PFILE_OBJECT FileObject
,
699 /* ------------------------------------------------------------- flush.c */
701 NTSTATUS
VfatFlush(PVFAT_IRP_CONTEXT IrpContext
);
703 NTSTATUS
VfatFlushVolume(PDEVICE_EXTENSION DeviceExt
, PVFATFCB VolumeFcb
);