/* $Id: vfat.h 16656 2005-07-20 02:52:52Z ion $ */ #include #include #include #include #include #include #include #define USE_ROS_CC_AND_FS #include struct _BootSector { unsigned char magic0, res0, magic1; unsigned char OEMName[8]; unsigned short BytesPerSector; unsigned char SectorsPerCluster; unsigned short ReservedSectors; unsigned char FATCount; unsigned short RootEntries, Sectors; unsigned char Media; unsigned short FATSectors, SectorsPerTrack, Heads; unsigned long HiddenSectors, SectorsHuge; unsigned char Drive, Res1, Sig; unsigned long VolumeID; unsigned char VolumeLabel[11], SysType[8]; unsigned char Res2[448]; unsigned short Signatur1; }; struct _BootSector32 { unsigned char magic0, res0, magic1; // 0 unsigned char OEMName[8]; // 3 unsigned short BytesPerSector; // 11 unsigned char SectorsPerCluster; // 13 unsigned short ReservedSectors; // 14 unsigned char FATCount; // 16 unsigned short RootEntries, Sectors; // 17 unsigned char Media; // 21 unsigned short FATSectors, SectorsPerTrack, Heads; // 22 unsigned long HiddenSectors, SectorsHuge; // 28 unsigned long FATSectors32; // 36 unsigned short ExtFlag; // 40 unsigned short FSVersion; // 42 unsigned long RootCluster; // 44 unsigned short FSInfoSector; // 48 unsigned short BootBackup; // 50 unsigned char Res3[12]; // 52 unsigned char Drive; // 64 unsigned char Res4; // 65 unsigned char ExtBootSignature; // 66 unsigned long VolumeID; // 67 unsigned char VolumeLabel[11], SysType[8]; // 71 unsigned char Res2[420]; // 90 unsigned short Signature1; // 510 }; struct _BootSectorFatX { unsigned char SysType[4]; // 0 unsigned long VolumeID; // 4 unsigned long SectorsPerCluster; // 8 unsigned short FATCount; // 12 unsigned long Unknown; // 14 unsigned char Unused[4078]; // 18 }; struct _FsInfoSector { unsigned long ExtBootSignature2; // 0 unsigned char Res6[480]; // 4 unsigned long FSINFOSignature; // 484 unsigned long FreeCluster; // 488 unsigned long NextCluster; // 492 unsigned char Res7[12]; // 496 unsigned long Signatur2; // 508 }; typedef struct _BootSector BootSector; struct _FATDirEntry { union { struct { unsigned char Filename[8], Ext[3]; }; unsigned char ShortName[11]; }; unsigned char Attrib; unsigned char lCase; unsigned char CreationTimeMs; unsigned short CreationTime,CreationDate,AccessDate; unsigned short FirstClusterHigh; // higher unsigned short UpdateTime; //time create/update unsigned short UpdateDate; //date create/update unsigned short FirstCluster; unsigned long FileSize; }; typedef struct _FATDirEntry FAT_DIR_ENTRY, *PFAT_DIR_ENTRY; struct _FATXDirEntry { unsigned char FilenameLength; // 0 unsigned char Attrib; // 1 unsigned char Filename[42]; // 2 unsigned long FirstCluster; // 44 unsigned long FileSize; // 48 unsigned short UpdateTime; // 52 unsigned short UpdateDate; // 54 unsigned short CreationTime; // 56 unsigned short CreationDate; // 58 unsigned short AccessTime; // 60 unsigned short AccessDate; // 62 }; struct _slot { unsigned char id; // sequence number for slot WCHAR name0_4[5]; // first 5 characters in name unsigned char attr; // attribute byte unsigned char reserved; // always 0 unsigned char alias_checksum; // checksum for 8.3 alias WCHAR name5_10[6]; // 6 more characters in name unsigned char start[2]; // starting cluster number WCHAR name11_12[2]; // last 2 characters in name }; typedef struct _slot slot; #include #define VFAT_CASE_LOWER_BASE 8 // base is lower case #define VFAT_CASE_LOWER_EXT 16 // extension is lower case #define LONGNAME_MAX_LENGTH 256 // max length for a long filename #define ENTRY_DELETED(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat))) #define ENTRY_VOLUME(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat))) #define ENTRY_END(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat))) #define FAT_ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5) #define FAT_ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0) #define FAT_ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f) #define FAT_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08) #define FATX_ENTRY_DELETED(DirEntry) ((DirEntry)->FilenameLength == 0xe5) #define FATX_ENTRY_END(DirEntry) ((DirEntry)->FilenameLength == 0xff) #define FATX_ENTRY_LONG(DirEntry) (FALSE) #define FATX_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08) #define FAT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FAT_DIR_ENTRY)) #define FATX_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATX_DIR_ENTRY)) typedef struct _FATXDirEntry FATX_DIR_ENTRY, *PFATX_DIR_ENTRY; union _DIR_ENTRY { FAT_DIR_ENTRY Fat; FATX_DIR_ENTRY FatX; }; typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY; #define BLOCKSIZE 512 #define FAT16 (1) #define FAT12 (2) #define FAT32 (3) #define FATX16 (4) #define FATX32 (5) #define VCB_VOLUME_LOCKED 0x0001 #define VCB_DISMOUNT_PENDING 0x0002 #define VCB_IS_FATX 0x0004 #define VCB_IS_DIRTY 0x4000 /* Volume is dirty */ #define VCB_CLEAR_DIRTY 0x8000 /* Clean dirty flag at shutdown */ typedef struct { ULONG VolumeID; ULONG FATStart; ULONG FATCount; ULONG FATSectors; ULONG rootDirectorySectors; ULONG rootStart; ULONG dataStart; ULONG RootCluster; ULONG SectorsPerCluster; ULONG BytesPerSector; ULONG BytesPerCluster; ULONG NumberOfClusters; ULONG FatType; ULONG Sectors; BOOLEAN FixedMedia; } FATINFO, *PFATINFO; struct _VFATFCB; struct _VFAT_DIRENTRY_CONTEXT; typedef struct _HASHENTRY { ULONG Hash; struct _VFATFCB* self; struct _HASHENTRY* next; } HASHENTRY; #define FCB_HASH_TABLE_SIZE 65536 typedef struct DEVICE_EXTENSION *PDEVICE_EXTENSION; typedef NTSTATUS (*PGET_NEXT_CLUSTER)(PDEVICE_EXTENSION,ULONG,PULONG); typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG); typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG); typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN); typedef struct DEVICE_EXTENSION { ERESOURCE DirResource; ERESOURCE FatResource; KSPIN_LOCK FcbListLock; LIST_ENTRY FcbListHead; ULONG HashTableSize; struct _HASHENTRY** FcbHashTable; PDEVICE_OBJECT StorageDevice; PFILE_OBJECT FATFileObject; FATINFO FatInfo; ULONG LastAvailableCluster; ULONG AvailableClusters; BOOLEAN AvailableClustersValid; ULONG Flags; struct _VFATFCB * VolumeFcb; /* Pointers to functions for manipulating FAT. */ PGET_NEXT_CLUSTER GetNextCluster; PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster; PWRITE_CLUSTER WriteCluster; ULONG CleanShutBitMask; /* Pointers to functions for manipulating directory entries. */ PGET_NEXT_DIR_ENTRY GetNextDirEntry; ULONG BaseDateYear; LIST_ENTRY VolumeListEntry; } DEVICE_EXTENSION, VCB, *PVCB; typedef struct { PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT DeviceObject; ULONG Flags; ERESOURCE VolumeListLock; LIST_ENTRY VolumeListHead; NPAGED_LOOKASIDE_LIST FcbLookasideList; NPAGED_LOOKASIDE_LIST CcbLookasideList; NPAGED_LOOKASIDE_LIST IrpContextLookasideList; FAST_IO_DISPATCH FastIoDispatch; CACHE_MANAGER_CALLBACKS CacheMgrCallbacks; } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA; extern PVFAT_GLOBAL_DATA VfatGlobalData; #define FCB_CACHE_INITIALIZED 0x0001 #define FCB_DELETE_PENDING 0x0002 #define FCB_IS_FAT 0x0004 #define FCB_IS_PAGE_FILE 0x0008 #define FCB_IS_VOLUME 0x0010 #define FCB_IS_DIRTY 0x0020 #define FCB_IS_FATX_ENTRY 0x0040 typedef struct _VFATFCB { /* FCB header required by ROS/NT */ FSRTL_COMMON_FCB_HEADER RFCB; SECTION_OBJECT_POINTERS SectionObjectPointers; ERESOURCE MainResource; ERESOURCE PagingIoResource; /* end FCB header required by ROS/NT */ /* directory entry for this file or directory */ DIR_ENTRY entry; /* Pointer to attributes in entry */ PUCHAR Attributes; /* long file name, points into PathNameBuffer */ UNICODE_STRING LongNameU; /* short file name */ UNICODE_STRING ShortNameU; /* directory name, points into PathNameBuffer */ UNICODE_STRING DirNameU; /* path + long file name 260 max*/ UNICODE_STRING PathNameU; /* buffer for PathNameU */ PWCHAR PathNameBuffer; /* buffer for ShortNameU */ WCHAR ShortNameBuffer[13]; /* */ LONG RefCount; /* List of FCB's for this volume */ LIST_ENTRY FcbListEntry; /* pointer to the parent fcb */ struct _VFATFCB* parentFcb; /* Flags for the fcb */ ULONG Flags; /* pointer to the file object which has initialized the fcb */ PFILE_OBJECT FileObject; /* Directory index for the short name entry */ ULONG dirIndex; /* Directory index where the long name starts */ ULONG startIndex; /* Share access for the file object */ SHARE_ACCESS FCBShareAccess; /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */ ULONG OpenHandleCount; /* Entry into the hash table for the path + long name */ HASHENTRY Hash; /* Entry into the hash table for the path + short name */ HASHENTRY ShortHash; /* List of byte-range locks for this file */ FILE_LOCK FileLock; /* * Optimalization: caching of last read/write cluster+offset pair. Can't * be in VFATCCB because it must be reset everytime the allocated clusters * change. */ FAST_MUTEX LastMutex; ULONG LastCluster; ULONG LastOffset; } VFATFCB, *PVFATFCB; typedef struct _VFATCCB { LARGE_INTEGER CurrentByteOffset; /* for DirectoryControl */ ULONG Entry; /* for DirectoryControl */ UNICODE_STRING SearchPattern; } VFATCCB, *PVFATCCB; #ifndef TAG #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) #endif #define TAG_CCB TAG('V', 'C', 'C', 'B') #define TAG_FCB TAG('V', 'F', 'C', 'B') #define TAG_IRP TAG('V', 'I', 'R', 'P') #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry)) typedef struct __DOSTIME { USHORT Second:5; USHORT Minute:6; USHORT Hour:5; } DOSTIME, *PDOSTIME; typedef struct __DOSDATE { USHORT Day:5; USHORT Month:4; USHORT Year:5; } DOSDATE, *PDOSDATE; #define IRPCONTEXT_CANWAIT 0x0001 #define IRPCONTEXT_PENDINGRETURNED 0x0002 typedef struct { PIRP Irp; PDEVICE_OBJECT DeviceObject; PDEVICE_EXTENSION DeviceExt; ULONG Flags; WORK_QUEUE_ITEM WorkQueueItem; PIO_STACK_LOCATION Stack; UCHAR MajorFunction; UCHAR MinorFunction; PFILE_OBJECT FileObject; ULONG RefCount; KEVENT Event; } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT; typedef struct _VFAT_DIRENTRY_CONTEXT { ULONG StartIndex; ULONG DirIndex; DIR_ENTRY DirEntry; UNICODE_STRING LongNameU; UNICODE_STRING ShortNameU; } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT; /* ------------------------------------------------------ shutdown.c */ NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject, PIRP Irp); /* -------------------------------------------------------- volume.c */ NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext); /* ------------------------------------------------------ blockdev.c */ NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN PUCHAR Buffer, IN BOOLEAN Override); NTSTATUS VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN ULONG BufferOffset, IN BOOLEAN Wait); NTSTATUS VfatWriteDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN ULONG BufferOffset, IN BOOLEAN Wait); NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer, IN OUT PULONG pOutputBufferSize, IN BOOLEAN Override); /* ----------------------------------------------------------- dir.c */ NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT); BOOLEAN FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime); BOOLEAN FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, USHORT *pDosDate, USHORT *pDosTime); /* -------------------------------------------------------- create.c */ NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PVFATFCB* parentFcb); NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Parent, PUNICODE_STRING FileToFindU, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First); VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU); NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb); /* --------------------------------------------------------- close.c */ NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject); /* ------------------------------------------------------- cleanup.c */ NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext); /* --------------------------------------------------------- fastio.c */ VOID VfatInitFastIoRoutines(PFAST_IO_DISPATCH FastIoDispatch); BOOLEAN NTAPI VfatAcquireForLazyWrite(IN PVOID Context, IN BOOLEAN Wait); VOID NTAPI VfatReleaseFromLazyWrite(IN PVOID Context); BOOLEAN NTAPI VfatAcquireForReadAhead(IN PVOID Context, IN BOOLEAN Wait); VOID NTAPI VfatReleaseFromReadAhead(IN PVOID Context); /* --------------------------------------------------------- fsctl.c */ NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext); /* --------------------------------------------------------- finfo.c */ NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PVFATFCB Fcb, PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER AllocationSize); /* --------------------------------------------------------- iface.c */ NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); /* --------------------------------------------------------- dirwr.c */ NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt, PUNICODE_STRING PathNameU, PVFATFCB* Fcb, PVFATFCB ParentFcb, ULONG RequestedOptions, UCHAR ReqAttr); NTSTATUS VfatUpdateEntry (PVFATFCB pFcb); NTSTATUS VfatDelEntry(PDEVICE_EXTENSION, PVFATFCB); BOOLEAN vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt, PVFATFCB pDirFcb, ULONG nbSlots, PULONG start); /* -------------------------------------------------------- string.c */ VOID vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU); BOOLEAN vfatIsLongIllegal(WCHAR c); BOOLEAN wstrcmpjoki (PWSTR s1, PWSTR s2); /* ----------------------------------------------------------- fat.c */ NTSTATUS FAT12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster); NTSTATUS FAT12FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster); NTSTATUS FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue); NTSTATUS FAT16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster); NTSTATUS FAT16FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster); NTSTATUS FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue); NTSTATUS FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster); NTSTATUS FAT32FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster); NTSTATUS FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue, PULONG OldValue); NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, ULONG FileOffset, PULONG Cluster, BOOLEAN Extend); ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt, ULONG Cluster); NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster); NTSTATUS GetNextClusterExtend (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, PULONG NextCluster); NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER Clusters); NTSTATUS WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, ULONG NewValue); /* ------------------------------------------------------ direntry.c */ ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pDirEntry); BOOLEAN VfatIsDirectoryEmpty(PVFATFCB Fcb); NTSTATUS FATGetNextDirEntry(PVOID * pContext, PVOID * pPage, IN PVFATFCB pDirFcb, IN PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First); NTSTATUS FATXGetNextDirEntry(PVOID * pContext, PVOID * pPage, IN PVFATFCB pDirFcb, IN PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First); /* ----------------------------------------------------------- fcb.c */ PVFATFCB vfatNewFCB (PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU); VOID vfatDestroyFCB (PVFATFCB pFCB); VOID vfatDestroyCCB(PVFATCCB pCcb); VOID vfatGrabFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB); VOID vfatReleaseFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB); VOID vfatAddFCBToTable (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB); PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt, PUNICODE_STRING pFileNameU); PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB); PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB); BOOLEAN vfatFCBIsDirectory (PVFATFCB FCB); BOOLEAN vfatFCBIsRoot(PVFATFCB FCB); NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, PVFATFCB fcb, PFILE_OBJECT fileObject); NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB, PVFATFCB parentFCB, PUNICODE_STRING FileToFindU, PVFATFCB * fileFCB); NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, PUNICODE_STRING pFileNameU); NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb, PVFATFCB directoryFCB, PVFAT_DIRENTRY_CONTEXT DirContext, PVFATFCB * fileFCB); /* ------------------------------------------------------------ rw.c */ NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext); NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend); /* ----------------------------------------------------------- misc.c */ NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext); PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp); VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext); NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp); PVOID VfatGetUserBuffer(IN PIRP); NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG, IN LOCK_OPERATION); NTSTATUS VfatSetExtendedAttributes(PFILE_OBJECT FileObject, PVOID Ea, ULONG EaLength); /* ------------------------------------------------------------- flush.c */ NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext); NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb); /* EOF */