- Add DDK alignment macros and move/rename the ones in the NDK for user-mode only...
[reactos.git] / reactos / drivers / fs / vfat / vfat.h
index a64f086..d1f8f1d 100644 (file)
@@ -1,8 +1,23 @@
-/* $Id: vfat.h,v 1.29 2001/05/10 04:02:21 rex Exp $ */
-
-#include <ddk/ntifs.h>
-
-struct _BootSector { 
+#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
+
+#include <pshpack1.h>
+struct _BootSector
+{
   unsigned char  magic0, res0, magic1;
   unsigned char  OEMName[8];
   unsigned short BytesPerSector;
@@ -16,294 +31,715 @@ struct _BootSector {
   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[27];
-  unsigned long  VolumeID;
-  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
+{
+  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 StreamStorageDevice;
-  PBCB StorageBcb;
-  PFILE_OBJECT Fat12StorageDevice;
-  PBCB Fat12StorageBcb;
-  BootSector *Boot;
-  int rootDirectorySectors, FATStart, rootStart, dataStart;
-  int FATEntriesPerSector, FATUnit;
-  ULONG BytesPerCluster;
-  ULONG FatType;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
+  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
 {
-  REACTOS_COMMON_FCB_HEADER RFCB;
+  /* FCB header required by ROS/NT */
+  FSRTL_COMMON_FCB_HEADER RFCB;
   SECTION_OBJECT_POINTERS SectionObjectPointers;
-  FATDirEntry entry;
-  /* point on filename (250 chars max) in PathName */
-  WCHAR *ObjectName; 
-  /* path+filename 260 max */
-  WCHAR PathName[MAX_PATH]; 
+  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;
-  PDEVICE_EXTENSION pDevExt;
+
+  /* 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
 {
-  VFATFCB *   pFcb;
-  LIST_ENTRY     NextCCB;
-  PFILE_OBJECT   PtrFileObject;
   LARGE_INTEGER  CurrentByteOffset;
   /* for DirectoryControl */
-  ULONG StartSector; 
+  ULONG Entry;
   /* for DirectoryControl */
-  ULONG StartEntry;  
-  //    PSTRING DirectorySearchPattern;// 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
 {
-   WORD        Second:5; 
-   WORD        Minute:6;
-   WORD Hour:5;
-} DOSTIME, *PDOSTIME;
+   USHORT Second:5;
+   USHORT Minute:6;
+   USHORT Hour:5;
+}
+DOSTIME, *PDOSTIME;
 
 typedef struct __DOSDATE
 {
-   WORD        Day:5; 
-   WORD        Month:4;
-   WORD Year:5;
-} DOSDATE, *PDOSDATE;
-
-/* functions called by i/o manager : */
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT _DriverObject,PUNICODE_STRING RegistryPath);
-NTSTATUS STDCALL
-VfatDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatCleanup (PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS STDCALL
-VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+   USHORT Day:5;
+   USHORT Month:4;
+   USHORT Year:5;
+}
+DOSDATE, *PDOSDATE;
 
+#define IRPCONTEXT_CANWAIT         0x0001
+#define IRPCONTEXT_PENDINGRETURNED  0x0002
 
-NTSTATUS
-NextCluster(PDEVICE_EXTENSION DeviceExt,
-           ULONG FirstCluster,
-           PULONG CurrentCluster,
-           BOOLEAN Extend);
+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;
 
-/* internal functions in blockdev.c */
-NTSTATUS
-VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject,
-               IN ULONG   DiskSector,
-               IN ULONG       SectorCount,
-               IN UCHAR*       Buffer);
+
+/*  ------------------------------------------------------  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
-VfatWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
-                IN ULONG   DiskSector,
-                IN ULONG        SectorCount,
-                IN UCHAR*      Buffer);
-
-/* internal functions in dir.c : */
-BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime);
-BOOL FsdFileTimeToDosDateTime(TIME *FileTime,WORD *pwDosDate,WORD *pwDosTime);
-
-/* internal functions in iface.c : */
-NTSTATUS 
-FindFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
-        PVFATFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
-NTSTATUS 
-VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject);
-NTSTATUS 
-VfatOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, 
-           PWSTR FileName);
-NTSTATUS 
-VfatReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
-            PVOID Buffer, ULONG Length, ULONG ReadOffset,
-             PULONG LengthRead, ULONG NoCache);
-NTSTATUS 
-VfatWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
-              PVOID Buffer, ULONG Length, ULONG WriteOffset, ULONG NoCache);
-NTSTATUS
-GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, 
-                   ULONG FirstCluster,
-                   ULONG CurrentCluster,
-                   PULONG NextCluster);
-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);
-NTSTATUS 
-VfatRawWriteCluster(PDEVICE_EXTENSION DeviceExt, 
-                   ULONG FirstCluster, 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);
-
-/*
- * String functions
- */
-VOID 
-vfat_initstr(wchar_t *wstr, ULONG wsize);
-wchar_t* 
-vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount);
-wchar_t* 
-vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
-wchar_t* 
-vfat_movstr(wchar_t *src, ULONG dpos, ULONG spos, ULONG len);
-BOOLEAN 
-wstrcmpi(PWSTR s1, PWSTR s2);
-BOOLEAN 
-wstrcmpjoki(PWSTR s1, PWSTR s2);
-PWCHAR  vfatGetNextPathElement (PWCHAR  pFileName);
-void  vfatWSubString (PWCHAR pTarget, const PWCHAR pSource, size_t pLength);
-BOOL  vfatIsFileNameValid (PWCHAR pFileName);
-
-/*
- * functions from fat.c
- */
-ULONG 
-ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster);
-NTSTATUS
-GetNextCluster(PDEVICE_EXTENSION DeviceExt, 
-              ULONG CurrentCluster,
-              PULONG NextCluster,
-              BOOLEAN Extend);
-NTSTATUS
-GetNextSector (PDEVICE_EXTENSION DeviceExt, 
-               ULONG CurrentSector,
-               PULONG NextSector,
-               BOOLEAN Extend);
-NTSTATUS
-VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt, 
-                   ULONG FirstCluster,
-                   PVOID Buffer, 
-                   ULONG Cluster);
-ULONG 
-FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
-ULONG 
-FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
-ULONG 
-FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
-NTSTATUS
-WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
-             ULONG NewValue);
-
-/*
- * From create.c
- */
-NTSTATUS 
-ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);
+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
-VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
-             PWSTR FileName);
+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);
 
-/*  -----------------------------------------------------  FCB Functions */
+VOID vfatReleaseFCB (PDEVICE_EXTENSION  pVCB,
+                     PVFATFCB  pFCB);
 
-PVFATFCB  vfatNewFCB (PWCHAR pFileName);
-void  vfatDestroyFCB (PVFATFCB  pFCB);
-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, 
-                                PWSTR  pFileName);
-PVFATFCB  vfatMakeRootFCB (PDEVICE_EXTENSION  pVCB);
-PVFATFCB  vfatOpenRootFCB (PDEVICE_EXTENSION  pVCB);
-BOOL  vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, PVFATFCB FCB);
-PVFATFCB  vfatDirFindFile (PDEVICE_EXTENSION pVCB, 
-                           PVFATFCB parentFCB, 
-                           const PWSTR elementName);
-NTSTATUS  vfatGetFCBForFile (PDEVICE_EXTENSION  pVCB, 
-                             PVFATFCB  *pParentFCB, 
-                             PVFATFCB  *pFCB, 
-                             const PWSTR  pFileName);
+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);
 
 
+/* EOF */