xref: /reactos/drivers/filesystems/vfatfs/vfat.h (revision 14c39362)
1*14c39362SHervé Poussineau #ifndef _VFATFS_PCH_
2*14c39362SHervé Poussineau #define _VFATFS_PCH_
3*14c39362SHervé Poussineau 
4*14c39362SHervé Poussineau #include <ntifs.h>
5*14c39362SHervé Poussineau #include <ntdddisk.h>
6*14c39362SHervé Poussineau #include <dos.h>
7*14c39362SHervé Poussineau #include <pseh/pseh2.h>
8*14c39362SHervé Poussineau #include <section_attribs.h>
9*14c39362SHervé Poussineau #ifdef KDBG
10*14c39362SHervé Poussineau #include <ndk/kdfuncs.h>
11*14c39362SHervé Poussineau #include <reactos/kdros.h>
12*14c39362SHervé Poussineau #endif
13*14c39362SHervé Poussineau 
14*14c39362SHervé Poussineau 
15*14c39362SHervé Poussineau #define USE_ROS_CC_AND_FS
16*14c39362SHervé Poussineau #define ENABLE_SWAPOUT
17*14c39362SHervé Poussineau 
18*14c39362SHervé Poussineau /* FIXME: because volume is not cached, we have to perform direct IOs
19*14c39362SHervé Poussineau  * The day this is fixed, just comment out that line, and check
20*14c39362SHervé Poussineau  * it still works (and delete old code ;-))
21*14c39362SHervé Poussineau  */
22*14c39362SHervé Poussineau #define VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
23*14c39362SHervé Poussineau 
24*14c39362SHervé Poussineau 
25*14c39362SHervé Poussineau #define ROUND_DOWN(n, align) \
26*14c39362SHervé Poussineau     (((ULONG)n) & ~((align) - 1l))
27*14c39362SHervé Poussineau 
28*14c39362SHervé Poussineau #define ROUND_UP(n, align) \
29*14c39362SHervé Poussineau     ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
30*14c39362SHervé Poussineau 
31*14c39362SHervé Poussineau #define ROUND_DOWN_64(n, align) \
32*14c39362SHervé Poussineau     (((ULONGLONG)n) & ~((align) - 1LL))
33*14c39362SHervé Poussineau 
34*14c39362SHervé Poussineau #define ROUND_UP_64(n, align) \
35*14c39362SHervé Poussineau     ROUND_DOWN_64(((ULONGLONG)n) + (align) - 1LL, (align))
36*14c39362SHervé Poussineau 
37*14c39362SHervé Poussineau #include <pshpack1.h>
38*14c39362SHervé Poussineau struct _BootSector
39*14c39362SHervé Poussineau {
40*14c39362SHervé Poussineau     unsigned char  magic0, res0, magic1;
41*14c39362SHervé Poussineau     unsigned char  OEMName[8];
42*14c39362SHervé Poussineau     unsigned short BytesPerSector;
43*14c39362SHervé Poussineau     unsigned char  SectorsPerCluster;
44*14c39362SHervé Poussineau     unsigned short ReservedSectors;
45*14c39362SHervé Poussineau     unsigned char  FATCount;
46*14c39362SHervé Poussineau     unsigned short RootEntries, Sectors;
47*14c39362SHervé Poussineau     unsigned char  Media;
48*14c39362SHervé Poussineau     unsigned short FATSectors, SectorsPerTrack, Heads;
49*14c39362SHervé Poussineau     unsigned long  HiddenSectors, SectorsHuge;
50*14c39362SHervé Poussineau     unsigned char  Drive, Res1, Sig;
51*14c39362SHervé Poussineau     unsigned long  VolumeID;
52*14c39362SHervé Poussineau     unsigned char  VolumeLabel[11], SysType[8];
53*14c39362SHervé Poussineau     unsigned char  Res2[448];
54*14c39362SHervé Poussineau     unsigned short Signatur1;
55*14c39362SHervé Poussineau };
56*14c39362SHervé Poussineau 
57*14c39362SHervé Poussineau struct _BootSector32
58*14c39362SHervé Poussineau {
59*14c39362SHervé Poussineau     unsigned char  magic0, res0, magic1;			// 0
60*14c39362SHervé Poussineau     unsigned char  OEMName[8];				// 3
61*14c39362SHervé Poussineau     unsigned short BytesPerSector;			// 11
62*14c39362SHervé Poussineau     unsigned char  SectorsPerCluster;			// 13
63*14c39362SHervé Poussineau     unsigned short ReservedSectors;			// 14
64*14c39362SHervé Poussineau     unsigned char  FATCount;				// 16
65*14c39362SHervé Poussineau     unsigned short RootEntries, Sectors;			// 17
66*14c39362SHervé Poussineau     unsigned char  Media;					// 21
67*14c39362SHervé Poussineau     unsigned short FATSectors, SectorsPerTrack, Heads;	// 22
68*14c39362SHervé Poussineau     unsigned long  HiddenSectors, SectorsHuge;		// 28
69*14c39362SHervé Poussineau     unsigned long  FATSectors32;				// 36
70*14c39362SHervé Poussineau     unsigned short ExtFlag;				// 40
71*14c39362SHervé Poussineau     unsigned short FSVersion;				// 42
72*14c39362SHervé Poussineau     unsigned long  RootCluster;				// 44
73*14c39362SHervé Poussineau     unsigned short FSInfoSector;				// 48
74*14c39362SHervé Poussineau     unsigned short BootBackup;				// 50
75*14c39362SHervé Poussineau     unsigned char  Res3[12];				// 52
76*14c39362SHervé Poussineau     unsigned char  Drive;					// 64
77*14c39362SHervé Poussineau     unsigned char  Res4;					// 65
78*14c39362SHervé Poussineau     unsigned char  ExtBootSignature;			// 66
79*14c39362SHervé Poussineau     unsigned long  VolumeID;				// 67
80*14c39362SHervé Poussineau     unsigned char  VolumeLabel[11], SysType[8];		// 71
81*14c39362SHervé Poussineau     unsigned char  Res2[420];				// 90
82*14c39362SHervé Poussineau     unsigned short Signature1;				// 510
83*14c39362SHervé Poussineau };
84*14c39362SHervé Poussineau 
85*14c39362SHervé Poussineau #define FAT_DIRTY_BIT 0x01
86*14c39362SHervé Poussineau 
87*14c39362SHervé Poussineau struct _BootSectorFatX
88*14c39362SHervé Poussineau {
89*14c39362SHervé Poussineau     unsigned char SysType[4];        // 0
90*14c39362SHervé Poussineau     unsigned long VolumeID;          // 4
91*14c39362SHervé Poussineau     unsigned long SectorsPerCluster; // 8
92*14c39362SHervé Poussineau     unsigned short FATCount;         // 12
93*14c39362SHervé Poussineau     unsigned long Unknown;           // 14
94*14c39362SHervé Poussineau     unsigned char Unused[4078];      // 18
95*14c39362SHervé Poussineau };
96*14c39362SHervé Poussineau 
97*14c39362SHervé Poussineau struct _FsInfoSector
98*14c39362SHervé Poussineau {
99*14c39362SHervé Poussineau     unsigned long  ExtBootSignature2;			// 0
100*14c39362SHervé Poussineau     unsigned char  Res6[480];				// 4
101*14c39362SHervé Poussineau     unsigned long  FSINFOSignature;			// 484
102*14c39362SHervé Poussineau     unsigned long  FreeCluster;				// 488
103*14c39362SHervé Poussineau     unsigned long  NextCluster;				// 492
104*14c39362SHervé Poussineau     unsigned char  Res7[12];				// 496
105*14c39362SHervé Poussineau     unsigned long  Signatur2;				// 508
106*14c39362SHervé Poussineau };
107*14c39362SHervé Poussineau 
108*14c39362SHervé Poussineau typedef struct _BootSector BootSector;
109*14c39362SHervé Poussineau 
110*14c39362SHervé Poussineau struct _FATDirEntry
111*14c39362SHervé Poussineau {
112*14c39362SHervé Poussineau     union
113*14c39362SHervé Poussineau     {
114*14c39362SHervé Poussineau         struct { unsigned char Filename[8], Ext[3]; };
115*14c39362SHervé Poussineau         unsigned char ShortName[11];
116*14c39362SHervé Poussineau     };
117*14c39362SHervé Poussineau     unsigned char  Attrib;
118*14c39362SHervé Poussineau     unsigned char  lCase;
119*14c39362SHervé Poussineau     unsigned char  CreationTimeMs;
120*14c39362SHervé Poussineau     unsigned short CreationTime,CreationDate,AccessDate;
121*14c39362SHervé Poussineau     union
122*14c39362SHervé Poussineau     {
123*14c39362SHervé Poussineau         unsigned short FirstClusterHigh; // FAT32
124*14c39362SHervé Poussineau         unsigned short ExtendedAttributes; // FAT12/FAT16
125*14c39362SHervé Poussineau     };
126*14c39362SHervé Poussineau     unsigned short UpdateTime;                            //time create/update
127*14c39362SHervé Poussineau     unsigned short UpdateDate;                            //date create/update
128*14c39362SHervé Poussineau     unsigned short FirstCluster;
129*14c39362SHervé Poussineau     unsigned long  FileSize;
130*14c39362SHervé Poussineau };
131*14c39362SHervé Poussineau 
132*14c39362SHervé Poussineau #define FAT_EAFILE  "EA DATA. SF"
133*14c39362SHervé Poussineau 
134*14c39362SHervé Poussineau typedef struct _EAFileHeader FAT_EA_FILE_HEADER, *PFAT_EA_FILE_HEADER;
135*14c39362SHervé Poussineau 
136*14c39362SHervé Poussineau struct _EAFileHeader
137*14c39362SHervé Poussineau {
138*14c39362SHervé Poussineau     unsigned short Signature; // ED
139*14c39362SHervé Poussineau     unsigned short Unknown[15];
140*14c39362SHervé Poussineau     unsigned short EASetTable[240];
141*14c39362SHervé Poussineau };
142*14c39362SHervé Poussineau 
143*14c39362SHervé Poussineau typedef struct _EASetHeader FAT_EA_SET_HEADER, *PFAT_EA_SET_HEADER;
144*14c39362SHervé Poussineau 
145*14c39362SHervé Poussineau struct _EASetHeader
146*14c39362SHervé Poussineau {
147*14c39362SHervé Poussineau     unsigned short Signature; // EA
148*14c39362SHervé Poussineau     unsigned short Offset; // relative offset, same value as in the EASetTable
149*14c39362SHervé Poussineau     unsigned short Unknown1[2];
150*14c39362SHervé Poussineau     char TargetFileName[12];
151*14c39362SHervé Poussineau     unsigned short Unknown2[3];
152*14c39362SHervé Poussineau     unsigned int EALength;
153*14c39362SHervé Poussineau     // EA Header
154*14c39362SHervé Poussineau };
155*14c39362SHervé Poussineau 
156*14c39362SHervé Poussineau typedef struct _EAHeader FAT_EA_HEADER, *PFAT_EA_HEADER;
157*14c39362SHervé Poussineau 
158*14c39362SHervé Poussineau struct _EAHeader
159*14c39362SHervé Poussineau {
160*14c39362SHervé Poussineau     unsigned char Unknown;
161*14c39362SHervé Poussineau     unsigned char EANameLength;
162*14c39362SHervé Poussineau     unsigned short EAValueLength;
163*14c39362SHervé Poussineau     // Name Data
164*14c39362SHervé Poussineau     // Value Data
165*14c39362SHervé Poussineau };
166*14c39362SHervé Poussineau 
167*14c39362SHervé Poussineau typedef struct _FATDirEntry FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
168*14c39362SHervé Poussineau 
169*14c39362SHervé Poussineau struct _FATXDirEntry
170*14c39362SHervé Poussineau {
171*14c39362SHervé Poussineau     unsigned char FilenameLength; // 0
172*14c39362SHervé Poussineau     unsigned char Attrib;         // 1
173*14c39362SHervé Poussineau     unsigned char Filename[42];   // 2
174*14c39362SHervé Poussineau     unsigned long FirstCluster;   // 44
175*14c39362SHervé Poussineau     unsigned long FileSize;       // 48
176*14c39362SHervé Poussineau     unsigned short UpdateTime;    // 52
177*14c39362SHervé Poussineau     unsigned short UpdateDate;    // 54
178*14c39362SHervé Poussineau     unsigned short CreationTime;  // 56
179*14c39362SHervé Poussineau     unsigned short CreationDate;  // 58
180*14c39362SHervé Poussineau     unsigned short AccessTime;    // 60
181*14c39362SHervé Poussineau     unsigned short AccessDate;    // 62
182*14c39362SHervé Poussineau };
183*14c39362SHervé Poussineau 
184*14c39362SHervé Poussineau struct _slot
185*14c39362SHervé Poussineau {
186*14c39362SHervé Poussineau     unsigned char id;               // sequence number for slot
187*14c39362SHervé Poussineau     WCHAR  name0_4[5];              // first 5 characters in name
188*14c39362SHervé Poussineau     unsigned char attr;             // attribute byte
189*14c39362SHervé Poussineau     unsigned char reserved;         // always 0
190*14c39362SHervé Poussineau     unsigned char alias_checksum;   // checksum for 8.3 alias
191*14c39362SHervé Poussineau     WCHAR  name5_10[6];             // 6 more characters in name
192*14c39362SHervé Poussineau     unsigned char start[2];         // starting cluster number
193*14c39362SHervé Poussineau     WCHAR  name11_12[2];            // last 2 characters in name
194*14c39362SHervé Poussineau };
195*14c39362SHervé Poussineau 
196*14c39362SHervé Poussineau typedef struct _slot slot;
197*14c39362SHervé Poussineau 
198*14c39362SHervé Poussineau #include <poppack.h>
199*14c39362SHervé Poussineau 
200*14c39362SHervé Poussineau #define VFAT_CASE_LOWER_BASE	8  		// base is lower case
201*14c39362SHervé Poussineau #define VFAT_CASE_LOWER_EXT 	16 		// extension is lower case
202*14c39362SHervé Poussineau 
203*14c39362SHervé Poussineau #define LONGNAME_MAX_LENGTH 	256		// max length for a long filename
204*14c39362SHervé Poussineau 
205*14c39362SHervé Poussineau #define ENTRY_DELETED(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat)))
206*14c39362SHervé Poussineau #define ENTRY_VOLUME(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat)))
207*14c39362SHervé Poussineau #define ENTRY_END(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat)))
208*14c39362SHervé Poussineau 
209*14c39362SHervé Poussineau #define FAT_ENTRY_DELETED(DirEntry)  ((DirEntry)->Filename[0] == 0xe5)
210*14c39362SHervé Poussineau #define FAT_ENTRY_END(DirEntry)      ((DirEntry)->Filename[0] == 0)
211*14c39362SHervé Poussineau #define FAT_ENTRY_LONG(DirEntry)     (((DirEntry)->Attrib & 0x3f) == 0x0f)
212*14c39362SHervé Poussineau #define FAT_ENTRY_VOLUME(DirEntry)   (((DirEntry)->Attrib & 0x1f) == 0x08)
213*14c39362SHervé Poussineau 
214*14c39362SHervé Poussineau #define FATX_ENTRY_DELETED(DirEntry) ((DirEntry)->FilenameLength == 0xe5)
215*14c39362SHervé Poussineau #define FATX_ENTRY_END(DirEntry)     ((DirEntry)->FilenameLength == 0xff)
216*14c39362SHervé Poussineau #define FATX_ENTRY_LONG(DirEntry)    (FALSE)
217*14c39362SHervé Poussineau #define FATX_ENTRY_VOLUME(DirEntry)  (((DirEntry)->Attrib & 0x1f) == 0x08)
218*14c39362SHervé Poussineau 
219*14c39362SHervé Poussineau #define FAT_ENTRIES_PER_PAGE   (PAGE_SIZE / sizeof (FAT_DIR_ENTRY))
220*14c39362SHervé Poussineau #define FATX_ENTRIES_PER_PAGE  (PAGE_SIZE / sizeof (FATX_DIR_ENTRY))
221*14c39362SHervé Poussineau 
222*14c39362SHervé Poussineau typedef struct _FATXDirEntry FATX_DIR_ENTRY, *PFATX_DIR_ENTRY;
223*14c39362SHervé Poussineau 
224*14c39362SHervé Poussineau union _DIR_ENTRY
225*14c39362SHervé Poussineau {
226*14c39362SHervé Poussineau     FAT_DIR_ENTRY Fat;
227*14c39362SHervé Poussineau     FATX_DIR_ENTRY FatX;
228*14c39362SHervé Poussineau };
229*14c39362SHervé Poussineau 
230*14c39362SHervé Poussineau typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY;
231*14c39362SHervé Poussineau 
232*14c39362SHervé Poussineau #define BLOCKSIZE 512
233*14c39362SHervé Poussineau 
234*14c39362SHervé Poussineau #define FAT16  (1)
235*14c39362SHervé Poussineau #define FAT12  (2)
236*14c39362SHervé Poussineau #define FAT32  (3)
237*14c39362SHervé Poussineau #define FATX16 (4)
238*14c39362SHervé Poussineau #define FATX32 (5)
239*14c39362SHervé Poussineau 
240*14c39362SHervé Poussineau #define VCB_VOLUME_LOCKED       0x0001
241*14c39362SHervé Poussineau #define VCB_DISMOUNT_PENDING    0x0002
242*14c39362SHervé Poussineau #define VCB_IS_FATX             0x0004
243*14c39362SHervé Poussineau #define VCB_IS_SYS_OR_HAS_PAGE  0x0008
244*14c39362SHervé Poussineau #define VCB_IS_DIRTY            0x4000 /* Volume is dirty */
245*14c39362SHervé Poussineau #define VCB_CLEAR_DIRTY         0x8000 /* Clean dirty flag at shutdown */
246*14c39362SHervé Poussineau /* VCB condition state */
247*14c39362SHervé Poussineau #define VCB_GOOD                0x0010 /* If not set, the VCB is improper for usage */
248*14c39362SHervé Poussineau 
249*14c39362SHervé Poussineau typedef struct
250*14c39362SHervé Poussineau {
251*14c39362SHervé Poussineau     ULONG VolumeID;
252*14c39362SHervé Poussineau     CHAR VolumeLabel[11];
253*14c39362SHervé Poussineau     ULONG FATStart;
254*14c39362SHervé Poussineau     ULONG FATCount;
255*14c39362SHervé Poussineau     ULONG FATSectors;
256*14c39362SHervé Poussineau     ULONG rootDirectorySectors;
257*14c39362SHervé Poussineau     ULONG rootStart;
258*14c39362SHervé Poussineau     ULONG dataStart;
259*14c39362SHervé Poussineau     ULONG RootCluster;
260*14c39362SHervé Poussineau     ULONG SectorsPerCluster;
261*14c39362SHervé Poussineau     ULONG BytesPerSector;
262*14c39362SHervé Poussineau     ULONG BytesPerCluster;
263*14c39362SHervé Poussineau     ULONG NumberOfClusters;
264*14c39362SHervé Poussineau     ULONG FatType;
265*14c39362SHervé Poussineau     ULONG Sectors;
266*14c39362SHervé Poussineau     BOOLEAN FixedMedia;
267*14c39362SHervé Poussineau     ULONG FSInfoSector;
268*14c39362SHervé Poussineau } FATINFO, *PFATINFO;
269*14c39362SHervé Poussineau 
270*14c39362SHervé Poussineau struct _VFATFCB;
271*14c39362SHervé Poussineau struct _VFAT_DIRENTRY_CONTEXT;
272*14c39362SHervé Poussineau struct _VFAT_MOVE_CONTEXT;
273*14c39362SHervé Poussineau struct _VFAT_CLOSE_CONTEXT;
274*14c39362SHervé Poussineau 
275*14c39362SHervé Poussineau typedef struct _HASHENTRY
276*14c39362SHervé Poussineau {
277*14c39362SHervé Poussineau     ULONG Hash;
278*14c39362SHervé Poussineau     struct _VFATFCB* self;
279*14c39362SHervé Poussineau     struct _HASHENTRY* next;
280*14c39362SHervé Poussineau }
281*14c39362SHervé Poussineau HASHENTRY;
282*14c39362SHervé Poussineau 
283*14c39362SHervé Poussineau typedef struct DEVICE_EXTENSION *PDEVICE_EXTENSION;
284*14c39362SHervé Poussineau 
285*14c39362SHervé Poussineau typedef NTSTATUS (*PGET_NEXT_CLUSTER)(PDEVICE_EXTENSION,ULONG,PULONG);
286*14c39362SHervé Poussineau typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
287*14c39362SHervé Poussineau typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
288*14c39362SHervé Poussineau 
289*14c39362SHervé Poussineau typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(PDEVICE_EXTENSION,struct _VFATFCB*);
290*14c39362SHervé Poussineau typedef NTSTATUS (*PADD_ENTRY)(PDEVICE_EXTENSION,PUNICODE_STRING,struct _VFATFCB**,struct _VFATFCB*,ULONG,UCHAR,struct _VFAT_MOVE_CONTEXT*);
291*14c39362SHervé Poussineau typedef NTSTATUS (*PDEL_ENTRY)(PDEVICE_EXTENSION,struct _VFATFCB*,struct _VFAT_MOVE_CONTEXT*);
292*14c39362SHervé Poussineau typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN);
293*14c39362SHervé Poussineau typedef NTSTATUS (*PGET_DIRTY_STATUS)(PDEVICE_EXTENSION,PBOOLEAN);
294*14c39362SHervé Poussineau typedef NTSTATUS (*PSET_DIRTY_STATUS)(PDEVICE_EXTENSION,BOOLEAN);
295*14c39362SHervé Poussineau 
296*14c39362SHervé Poussineau typedef struct _VFAT_DISPATCH
297*14c39362SHervé Poussineau {
298*14c39362SHervé Poussineau     PIS_DIRECTORY_EMPTY IsDirectoryEmpty;
299*14c39362SHervé Poussineau     PADD_ENTRY AddEntry;
300*14c39362SHervé Poussineau     PDEL_ENTRY DelEntry;
301*14c39362SHervé Poussineau     PGET_NEXT_DIR_ENTRY GetNextDirEntry;
302*14c39362SHervé Poussineau } VFAT_DISPATCH, *PVFAT_DISPATCH;
303*14c39362SHervé Poussineau 
304*14c39362SHervé Poussineau #define STATISTICS_SIZE_NO_PAD (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS))
305*14c39362SHervé Poussineau typedef struct _STATISTICS {
306*14c39362SHervé Poussineau     FILESYSTEM_STATISTICS Base;
307*14c39362SHervé Poussineau     FAT_STATISTICS Fat;
308*14c39362SHervé Poussineau     UCHAR Pad[((STATISTICS_SIZE_NO_PAD + 0x3f) & ~0x3f) - STATISTICS_SIZE_NO_PAD];
309*14c39362SHervé Poussineau } STATISTICS, *PSTATISTICS;
310*14c39362SHervé Poussineau 
311*14c39362SHervé Poussineau typedef struct DEVICE_EXTENSION
312*14c39362SHervé Poussineau {
313*14c39362SHervé Poussineau     ERESOURCE DirResource;
314*14c39362SHervé Poussineau     ERESOURCE FatResource;
315*14c39362SHervé Poussineau 
316*14c39362SHervé Poussineau     KSPIN_LOCK FcbListLock;
317*14c39362SHervé Poussineau     LIST_ENTRY FcbListHead;
318*14c39362SHervé Poussineau     ULONG HashTableSize;
319*14c39362SHervé Poussineau     struct _HASHENTRY **FcbHashTable;
320*14c39362SHervé Poussineau 
321*14c39362SHervé Poussineau     PDEVICE_OBJECT VolumeDevice;
322*14c39362SHervé Poussineau     PDEVICE_OBJECT StorageDevice;
323*14c39362SHervé Poussineau     PFILE_OBJECT FATFileObject;
324*14c39362SHervé Poussineau     FATINFO FatInfo;
325*14c39362SHervé Poussineau     ULONG LastAvailableCluster;
326*14c39362SHervé Poussineau     ULONG AvailableClusters;
327*14c39362SHervé Poussineau     BOOLEAN AvailableClustersValid;
328*14c39362SHervé Poussineau     ULONG Flags;
329*14c39362SHervé Poussineau     struct _VFATFCB *VolumeFcb;
330*14c39362SHervé Poussineau     struct _VFATFCB *RootFcb;
331*14c39362SHervé Poussineau     PSTATISTICS Statistics;
332*14c39362SHervé Poussineau 
333*14c39362SHervé Poussineau     /* Overflow request queue */
334*14c39362SHervé Poussineau     KSPIN_LOCK OverflowQueueSpinLock;
335*14c39362SHervé Poussineau     LIST_ENTRY OverflowQueue;
336*14c39362SHervé Poussineau     ULONG OverflowQueueCount;
337*14c39362SHervé Poussineau     ULONG PostedRequestCount;
338*14c39362SHervé Poussineau 
339*14c39362SHervé Poussineau     /* Pointers to functions for manipulating FAT. */
340*14c39362SHervé Poussineau     PGET_NEXT_CLUSTER GetNextCluster;
341*14c39362SHervé Poussineau     PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
342*14c39362SHervé Poussineau     PWRITE_CLUSTER WriteCluster;
343*14c39362SHervé Poussineau     PGET_DIRTY_STATUS GetDirtyStatus;
344*14c39362SHervé Poussineau     PSET_DIRTY_STATUS SetDirtyStatus;
345*14c39362SHervé Poussineau 
346*14c39362SHervé Poussineau     ULONG BaseDateYear;
347*14c39362SHervé Poussineau 
348*14c39362SHervé Poussineau     LIST_ENTRY VolumeListEntry;
349*14c39362SHervé Poussineau 
350*14c39362SHervé Poussineau     /* Notifications */
351*14c39362SHervé Poussineau     LIST_ENTRY NotifyList;
352*14c39362SHervé Poussineau     PNOTIFY_SYNC NotifySync;
353*14c39362SHervé Poussineau 
354*14c39362SHervé Poussineau     /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE */
355*14c39362SHervé Poussineau     ULONG OpenHandleCount;
356*14c39362SHervé Poussineau 
357*14c39362SHervé Poussineau     /* VPBs for dismount */
358*14c39362SHervé Poussineau     PVPB IoVPB;
359*14c39362SHervé Poussineau     PVPB SpareVPB;
360*14c39362SHervé Poussineau 
361*14c39362SHervé Poussineau     /* Pointers to functions for manipulating directory entries. */
362*14c39362SHervé Poussineau     VFAT_DISPATCH Dispatch;
363*14c39362SHervé Poussineau } DEVICE_EXTENSION, VCB, *PVCB;
364*14c39362SHervé Poussineau 
365*14c39362SHervé Poussineau FORCEINLINE
366*14c39362SHervé Poussineau BOOLEAN
VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,struct _VFATFCB * Fcb)367*14c39362SHervé Poussineau VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,
368*14c39362SHervé Poussineau                      struct _VFATFCB* Fcb)
369*14c39362SHervé Poussineau {
370*14c39362SHervé Poussineau     return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, Fcb);
371*14c39362SHervé Poussineau }
372*14c39362SHervé Poussineau 
373*14c39362SHervé Poussineau FORCEINLINE
374*14c39362SHervé Poussineau NTSTATUS
VfatAddEntry(PDEVICE_EXTENSION DeviceExt,PUNICODE_STRING NameU,struct _VFATFCB ** Fcb,struct _VFATFCB * ParentFcb,ULONG RequestedOptions,UCHAR ReqAttr,struct _VFAT_MOVE_CONTEXT * MoveContext)375*14c39362SHervé Poussineau VfatAddEntry(PDEVICE_EXTENSION DeviceExt,
376*14c39362SHervé Poussineau              PUNICODE_STRING NameU,
377*14c39362SHervé Poussineau              struct _VFATFCB** Fcb,
378*14c39362SHervé Poussineau              struct _VFATFCB* ParentFcb,
379*14c39362SHervé Poussineau              ULONG RequestedOptions,
380*14c39362SHervé Poussineau              UCHAR ReqAttr,
381*14c39362SHervé Poussineau              struct _VFAT_MOVE_CONTEXT* MoveContext)
382*14c39362SHervé Poussineau {
383*14c39362SHervé Poussineau     return DeviceExt->Dispatch.AddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr, MoveContext);
384*14c39362SHervé Poussineau }
385*14c39362SHervé Poussineau 
386*14c39362SHervé Poussineau FORCEINLINE
387*14c39362SHervé Poussineau NTSTATUS
VfatDelEntry(PDEVICE_EXTENSION DeviceExt,struct _VFATFCB * Fcb,struct _VFAT_MOVE_CONTEXT * MoveContext)388*14c39362SHervé Poussineau VfatDelEntry(PDEVICE_EXTENSION DeviceExt,
389*14c39362SHervé Poussineau              struct _VFATFCB* Fcb,
390*14c39362SHervé Poussineau              struct _VFAT_MOVE_CONTEXT* MoveContext)
391*14c39362SHervé Poussineau {
392*14c39362SHervé Poussineau     return DeviceExt->Dispatch.DelEntry(DeviceExt, Fcb, MoveContext);
393*14c39362SHervé Poussineau }
394*14c39362SHervé Poussineau 
395*14c39362SHervé Poussineau FORCEINLINE
396*14c39362SHervé Poussineau NTSTATUS
VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt,PVOID * pContext,PVOID * pPage,struct _VFATFCB * pDirFcb,struct _VFAT_DIRENTRY_CONTEXT * DirContext,BOOLEAN First)397*14c39362SHervé Poussineau VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt,
398*14c39362SHervé Poussineau                     PVOID *pContext,
399*14c39362SHervé Poussineau                     PVOID *pPage,
400*14c39362SHervé Poussineau                     struct _VFATFCB* pDirFcb,
401*14c39362SHervé Poussineau                     struct _VFAT_DIRENTRY_CONTEXT* DirContext,
402*14c39362SHervé Poussineau                     BOOLEAN First)
403*14c39362SHervé Poussineau {
404*14c39362SHervé Poussineau     return DeviceExt->Dispatch.GetNextDirEntry(pContext, pPage, pDirFcb, DirContext, First);
405*14c39362SHervé Poussineau }
406*14c39362SHervé Poussineau 
407*14c39362SHervé Poussineau #define VFAT_BREAK_ON_CORRUPTION 1
408*14c39362SHervé Poussineau 
409*14c39362SHervé Poussineau typedef struct
410*14c39362SHervé Poussineau {
411*14c39362SHervé Poussineau     PDRIVER_OBJECT DriverObject;
412*14c39362SHervé Poussineau     PDEVICE_OBJECT DeviceObject;
413*14c39362SHervé Poussineau     ULONG Flags;
414*14c39362SHervé Poussineau     ULONG NumberProcessors;
415*14c39362SHervé Poussineau     ERESOURCE VolumeListLock;
416*14c39362SHervé Poussineau     LIST_ENTRY VolumeListHead;
417*14c39362SHervé Poussineau     NPAGED_LOOKASIDE_LIST FcbLookasideList;
418*14c39362SHervé Poussineau     NPAGED_LOOKASIDE_LIST CcbLookasideList;
419*14c39362SHervé Poussineau     NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
420*14c39362SHervé Poussineau     PAGED_LOOKASIDE_LIST CloseContextLookasideList;
421*14c39362SHervé Poussineau     FAST_IO_DISPATCH FastIoDispatch;
422*14c39362SHervé Poussineau     CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
423*14c39362SHervé Poussineau     FAST_MUTEX CloseMutex;
424*14c39362SHervé Poussineau     ULONG CloseCount;
425*14c39362SHervé Poussineau     LIST_ENTRY CloseListHead;
426*14c39362SHervé Poussineau     BOOLEAN CloseWorkerRunning;
427*14c39362SHervé Poussineau     PIO_WORKITEM CloseWorkItem;
428*14c39362SHervé Poussineau     BOOLEAN ShutdownStarted;
429*14c39362SHervé Poussineau } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
430*14c39362SHervé Poussineau 
431*14c39362SHervé Poussineau extern PVFAT_GLOBAL_DATA VfatGlobalData;
432*14c39362SHervé Poussineau 
433*14c39362SHervé Poussineau #define FCB_CACHE_INITIALIZED   0x0001
434*14c39362SHervé Poussineau #define FCB_DELETE_PENDING      0x0002
435*14c39362SHervé Poussineau #define FCB_IS_FAT              0x0004
436*14c39362SHervé Poussineau #define FCB_IS_PAGE_FILE        0x0008
437*14c39362SHervé Poussineau #define FCB_IS_VOLUME           0x0010
438*14c39362SHervé Poussineau #define FCB_IS_DIRTY            0x0020
439*14c39362SHervé Poussineau #define FCB_DELAYED_CLOSE       0x0040
440*14c39362SHervé Poussineau #ifdef KDBG
441*14c39362SHervé Poussineau #define FCB_CLEANED_UP          0x0080
442*14c39362SHervé Poussineau #define FCB_CLOSED              0x0100
443*14c39362SHervé Poussineau #endif
444*14c39362SHervé Poussineau 
445*14c39362SHervé Poussineau #define NODE_TYPE_FCB ((CSHORT)0x0502)
446*14c39362SHervé Poussineau 
447*14c39362SHervé Poussineau typedef struct _VFATFCB
448*14c39362SHervé Poussineau {
449*14c39362SHervé Poussineau     /* FCB header required by ROS/NT */
450*14c39362SHervé Poussineau     FSRTL_COMMON_FCB_HEADER RFCB;
451*14c39362SHervé Poussineau     SECTION_OBJECT_POINTERS SectionObjectPointers;
452*14c39362SHervé Poussineau     ERESOURCE MainResource;
453*14c39362SHervé Poussineau     ERESOURCE PagingIoResource;
454*14c39362SHervé Poussineau     /* end FCB header required by ROS/NT */
455*14c39362SHervé Poussineau 
456*14c39362SHervé Poussineau     /* directory entry for this file or directory */
457*14c39362SHervé Poussineau     DIR_ENTRY entry;
458*14c39362SHervé Poussineau 
459*14c39362SHervé Poussineau     /* Pointer to attributes in entry */
460*14c39362SHervé Poussineau     PUCHAR Attributes;
461*14c39362SHervé Poussineau 
462*14c39362SHervé Poussineau     /* long file name, points into PathNameBuffer */
463*14c39362SHervé Poussineau     UNICODE_STRING LongNameU;
464*14c39362SHervé Poussineau 
465*14c39362SHervé Poussineau     /* short file name */
466*14c39362SHervé Poussineau     UNICODE_STRING ShortNameU;
467*14c39362SHervé Poussineau 
468*14c39362SHervé Poussineau     /* directory name, points into PathNameBuffer */
469*14c39362SHervé Poussineau     UNICODE_STRING DirNameU;
470*14c39362SHervé Poussineau 
471*14c39362SHervé Poussineau     /* path + long file name 260 max*/
472*14c39362SHervé Poussineau     UNICODE_STRING PathNameU;
473*14c39362SHervé Poussineau 
474*14c39362SHervé Poussineau     /* buffer for PathNameU */
475*14c39362SHervé Poussineau     PWCHAR PathNameBuffer;
476*14c39362SHervé Poussineau 
477*14c39362SHervé Poussineau     /* buffer for ShortNameU */
478*14c39362SHervé Poussineau     WCHAR ShortNameBuffer[13];
479*14c39362SHervé Poussineau 
480*14c39362SHervé Poussineau     /* */
481*14c39362SHervé Poussineau     LONG RefCount;
482*14c39362SHervé Poussineau 
483*14c39362SHervé Poussineau     /* List of FCB's for this volume */
484*14c39362SHervé Poussineau     LIST_ENTRY FcbListEntry;
485*14c39362SHervé Poussineau 
486*14c39362SHervé Poussineau     /* List of FCB's for the parent */
487*14c39362SHervé Poussineau     LIST_ENTRY ParentListEntry;
488*14c39362SHervé Poussineau 
489*14c39362SHervé Poussineau     /* pointer to the parent fcb */
490*14c39362SHervé Poussineau     struct _VFATFCB *parentFcb;
491*14c39362SHervé Poussineau 
492*14c39362SHervé Poussineau     /* List for the children */
493*14c39362SHervé Poussineau     LIST_ENTRY ParentListHead;
494*14c39362SHervé Poussineau 
495*14c39362SHervé Poussineau     /* Flags for the fcb */
496*14c39362SHervé Poussineau     ULONG Flags;
497*14c39362SHervé Poussineau 
498*14c39362SHervé Poussineau     /* pointer to the file object which has initialized the fcb */
499*14c39362SHervé Poussineau     PFILE_OBJECT FileObject;
500*14c39362SHervé Poussineau 
501*14c39362SHervé Poussineau     /* Directory index for the short name entry */
502*14c39362SHervé Poussineau     ULONG dirIndex;
503*14c39362SHervé Poussineau 
504*14c39362SHervé Poussineau     /* Directory index where the long name starts */
505*14c39362SHervé Poussineau     ULONG startIndex;
506*14c39362SHervé Poussineau 
507*14c39362SHervé Poussineau     /* Share access for the file object */
508*14c39362SHervé Poussineau     SHARE_ACCESS FCBShareAccess;
509*14c39362SHervé Poussineau 
510*14c39362SHervé Poussineau     /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */
511*14c39362SHervé Poussineau     ULONG OpenHandleCount;
512*14c39362SHervé Poussineau 
513*14c39362SHervé Poussineau     /* Entry into the hash table for the path + long name */
514*14c39362SHervé Poussineau     HASHENTRY Hash;
515*14c39362SHervé Poussineau 
516*14c39362SHervé Poussineau     /* Entry into the hash table for the path + short name */
517*14c39362SHervé Poussineau     HASHENTRY ShortHash;
518*14c39362SHervé Poussineau 
519*14c39362SHervé Poussineau     /* List of byte-range locks for this file */
520*14c39362SHervé Poussineau     FILE_LOCK FileLock;
521*14c39362SHervé Poussineau 
522*14c39362SHervé Poussineau     /*
523*14c39362SHervé Poussineau      * Optimization: caching of last read/write cluster+offset pair. Can't
524*14c39362SHervé Poussineau      * be in VFATCCB because it must be reset everytime the allocated clusters
525*14c39362SHervé Poussineau      * change.
526*14c39362SHervé Poussineau      */
527*14c39362SHervé Poussineau     FAST_MUTEX LastMutex;
528*14c39362SHervé Poussineau     ULONG LastCluster;
529*14c39362SHervé Poussineau     ULONG LastOffset;
530*14c39362SHervé Poussineau 
531*14c39362SHervé Poussineau     struct _VFAT_CLOSE_CONTEXT * CloseContext;
532*14c39362SHervé Poussineau } VFATFCB, *PVFATFCB;
533*14c39362SHervé Poussineau 
534*14c39362SHervé Poussineau #define CCB_DELETE_ON_CLOSE     0x0001
535*14c39362SHervé Poussineau 
536*14c39362SHervé Poussineau typedef struct _VFATCCB
537*14c39362SHervé Poussineau {
538*14c39362SHervé Poussineau     LARGE_INTEGER  CurrentByteOffset;
539*14c39362SHervé Poussineau     ULONG Flags;
540*14c39362SHervé Poussineau     /* for DirectoryControl */
541*14c39362SHervé Poussineau     ULONG Entry;
542*14c39362SHervé Poussineau     /* for DirectoryControl */
543*14c39362SHervé Poussineau     UNICODE_STRING SearchPattern;
544*14c39362SHervé Poussineau } VFATCCB, *PVFATCCB;
545*14c39362SHervé Poussineau 
546*14c39362SHervé Poussineau #define TAG_CCB  'CtaF'
547*14c39362SHervé Poussineau #define TAG_FCB  'FtaF'
548*14c39362SHervé Poussineau #define TAG_IRP  'ItaF'
549*14c39362SHervé Poussineau #define TAG_CLOSE 'xtaF'
550*14c39362SHervé Poussineau #define TAG_STATS 'VtaF'
551*14c39362SHervé Poussineau #define TAG_BUFFER 'OtaF'
552*14c39362SHervé Poussineau #define TAG_VPB 'vtaF'
553*14c39362SHervé Poussineau #define TAG_NAME 'ntaF'
554*14c39362SHervé Poussineau #define TAG_SEARCH 'LtaF'
555*14c39362SHervé Poussineau #define TAG_DIRENT 'DtaF'
556*14c39362SHervé Poussineau 
557*14c39362SHervé Poussineau #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
558*14c39362SHervé Poussineau 
559*14c39362SHervé Poussineau typedef struct __DOSTIME
560*14c39362SHervé Poussineau {
561*14c39362SHervé Poussineau     USHORT Second:5;
562*14c39362SHervé Poussineau     USHORT Minute:6;
563*14c39362SHervé Poussineau     USHORT Hour:5;
564*14c39362SHervé Poussineau }
565*14c39362SHervé Poussineau DOSTIME, *PDOSTIME;
566*14c39362SHervé Poussineau 
567*14c39362SHervé Poussineau typedef struct __DOSDATE
568*14c39362SHervé Poussineau {
569*14c39362SHervé Poussineau     USHORT Day:5;
570*14c39362SHervé Poussineau     USHORT Month:4;
571*14c39362SHervé Poussineau     USHORT Year:7;
572*14c39362SHervé Poussineau }
573*14c39362SHervé Poussineau DOSDATE, *PDOSDATE;
574*14c39362SHervé Poussineau 
575*14c39362SHervé Poussineau #define IRPCONTEXT_CANWAIT          0x0001
576*14c39362SHervé Poussineau #define IRPCONTEXT_COMPLETE         0x0002
577*14c39362SHervé Poussineau #define IRPCONTEXT_QUEUE            0x0004
578*14c39362SHervé Poussineau #define IRPCONTEXT_PENDINGRETURNED  0x0008
579*14c39362SHervé Poussineau #define IRPCONTEXT_DEFERRED_WRITE   0x0010
580*14c39362SHervé Poussineau 
581*14c39362SHervé Poussineau typedef struct
582*14c39362SHervé Poussineau {
583*14c39362SHervé Poussineau     PIRP Irp;
584*14c39362SHervé Poussineau     PDEVICE_OBJECT DeviceObject;
585*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt;
586*14c39362SHervé Poussineau     ULONG Flags;
587*14c39362SHervé Poussineau     WORK_QUEUE_ITEM WorkQueueItem;
588*14c39362SHervé Poussineau     PIO_STACK_LOCATION Stack;
589*14c39362SHervé Poussineau     UCHAR MajorFunction;
590*14c39362SHervé Poussineau     UCHAR MinorFunction;
591*14c39362SHervé Poussineau     PFILE_OBJECT FileObject;
592*14c39362SHervé Poussineau     ULONG RefCount;
593*14c39362SHervé Poussineau     KEVENT Event;
594*14c39362SHervé Poussineau     CCHAR PriorityBoost;
595*14c39362SHervé Poussineau } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
596*14c39362SHervé Poussineau 
597*14c39362SHervé Poussineau typedef struct _VFAT_DIRENTRY_CONTEXT
598*14c39362SHervé Poussineau {
599*14c39362SHervé Poussineau     ULONG StartIndex;
600*14c39362SHervé Poussineau     ULONG DirIndex;
601*14c39362SHervé Poussineau     DIR_ENTRY DirEntry;
602*14c39362SHervé Poussineau     UNICODE_STRING LongNameU;
603*14c39362SHervé Poussineau     UNICODE_STRING ShortNameU;
604*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt;
605*14c39362SHervé Poussineau } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
606*14c39362SHervé Poussineau 
607*14c39362SHervé Poussineau typedef struct _VFAT_MOVE_CONTEXT
608*14c39362SHervé Poussineau {
609*14c39362SHervé Poussineau     ULONG FirstCluster;
610*14c39362SHervé Poussineau     ULONG FileSize;
611*14c39362SHervé Poussineau     USHORT CreationDate;
612*14c39362SHervé Poussineau     USHORT CreationTime;
613*14c39362SHervé Poussineau     BOOLEAN InPlace;
614*14c39362SHervé Poussineau } VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
615*14c39362SHervé Poussineau 
616*14c39362SHervé Poussineau typedef struct _VFAT_CLOSE_CONTEXT
617*14c39362SHervé Poussineau {
618*14c39362SHervé Poussineau     PDEVICE_EXTENSION Vcb;
619*14c39362SHervé Poussineau     PVFATFCB Fcb;
620*14c39362SHervé Poussineau     LIST_ENTRY CloseListEntry;
621*14c39362SHervé Poussineau } VFAT_CLOSE_CONTEXT, *PVFAT_CLOSE_CONTEXT;
622*14c39362SHervé Poussineau 
623*14c39362SHervé Poussineau FORCEINLINE
624*14c39362SHervé Poussineau NTSTATUS
VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)625*14c39362SHervé Poussineau VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
626*14c39362SHervé Poussineau {
627*14c39362SHervé Poussineau     PULONG Flags = &IrpContext->Flags;
628*14c39362SHervé Poussineau 
629*14c39362SHervé Poussineau     *Flags &= ~IRPCONTEXT_COMPLETE;
630*14c39362SHervé Poussineau     *Flags |= IRPCONTEXT_QUEUE;
631*14c39362SHervé Poussineau 
632*14c39362SHervé Poussineau     return STATUS_PENDING;
633*14c39362SHervé Poussineau }
634*14c39362SHervé Poussineau 
635*14c39362SHervé Poussineau FORCEINLINE
636*14c39362SHervé Poussineau BOOLEAN
vfatFCBIsDirectory(PVFATFCB FCB)637*14c39362SHervé Poussineau vfatFCBIsDirectory(PVFATFCB FCB)
638*14c39362SHervé Poussineau {
639*14c39362SHervé Poussineau     return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_DIRECTORY);
640*14c39362SHervé Poussineau }
641*14c39362SHervé Poussineau 
642*14c39362SHervé Poussineau FORCEINLINE
643*14c39362SHervé Poussineau BOOLEAN
vfatFCBIsReadOnly(PVFATFCB FCB)644*14c39362SHervé Poussineau vfatFCBIsReadOnly(PVFATFCB FCB)
645*14c39362SHervé Poussineau {
646*14c39362SHervé Poussineau     return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_READONLY);
647*14c39362SHervé Poussineau }
648*14c39362SHervé Poussineau 
649*14c39362SHervé Poussineau FORCEINLINE
650*14c39362SHervé Poussineau BOOLEAN
vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)651*14c39362SHervé Poussineau vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
652*14c39362SHervé Poussineau {
653*14c39362SHervé Poussineau     return BooleanFlagOn(DeviceExt->Flags, VCB_IS_FATX);
654*14c39362SHervé Poussineau }
655*14c39362SHervé Poussineau 
656*14c39362SHervé Poussineau FORCEINLINE
657*14c39362SHervé Poussineau VOID
vfatReportChange(IN PDEVICE_EXTENSION DeviceExt,IN PVFATFCB Fcb,IN ULONG FilterMatch,IN ULONG Action)658*14c39362SHervé Poussineau vfatReportChange(
659*14c39362SHervé Poussineau     IN PDEVICE_EXTENSION DeviceExt,
660*14c39362SHervé Poussineau     IN PVFATFCB Fcb,
661*14c39362SHervé Poussineau     IN ULONG FilterMatch,
662*14c39362SHervé Poussineau     IN ULONG Action)
663*14c39362SHervé Poussineau {
664*14c39362SHervé Poussineau     FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
665*14c39362SHervé Poussineau                                 &(DeviceExt->NotifyList),
666*14c39362SHervé Poussineau                                 (PSTRING)&Fcb->PathNameU,
667*14c39362SHervé Poussineau                                 Fcb->PathNameU.Length - Fcb->LongNameU.Length,
668*14c39362SHervé Poussineau                                 NULL, NULL, FilterMatch, Action, NULL);
669*14c39362SHervé Poussineau }
670*14c39362SHervé Poussineau 
671*14c39362SHervé Poussineau #define vfatAddToStat(Vcb, Stat, Inc)                                                                         \
672*14c39362SHervé Poussineau {                                                                                                             \
673*14c39362SHervé Poussineau     PSTATISTICS Stats = &(Vcb)->Statistics[KeGetCurrentProcessorNumber() % VfatGlobalData->NumberProcessors]; \
674*14c39362SHervé Poussineau     Stats->Stat += Inc;                                                                                       \
675*14c39362SHervé Poussineau }
676*14c39362SHervé Poussineau 
677*14c39362SHervé Poussineau /* blockdev.c */
678*14c39362SHervé Poussineau 
679*14c39362SHervé Poussineau NTSTATUS
680*14c39362SHervé Poussineau VfatReadDisk(
681*14c39362SHervé Poussineau     IN PDEVICE_OBJECT pDeviceObject,
682*14c39362SHervé Poussineau     IN PLARGE_INTEGER ReadOffset,
683*14c39362SHervé Poussineau     IN ULONG ReadLength,
684*14c39362SHervé Poussineau     IN PUCHAR Buffer,
685*14c39362SHervé Poussineau     IN BOOLEAN Override);
686*14c39362SHervé Poussineau 
687*14c39362SHervé Poussineau NTSTATUS
688*14c39362SHervé Poussineau VfatReadDiskPartial(
689*14c39362SHervé Poussineau     IN PVFAT_IRP_CONTEXT IrpContext,
690*14c39362SHervé Poussineau     IN PLARGE_INTEGER ReadOffset,
691*14c39362SHervé Poussineau     IN ULONG ReadLength,
692*14c39362SHervé Poussineau     IN ULONG BufferOffset,
693*14c39362SHervé Poussineau     IN BOOLEAN Wait);
694*14c39362SHervé Poussineau 
695*14c39362SHervé Poussineau NTSTATUS
696*14c39362SHervé Poussineau VfatWriteDisk(
697*14c39362SHervé Poussineau     IN PDEVICE_OBJECT pDeviceObject,
698*14c39362SHervé Poussineau     IN PLARGE_INTEGER WriteOffset,
699*14c39362SHervé Poussineau     IN ULONG WriteLength,
700*14c39362SHervé Poussineau     IN OUT PUCHAR Buffer,
701*14c39362SHervé Poussineau     IN BOOLEAN Override);
702*14c39362SHervé Poussineau 
703*14c39362SHervé Poussineau NTSTATUS
704*14c39362SHervé Poussineau VfatWriteDiskPartial(
705*14c39362SHervé Poussineau     IN PVFAT_IRP_CONTEXT IrpContext,
706*14c39362SHervé Poussineau     IN PLARGE_INTEGER WriteOffset,
707*14c39362SHervé Poussineau     IN ULONG WriteLength,
708*14c39362SHervé Poussineau     IN ULONG BufferOffset,
709*14c39362SHervé Poussineau     IN BOOLEAN Wait);
710*14c39362SHervé Poussineau 
711*14c39362SHervé Poussineau NTSTATUS
712*14c39362SHervé Poussineau VfatBlockDeviceIoControl(
713*14c39362SHervé Poussineau     IN PDEVICE_OBJECT DeviceObject,
714*14c39362SHervé Poussineau     IN ULONG CtlCode,
715*14c39362SHervé Poussineau     IN PVOID InputBuffer,
716*14c39362SHervé Poussineau     IN ULONG InputBufferSize,
717*14c39362SHervé Poussineau     IN OUT PVOID OutputBuffer,
718*14c39362SHervé Poussineau     IN OUT PULONG pOutputBufferSize,
719*14c39362SHervé Poussineau     IN BOOLEAN Override);
720*14c39362SHervé Poussineau 
721*14c39362SHervé Poussineau /* cleanup.c */
722*14c39362SHervé Poussineau 
723*14c39362SHervé Poussineau NTSTATUS
724*14c39362SHervé Poussineau VfatCleanup(
725*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
726*14c39362SHervé Poussineau 
727*14c39362SHervé Poussineau /* close.c */
728*14c39362SHervé Poussineau 
729*14c39362SHervé Poussineau NTSTATUS
730*14c39362SHervé Poussineau VfatClose(
731*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
732*14c39362SHervé Poussineau 
733*14c39362SHervé Poussineau NTSTATUS
734*14c39362SHervé Poussineau VfatCloseFile(
735*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
736*14c39362SHervé Poussineau     PFILE_OBJECT FileObject);
737*14c39362SHervé Poussineau 
738*14c39362SHervé Poussineau /* create.c */
739*14c39362SHervé Poussineau 
740*14c39362SHervé Poussineau NTSTATUS
741*14c39362SHervé Poussineau VfatCreate(
742*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
743*14c39362SHervé Poussineau 
744*14c39362SHervé Poussineau NTSTATUS
745*14c39362SHervé Poussineau FindFile(
746*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
747*14c39362SHervé Poussineau     PVFATFCB Parent,
748*14c39362SHervé Poussineau     PUNICODE_STRING FileToFindU,
749*14c39362SHervé Poussineau     PVFAT_DIRENTRY_CONTEXT DirContext,
750*14c39362SHervé Poussineau     BOOLEAN First);
751*14c39362SHervé Poussineau 
752*14c39362SHervé Poussineau VOID
753*14c39362SHervé Poussineau vfat8Dot3ToString(
754*14c39362SHervé Poussineau     PFAT_DIR_ENTRY pEntry,
755*14c39362SHervé Poussineau     PUNICODE_STRING NameU);
756*14c39362SHervé Poussineau 
757*14c39362SHervé Poussineau /* dir.c */
758*14c39362SHervé Poussineau 
759*14c39362SHervé Poussineau NTSTATUS
760*14c39362SHervé Poussineau VfatDirectoryControl(
761*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
762*14c39362SHervé Poussineau 
763*14c39362SHervé Poussineau BOOLEAN
764*14c39362SHervé Poussineau FsdDosDateTimeToSystemTime(
765*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
766*14c39362SHervé Poussineau     USHORT DosDate,
767*14c39362SHervé Poussineau     USHORT DosTime,
768*14c39362SHervé Poussineau     PLARGE_INTEGER SystemTime);
769*14c39362SHervé Poussineau 
770*14c39362SHervé Poussineau BOOLEAN
771*14c39362SHervé Poussineau FsdSystemTimeToDosDateTime(
772*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
773*14c39362SHervé Poussineau     PLARGE_INTEGER SystemTime,
774*14c39362SHervé Poussineau     USHORT *pDosDate,
775*14c39362SHervé Poussineau     USHORT *pDosTime);
776*14c39362SHervé Poussineau 
777*14c39362SHervé Poussineau /* direntry.c */
778*14c39362SHervé Poussineau 
779*14c39362SHervé Poussineau ULONG
780*14c39362SHervé Poussineau vfatDirEntryGetFirstCluster(
781*14c39362SHervé Poussineau     PDEVICE_EXTENSION pDeviceExt,
782*14c39362SHervé Poussineau     PDIR_ENTRY pDirEntry);
783*14c39362SHervé Poussineau 
784*14c39362SHervé Poussineau /* dirwr.c */
785*14c39362SHervé Poussineau 
786*14c39362SHervé Poussineau NTSTATUS
787*14c39362SHervé Poussineau vfatFCBInitializeCacheFromVolume(
788*14c39362SHervé Poussineau     PVCB vcb,
789*14c39362SHervé Poussineau     PVFATFCB fcb);
790*14c39362SHervé Poussineau 
791*14c39362SHervé Poussineau NTSTATUS
792*14c39362SHervé Poussineau VfatUpdateEntry(
793*14c39362SHervé Poussineau     IN PDEVICE_EXTENSION DeviceExt,
794*14c39362SHervé Poussineau     PVFATFCB pFcb);
795*14c39362SHervé Poussineau 
796*14c39362SHervé Poussineau BOOLEAN
797*14c39362SHervé Poussineau vfatFindDirSpace(
798*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
799*14c39362SHervé Poussineau     PVFATFCB pDirFcb,
800*14c39362SHervé Poussineau     ULONG nbSlots,
801*14c39362SHervé Poussineau     PULONG start);
802*14c39362SHervé Poussineau 
803*14c39362SHervé Poussineau NTSTATUS
804*14c39362SHervé Poussineau vfatRenameEntry(
805*14c39362SHervé Poussineau     IN PDEVICE_EXTENSION DeviceExt,
806*14c39362SHervé Poussineau     IN PVFATFCB pFcb,
807*14c39362SHervé Poussineau     IN PUNICODE_STRING FileName,
808*14c39362SHervé Poussineau     IN BOOLEAN CaseChangeOnly);
809*14c39362SHervé Poussineau 
810*14c39362SHervé Poussineau NTSTATUS
811*14c39362SHervé Poussineau VfatMoveEntry(
812*14c39362SHervé Poussineau     IN PDEVICE_EXTENSION DeviceExt,
813*14c39362SHervé Poussineau     IN PVFATFCB pFcb,
814*14c39362SHervé Poussineau     IN PUNICODE_STRING FileName,
815*14c39362SHervé Poussineau     IN PVFATFCB ParentFcb);
816*14c39362SHervé Poussineau 
817*14c39362SHervé Poussineau /* ea.h */
818*14c39362SHervé Poussineau 
819*14c39362SHervé Poussineau NTSTATUS
820*14c39362SHervé Poussineau VfatSetExtendedAttributes(
821*14c39362SHervé Poussineau     PFILE_OBJECT FileObject,
822*14c39362SHervé Poussineau     PVOID Ea,
823*14c39362SHervé Poussineau     ULONG EaLength);
824*14c39362SHervé Poussineau 
825*14c39362SHervé Poussineau /* fastio.c */
826*14c39362SHervé Poussineau 
827*14c39362SHervé Poussineau CODE_SEG("INIT")
828*14c39362SHervé Poussineau VOID
829*14c39362SHervé Poussineau VfatInitFastIoRoutines(
830*14c39362SHervé Poussineau     PFAST_IO_DISPATCH FastIoDispatch);
831*14c39362SHervé Poussineau 
832*14c39362SHervé Poussineau BOOLEAN
833*14c39362SHervé Poussineau NTAPI
834*14c39362SHervé Poussineau VfatAcquireForLazyWrite(
835*14c39362SHervé Poussineau     IN PVOID Context,
836*14c39362SHervé Poussineau     IN BOOLEAN Wait);
837*14c39362SHervé Poussineau 
838*14c39362SHervé Poussineau VOID
839*14c39362SHervé Poussineau NTAPI
840*14c39362SHervé Poussineau VfatReleaseFromLazyWrite(
841*14c39362SHervé Poussineau     IN PVOID Context);
842*14c39362SHervé Poussineau 
843*14c39362SHervé Poussineau /* fat.c */
844*14c39362SHervé Poussineau 
845*14c39362SHervé Poussineau NTSTATUS
846*14c39362SHervé Poussineau FAT12GetNextCluster(
847*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
848*14c39362SHervé Poussineau     ULONG CurrentCluster,
849*14c39362SHervé Poussineau     PULONG NextCluster);
850*14c39362SHervé Poussineau 
851*14c39362SHervé Poussineau NTSTATUS
852*14c39362SHervé Poussineau FAT12FindAndMarkAvailableCluster(
853*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
854*14c39362SHervé Poussineau     PULONG Cluster);
855*14c39362SHervé Poussineau 
856*14c39362SHervé Poussineau NTSTATUS
857*14c39362SHervé Poussineau FAT12WriteCluster(
858*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
859*14c39362SHervé Poussineau     ULONG ClusterToWrite,
860*14c39362SHervé Poussineau     ULONG NewValue,
861*14c39362SHervé Poussineau     PULONG OldValue);
862*14c39362SHervé Poussineau 
863*14c39362SHervé Poussineau NTSTATUS
864*14c39362SHervé Poussineau FAT16GetNextCluster(
865*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
866*14c39362SHervé Poussineau     ULONG CurrentCluster,
867*14c39362SHervé Poussineau     PULONG NextCluster);
868*14c39362SHervé Poussineau 
869*14c39362SHervé Poussineau NTSTATUS
870*14c39362SHervé Poussineau FAT16FindAndMarkAvailableCluster(
871*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
872*14c39362SHervé Poussineau     PULONG Cluster);
873*14c39362SHervé Poussineau 
874*14c39362SHervé Poussineau NTSTATUS
875*14c39362SHervé Poussineau FAT16WriteCluster(
876*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
877*14c39362SHervé Poussineau     ULONG ClusterToWrite,
878*14c39362SHervé Poussineau     ULONG NewValue,
879*14c39362SHervé Poussineau     PULONG OldValue);
880*14c39362SHervé Poussineau 
881*14c39362SHervé Poussineau NTSTATUS
882*14c39362SHervé Poussineau FAT32GetNextCluster(
883*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
884*14c39362SHervé Poussineau     ULONG CurrentCluster,
885*14c39362SHervé Poussineau     PULONG NextCluster);
886*14c39362SHervé Poussineau 
887*14c39362SHervé Poussineau NTSTATUS
888*14c39362SHervé Poussineau FAT32FindAndMarkAvailableCluster(
889*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
890*14c39362SHervé Poussineau     PULONG Cluster);
891*14c39362SHervé Poussineau 
892*14c39362SHervé Poussineau NTSTATUS
893*14c39362SHervé Poussineau FAT32WriteCluster(
894*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
895*14c39362SHervé Poussineau     ULONG ClusterToWrite,
896*14c39362SHervé Poussineau     ULONG NewValue,
897*14c39362SHervé Poussineau     PULONG OldValue);
898*14c39362SHervé Poussineau 
899*14c39362SHervé Poussineau NTSTATUS
900*14c39362SHervé Poussineau OffsetToCluster(
901*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
902*14c39362SHervé Poussineau     ULONG FirstCluster,
903*14c39362SHervé Poussineau     ULONG FileOffset,
904*14c39362SHervé Poussineau     PULONG Cluster,
905*14c39362SHervé Poussineau     BOOLEAN Extend);
906*14c39362SHervé Poussineau 
907*14c39362SHervé Poussineau ULONGLONG
908*14c39362SHervé Poussineau ClusterToSector(
909*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
910*14c39362SHervé Poussineau     ULONG Cluster);
911*14c39362SHervé Poussineau 
912*14c39362SHervé Poussineau NTSTATUS
913*14c39362SHervé Poussineau GetNextCluster(
914*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
915*14c39362SHervé Poussineau     ULONG CurrentCluster,
916*14c39362SHervé Poussineau     PULONG NextCluster);
917*14c39362SHervé Poussineau 
918*14c39362SHervé Poussineau NTSTATUS
919*14c39362SHervé Poussineau GetNextClusterExtend(
920*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
921*14c39362SHervé Poussineau     ULONG CurrentCluster,
922*14c39362SHervé Poussineau     PULONG NextCluster);
923*14c39362SHervé Poussineau 
924*14c39362SHervé Poussineau NTSTATUS
925*14c39362SHervé Poussineau CountAvailableClusters(
926*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
927*14c39362SHervé Poussineau     PLARGE_INTEGER Clusters);
928*14c39362SHervé Poussineau 
929*14c39362SHervé Poussineau NTSTATUS
930*14c39362SHervé Poussineau WriteCluster(
931*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
932*14c39362SHervé Poussineau     ULONG ClusterToWrite,
933*14c39362SHervé Poussineau     ULONG NewValue);
934*14c39362SHervé Poussineau 
935*14c39362SHervé Poussineau NTSTATUS
936*14c39362SHervé Poussineau GetDirtyStatus(
937*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
938*14c39362SHervé Poussineau     PBOOLEAN DirtyStatus);
939*14c39362SHervé Poussineau 
940*14c39362SHervé Poussineau NTSTATUS
941*14c39362SHervé Poussineau FAT16GetDirtyStatus(
942*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
943*14c39362SHervé Poussineau     PBOOLEAN DirtyStatus);
944*14c39362SHervé Poussineau 
945*14c39362SHervé Poussineau NTSTATUS
946*14c39362SHervé Poussineau FAT32GetDirtyStatus(
947*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
948*14c39362SHervé Poussineau     PBOOLEAN DirtyStatus);
949*14c39362SHervé Poussineau 
950*14c39362SHervé Poussineau NTSTATUS
951*14c39362SHervé Poussineau SetDirtyStatus(
952*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
953*14c39362SHervé Poussineau     BOOLEAN DirtyStatus);
954*14c39362SHervé Poussineau 
955*14c39362SHervé Poussineau NTSTATUS
956*14c39362SHervé Poussineau FAT16SetDirtyStatus(
957*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
958*14c39362SHervé Poussineau     BOOLEAN DirtyStatus);
959*14c39362SHervé Poussineau 
960*14c39362SHervé Poussineau NTSTATUS
961*14c39362SHervé Poussineau FAT32SetDirtyStatus(
962*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
963*14c39362SHervé Poussineau     BOOLEAN DirtyStatus);
964*14c39362SHervé Poussineau 
965*14c39362SHervé Poussineau NTSTATUS
966*14c39362SHervé Poussineau FAT32UpdateFreeClustersCount(
967*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt);
968*14c39362SHervé Poussineau 
969*14c39362SHervé Poussineau /* fcb.c */
970*14c39362SHervé Poussineau 
971*14c39362SHervé Poussineau PVFATFCB
972*14c39362SHervé Poussineau vfatNewFCB(
973*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB,
974*14c39362SHervé Poussineau     PUNICODE_STRING pFileNameU);
975*14c39362SHervé Poussineau 
976*14c39362SHervé Poussineau NTSTATUS
977*14c39362SHervé Poussineau vfatSetFCBNewDirName(
978*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB,
979*14c39362SHervé Poussineau     PVFATFCB Fcb,
980*14c39362SHervé Poussineau     PVFATFCB ParentFcb);
981*14c39362SHervé Poussineau 
982*14c39362SHervé Poussineau NTSTATUS
983*14c39362SHervé Poussineau vfatUpdateFCB(
984*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB,
985*14c39362SHervé Poussineau     PVFATFCB Fcb,
986*14c39362SHervé Poussineau     PVFAT_DIRENTRY_CONTEXT DirContext,
987*14c39362SHervé Poussineau     PVFATFCB ParentFcb);
988*14c39362SHervé Poussineau 
989*14c39362SHervé Poussineau VOID
990*14c39362SHervé Poussineau vfatDestroyFCB(
991*14c39362SHervé Poussineau     PVFATFCB pFCB);
992*14c39362SHervé Poussineau 
993*14c39362SHervé Poussineau VOID
994*14c39362SHervé Poussineau vfatDestroyCCB(
995*14c39362SHervé Poussineau     PVFATCCB pCcb);
996*14c39362SHervé Poussineau 
997*14c39362SHervé Poussineau VOID
998*14c39362SHervé Poussineau #ifndef KDBG
999*14c39362SHervé Poussineau vfatGrabFCB(
1000*14c39362SHervé Poussineau #else
1001*14c39362SHervé Poussineau _vfatGrabFCB(
1002*14c39362SHervé Poussineau #endif
1003*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB,
1004*14c39362SHervé Poussineau     PVFATFCB pFCB
1005*14c39362SHervé Poussineau #ifdef KDBG
1006*14c39362SHervé Poussineau     ,
1007*14c39362SHervé Poussineau     PCSTR File,
1008*14c39362SHervé Poussineau     ULONG Line,
1009*14c39362SHervé Poussineau     PCSTR Func
1010*14c39362SHervé Poussineau #endif
1011*14c39362SHervé Poussineau     );
1012*14c39362SHervé Poussineau 
1013*14c39362SHervé Poussineau VOID
1014*14c39362SHervé Poussineau #ifndef KDBG
1015*14c39362SHervé Poussineau vfatReleaseFCB(
1016*14c39362SHervé Poussineau #else
1017*14c39362SHervé Poussineau _vfatReleaseFCB(
1018*14c39362SHervé Poussineau #endif
1019*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB,
1020*14c39362SHervé Poussineau     PVFATFCB pFCB
1021*14c39362SHervé Poussineau #ifdef KDBG
1022*14c39362SHervé Poussineau     ,
1023*14c39362SHervé Poussineau     PCSTR File,
1024*14c39362SHervé Poussineau     ULONG Line,
1025*14c39362SHervé Poussineau     PCSTR Func
1026*14c39362SHervé Poussineau #endif
1027*14c39362SHervé Poussineau     );
1028*14c39362SHervé Poussineau 
1029*14c39362SHervé Poussineau #ifdef KDBG
1030*14c39362SHervé Poussineau #define vfatGrabFCB(v, f) _vfatGrabFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
1031*14c39362SHervé Poussineau #define vfatReleaseFCB(v, f) _vfatReleaseFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
1032*14c39362SHervé Poussineau #endif
1033*14c39362SHervé Poussineau 
1034*14c39362SHervé Poussineau PVFATFCB
1035*14c39362SHervé Poussineau vfatGrabFCBFromTable(
1036*14c39362SHervé Poussineau     PDEVICE_EXTENSION pDeviceExt,
1037*14c39362SHervé Poussineau     PUNICODE_STRING pFileNameU);
1038*14c39362SHervé Poussineau 
1039*14c39362SHervé Poussineau PVFATFCB
1040*14c39362SHervé Poussineau vfatMakeRootFCB(
1041*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB);
1042*14c39362SHervé Poussineau 
1043*14c39362SHervé Poussineau PVFATFCB
1044*14c39362SHervé Poussineau vfatOpenRootFCB(
1045*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB);
1046*14c39362SHervé Poussineau 
1047*14c39362SHervé Poussineau BOOLEAN
1048*14c39362SHervé Poussineau vfatFCBIsDirectory(
1049*14c39362SHervé Poussineau     PVFATFCB FCB);
1050*14c39362SHervé Poussineau 
1051*14c39362SHervé Poussineau BOOLEAN
1052*14c39362SHervé Poussineau vfatFCBIsRoot(
1053*14c39362SHervé Poussineau     PVFATFCB FCB);
1054*14c39362SHervé Poussineau 
1055*14c39362SHervé Poussineau NTSTATUS
1056*14c39362SHervé Poussineau vfatAttachFCBToFileObject(
1057*14c39362SHervé Poussineau     PDEVICE_EXTENSION vcb,
1058*14c39362SHervé Poussineau     PVFATFCB fcb,
1059*14c39362SHervé Poussineau     PFILE_OBJECT fileObject);
1060*14c39362SHervé Poussineau 
1061*14c39362SHervé Poussineau NTSTATUS
1062*14c39362SHervé Poussineau vfatDirFindFile(
1063*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB,
1064*14c39362SHervé Poussineau     PVFATFCB parentFCB,
1065*14c39362SHervé Poussineau     PUNICODE_STRING FileToFindU,
1066*14c39362SHervé Poussineau     PVFATFCB *fileFCB);
1067*14c39362SHervé Poussineau 
1068*14c39362SHervé Poussineau NTSTATUS
1069*14c39362SHervé Poussineau vfatGetFCBForFile(
1070*14c39362SHervé Poussineau     PDEVICE_EXTENSION pVCB,
1071*14c39362SHervé Poussineau     PVFATFCB *pParentFCB,
1072*14c39362SHervé Poussineau     PVFATFCB *pFCB,
1073*14c39362SHervé Poussineau     PUNICODE_STRING pFileNameU);
1074*14c39362SHervé Poussineau 
1075*14c39362SHervé Poussineau NTSTATUS
1076*14c39362SHervé Poussineau vfatMakeFCBFromDirEntry(
1077*14c39362SHervé Poussineau     PVCB vcb,
1078*14c39362SHervé Poussineau     PVFATFCB directoryFCB,
1079*14c39362SHervé Poussineau     PVFAT_DIRENTRY_CONTEXT DirContext,
1080*14c39362SHervé Poussineau     PVFATFCB *fileFCB);
1081*14c39362SHervé Poussineau 
1082*14c39362SHervé Poussineau /* finfo.c */
1083*14c39362SHervé Poussineau 
1084*14c39362SHervé Poussineau NTSTATUS
1085*14c39362SHervé Poussineau VfatGetStandardInformation(
1086*14c39362SHervé Poussineau     PVFATFCB FCB,
1087*14c39362SHervé Poussineau     PFILE_STANDARD_INFORMATION StandardInfo,
1088*14c39362SHervé Poussineau     PULONG BufferLength);
1089*14c39362SHervé Poussineau 
1090*14c39362SHervé Poussineau NTSTATUS
1091*14c39362SHervé Poussineau VfatGetBasicInformation(
1092*14c39362SHervé Poussineau     PFILE_OBJECT FileObject,
1093*14c39362SHervé Poussineau     PVFATFCB FCB,
1094*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
1095*14c39362SHervé Poussineau     PFILE_BASIC_INFORMATION BasicInfo,
1096*14c39362SHervé Poussineau     PULONG BufferLength);
1097*14c39362SHervé Poussineau 
1098*14c39362SHervé Poussineau NTSTATUS
1099*14c39362SHervé Poussineau VfatQueryInformation(
1100*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
1101*14c39362SHervé Poussineau 
1102*14c39362SHervé Poussineau NTSTATUS
1103*14c39362SHervé Poussineau VfatSetInformation(
1104*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
1105*14c39362SHervé Poussineau 
1106*14c39362SHervé Poussineau NTSTATUS
1107*14c39362SHervé Poussineau VfatSetAllocationSizeInformation(
1108*14c39362SHervé Poussineau     PFILE_OBJECT FileObject,
1109*14c39362SHervé Poussineau     PVFATFCB Fcb,
1110*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
1111*14c39362SHervé Poussineau     PLARGE_INTEGER AllocationSize);
1112*14c39362SHervé Poussineau 
1113*14c39362SHervé Poussineau /* flush.c */
1114*14c39362SHervé Poussineau 
1115*14c39362SHervé Poussineau NTSTATUS
1116*14c39362SHervé Poussineau VfatFlush(
1117*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
1118*14c39362SHervé Poussineau 
1119*14c39362SHervé Poussineau NTSTATUS
1120*14c39362SHervé Poussineau VfatFlushVolume(
1121*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
1122*14c39362SHervé Poussineau     PVFATFCB VolumeFcb);
1123*14c39362SHervé Poussineau 
1124*14c39362SHervé Poussineau /* fsctl.c */
1125*14c39362SHervé Poussineau 
1126*14c39362SHervé Poussineau NTSTATUS
1127*14c39362SHervé Poussineau VfatFileSystemControl(
1128*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
1129*14c39362SHervé Poussineau 
1130*14c39362SHervé Poussineau /* iface.c */
1131*14c39362SHervé Poussineau 
1132*14c39362SHervé Poussineau CODE_SEG("INIT")
1133*14c39362SHervé Poussineau NTSTATUS
1134*14c39362SHervé Poussineau NTAPI
1135*14c39362SHervé Poussineau DriverEntry(
1136*14c39362SHervé Poussineau     PDRIVER_OBJECT DriverObject,
1137*14c39362SHervé Poussineau     PUNICODE_STRING RegistryPath);
1138*14c39362SHervé Poussineau 
1139*14c39362SHervé Poussineau #ifdef KDBG
1140*14c39362SHervé Poussineau /* kdbg.c */
1141*14c39362SHervé Poussineau KDBG_CLI_ROUTINE vfatKdbgHandler;
1142*14c39362SHervé Poussineau #endif
1143*14c39362SHervé Poussineau 
1144*14c39362SHervé Poussineau /* misc.c */
1145*14c39362SHervé Poussineau 
1146*14c39362SHervé Poussineau DRIVER_DISPATCH
1147*14c39362SHervé Poussineau VfatBuildRequest;
1148*14c39362SHervé Poussineau 
1149*14c39362SHervé Poussineau NTSTATUS
1150*14c39362SHervé Poussineau NTAPI
1151*14c39362SHervé Poussineau VfatBuildRequest(
1152*14c39362SHervé Poussineau     PDEVICE_OBJECT DeviceObject,
1153*14c39362SHervé Poussineau     PIRP Irp);
1154*14c39362SHervé Poussineau 
1155*14c39362SHervé Poussineau PVOID
1156*14c39362SHervé Poussineau VfatGetUserBuffer(
1157*14c39362SHervé Poussineau     IN PIRP Irp,
1158*14c39362SHervé Poussineau     IN BOOLEAN Paging);
1159*14c39362SHervé Poussineau 
1160*14c39362SHervé Poussineau NTSTATUS
1161*14c39362SHervé Poussineau VfatLockUserBuffer(
1162*14c39362SHervé Poussineau     IN PIRP Irp,
1163*14c39362SHervé Poussineau     IN ULONG Length,
1164*14c39362SHervé Poussineau     IN LOCK_OPERATION Operation);
1165*14c39362SHervé Poussineau 
1166*14c39362SHervé Poussineau BOOLEAN
1167*14c39362SHervé Poussineau VfatCheckForDismount(
1168*14c39362SHervé Poussineau     IN PDEVICE_EXTENSION DeviceExt,
1169*14c39362SHervé Poussineau     IN BOOLEAN Create);
1170*14c39362SHervé Poussineau 
1171*14c39362SHervé Poussineau VOID
1172*14c39362SHervé Poussineau vfatReportChange(
1173*14c39362SHervé Poussineau     IN PDEVICE_EXTENSION DeviceExt,
1174*14c39362SHervé Poussineau     IN PVFATFCB Fcb,
1175*14c39362SHervé Poussineau     IN ULONG FilterMatch,
1176*14c39362SHervé Poussineau     IN ULONG Action);
1177*14c39362SHervé Poussineau 
1178*14c39362SHervé Poussineau VOID
1179*14c39362SHervé Poussineau NTAPI
1180*14c39362SHervé Poussineau VfatHandleDeferredWrite(
1181*14c39362SHervé Poussineau     IN PVOID IrpContext,
1182*14c39362SHervé Poussineau     IN PVOID Unused);
1183*14c39362SHervé Poussineau 
1184*14c39362SHervé Poussineau /* pnp.c */
1185*14c39362SHervé Poussineau 
1186*14c39362SHervé Poussineau NTSTATUS
1187*14c39362SHervé Poussineau VfatPnp(
1188*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
1189*14c39362SHervé Poussineau 
1190*14c39362SHervé Poussineau /* rw.c */
1191*14c39362SHervé Poussineau 
1192*14c39362SHervé Poussineau NTSTATUS
1193*14c39362SHervé Poussineau VfatRead(
1194*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
1195*14c39362SHervé Poussineau 
1196*14c39362SHervé Poussineau NTSTATUS
1197*14c39362SHervé Poussineau VfatWrite(
1198*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT *pIrpContext);
1199*14c39362SHervé Poussineau 
1200*14c39362SHervé Poussineau NTSTATUS
1201*14c39362SHervé Poussineau NextCluster(
1202*14c39362SHervé Poussineau     PDEVICE_EXTENSION DeviceExt,
1203*14c39362SHervé Poussineau     ULONG FirstCluster,
1204*14c39362SHervé Poussineau     PULONG CurrentCluster,
1205*14c39362SHervé Poussineau     BOOLEAN Extend);
1206*14c39362SHervé Poussineau 
1207*14c39362SHervé Poussineau /* shutdown.c */
1208*14c39362SHervé Poussineau 
1209*14c39362SHervé Poussineau DRIVER_DISPATCH
1210*14c39362SHervé Poussineau VfatShutdown;
1211*14c39362SHervé Poussineau 
1212*14c39362SHervé Poussineau NTSTATUS
1213*14c39362SHervé Poussineau NTAPI
1214*14c39362SHervé Poussineau VfatShutdown(
1215*14c39362SHervé Poussineau     PDEVICE_OBJECT DeviceObject,
1216*14c39362SHervé Poussineau     PIRP Irp);
1217*14c39362SHervé Poussineau 
1218*14c39362SHervé Poussineau /* string.c */
1219*14c39362SHervé Poussineau 
1220*14c39362SHervé Poussineau VOID
1221*14c39362SHervé Poussineau vfatSplitPathName(
1222*14c39362SHervé Poussineau     PUNICODE_STRING PathNameU,
1223*14c39362SHervé Poussineau     PUNICODE_STRING DirNameU,
1224*14c39362SHervé Poussineau     PUNICODE_STRING FileNameU);
1225*14c39362SHervé Poussineau 
1226*14c39362SHervé Poussineau BOOLEAN
1227*14c39362SHervé Poussineau vfatIsLongIllegal(
1228*14c39362SHervé Poussineau     WCHAR c);
1229*14c39362SHervé Poussineau 
1230*14c39362SHervé Poussineau BOOLEAN
1231*14c39362SHervé Poussineau IsDotOrDotDot(
1232*14c39362SHervé Poussineau     PCUNICODE_STRING Name);
1233*14c39362SHervé Poussineau 
1234*14c39362SHervé Poussineau /* volume.c */
1235*14c39362SHervé Poussineau 
1236*14c39362SHervé Poussineau NTSTATUS
1237*14c39362SHervé Poussineau VfatQueryVolumeInformation(
1238*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
1239*14c39362SHervé Poussineau 
1240*14c39362SHervé Poussineau NTSTATUS
1241*14c39362SHervé Poussineau VfatSetVolumeInformation(
1242*14c39362SHervé Poussineau     PVFAT_IRP_CONTEXT IrpContext);
1243*14c39362SHervé Poussineau 
1244*14c39362SHervé Poussineau #endif /* _VFATFS_PCH_ */
1245