+#include <debug.h>
+#include <ntifs.h>
+#include <ntdddisk.h>
+#include <reactos/helper.h>
+#ifdef __GNUC__
+#include <ndk/ntndk.h>
+#include <ccros.h>
+#define USE_ROS_CC_AND_FS
+#else
+#define KEBUGCHECK KeBugCheck
+#define KEBUGCHECKEX KeBugCheckEx
+#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
+#define ROUND_UP(N, S) ROUND_DOWN((N) + (S) - 1, (S))
+#endif
-
-
-struct _BootSector {
+#include <pshpack1.h>
+struct _BootSector
+{
unsigned char magic0, res0, magic1;
unsigned char OEMName[8];
unsigned short BytesPerSector;
unsigned char Drive, Res1, Sig;
unsigned long VolumeID;
unsigned char VolumeLabel[11], SysType[8];
- unsigned char Res2[450];
-} __attribute__((packed));
+ unsigned char Res2[448];
+ unsigned short Signatur1;
+};
-struct _BootSector32 {
- 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 long FATSectors32;
- unsigned char x[31];
- unsigned char VolumeLabel[11], SysType[8];
- unsigned char Res2[422];
-} __attribute__((packed));
+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 {
- unsigned char Filename[8], Ext[3], Attrib, Res[2];
+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 FirstClusterHigh; // higher
+ unsigned short UpdateTime; //time create/update
+ unsigned short UpdateDate; //date create/update
unsigned short FirstCluster;
unsigned long FileSize;
-} __attribute__((packed));
+};
+
+typedef struct _FATDirEntry FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
-typedef struct _FATDirEntry FATDirEntry;
+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
+ 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
+ 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
-} __attribute__((packed));
-
+ WCHAR name11_12[2]; // last 2 characters in name
+};
typedef struct _slot slot;
+#include <poppack.h>
+
+#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 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
{
- ERESOURCE Resource;
- PDEVICE_OBJECT StorageDevice;
- BootSector *Boot;
- int rootDirectorySectors, FATStart, rootStart, dataStart;
- int FATEntriesPerSector, FATUnit;
- ULONG BytesPerCluster;
- ULONG FatType;
- unsigned char* FAT;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-typedef struct _FSRTL_COMMON_FCB_HEADER{
- char IsFastIoPossible;//is char the realtype ?
- ERESOURCE Resource;
- ERESOURCE PagingIoResource;
- ULONG Flags;// is long the real type ?
- LARGE_INTEGER AllocationSize;
- LARGE_INTEGER FileSize;
- LARGE_INTEGER ValidDataLength;
- // other fields ??
-} FSRTL_COMMON_FCB_HEADER;
-
-typedef struct _SFsdNTRequiredFCB {
- FSRTL_COMMON_FCB_HEADER CommonFCBHeader;
- SECTION_OBJECT_POINTERS SectionObject;
- ERESOURCE MainResource;
- ERESOURCE PagingIoResource;
-} SFsdNTRequiredFCB, *PtrSFsdNTRequiredFCB;
-
-struct _VfatFCB;
-typedef struct _VfatFCB
-{
- SFsdNTRequiredFCB NTRequiredFCB;
- FATDirEntry entry;
- WCHAR *ObjectName; // point on filename (250 chars max) in PathName
- WCHAR PathName[MAX_PATH];// path+filename 260 max
- long RefCount;
- PDEVICE_EXTENSION pDevExt;
- struct _VfatFCB * nextFcb, *prevFcb;
- struct _VfatFCB * parentFcb;
-} VfatFCB, *PVfatFCB;
+ 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
{
- VfatFCB * pFcb;
- LIST_ENTRY NextCCB;
- PFILE_OBJECT PtrFileObject;
+ 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;
- ULONG StartSector; // for DirectoryControl
- ULONG StartEntry; //for DirectoryControl
-// PSTRING DirectorySearchPattern;// for DirectoryControl ?
-} VfatCCB, *PVfatCCB;
+ /* 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 NTAPI 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 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 NTAPI 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 NTAPI 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);
+
-extern PVfatFCB pFirstFcb;
-
-// functions called by i/o manager :
-NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,PUNICODE_STRING RegistryPath);
-NTSTATUS FsdDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-
-
-// internal functions in blockdev.c
-BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
- IN ULONG DiskSector,
- IN ULONG SectorCount,
- IN UCHAR* Buffer);
-
-BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
- IN ULONG DiskSector,
- IN ULONG SectorCount,
- IN UCHAR* Buffer);
-
-//internal functions in iface.c :
-NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
- PVfatFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
-NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject);
-NTSTATUS FsdGetStandardInformation(PVfatFCB FCB, PDEVICE_OBJECT DeviceObject,
- PFILE_STANDARD_INFORMATION StandardInfo);
-NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
- PWSTR FileName);
-NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
- PVOID Buffer, ULONG Length, ULONG ReadOffset,
- PULONG LengthRead);
-NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
- PVOID Buffer, ULONG Length, ULONG WriteOffset);
-ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster);
-BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset);
-BOOLEAN IsLastEntry(PVOID Block, ULONG Offset);
-wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
-void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster);
-
-//internal functions in dirwr.c
-NTSTATUS addEntry(PDEVICE_EXTENSION DeviceExt
- ,PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr);
-NTSTATUS updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject);
-
-
-//FIXME : following defines must be removed
-//FIXME when this functions will work.
-#define ExAcquireResourceExclusiveLite(x,y) {}
-#define ExReleaseResourceForThreadLite(x,y) {}
+/* EOF */