Fixed handling of large FAT32 partitions.
[reactos.git] / reactos / drivers / fs / vfat / vfat.h
1 /* $Id: vfat.h,v 1.50 2003/01/04 02:07:18 hbirr Exp $ */
2
3 #include <ddk/ntifs.h>
4
5 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
6 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
7
8 struct _BootSector
9 {
10 unsigned char magic0, res0, magic1;
11 unsigned char OEMName[8];
12 unsigned short BytesPerSector;
13 unsigned char SectorsPerCluster;
14 unsigned short ReservedSectors;
15 unsigned char FATCount;
16 unsigned short RootEntries, Sectors;
17 unsigned char Media;
18 unsigned short FATSectors, SectorsPerTrack, Heads;
19 unsigned long HiddenSectors, SectorsHuge;
20 unsigned char Drive, Res1, Sig;
21 unsigned long VolumeID;
22 unsigned char VolumeLabel[11], SysType[8];
23 unsigned char Res2[446];
24 unsigned long Signatur1;
25 } __attribute__((packed));
26
27 struct _BootSector32
28 {
29 unsigned char magic0, res0, magic1; // 0
30 unsigned char OEMName[8]; // 3
31 unsigned short BytesPerSector; // 11
32 unsigned char SectorsPerCluster; // 13
33 unsigned short ReservedSectors; // 14
34 unsigned char FATCount; // 16
35 unsigned short RootEntries, Sectors; // 17
36 unsigned char Media; // 21
37 unsigned short FATSectors, SectorsPerTrack, Heads; // 22
38 unsigned long HiddenSectors, SectorsHuge; // 28
39 unsigned long FATSectors32; // 36
40 unsigned short ExtFlag; // 40
41 unsigned short FSVersion; // 42
42 unsigned long RootCluster; // 44
43 unsigned short FSInfoSector; // 48
44 unsigned long BootBackup; // 50
45 unsigned char Res3[10]; // 54
46 unsigned char Drive; // 64
47 unsigned char Res4; // 65
48 unsigned char ExtBootSignature; // 66
49 unsigned long VolumeID; // 67
50 unsigned char VolumeLabel[11], SysType[8]; // 71
51 unsigned char Res2[418]; // 90
52 unsigned long Signature1; // 508
53 } __attribute__((packed));
54
55 struct _BootBackupSector
56 {
57 unsigned long ExtBootSignature2; // 0
58 unsigned char Res6[480]; // 4
59 unsigned long FSINFOSignature; // 484
60 unsigned long FreeCluster; // 488
61 unsigned long NextCluster; // 492
62 unsigned char Res7[12]; // 496
63 unsigned long Signatur2; // 508
64 } __attribute__((packed));
65
66 typedef struct _BootSector BootSector;
67
68 #define VFAT_CASE_LOWER_BASE 8 // base is lower case
69 #define VFAT_CASE_LOWER_EXT 16 // extension is lower case
70
71 struct _FATDirEntry
72 {
73 unsigned char Filename[8], Ext[3];
74 unsigned char Attrib;
75 unsigned char lCase;
76 unsigned char CreationTimeMs;
77 unsigned short CreationTime,CreationDate,AccessDate;
78 unsigned short FirstClusterHigh; // higher
79 unsigned short UpdateTime; //time create/update
80 unsigned short UpdateDate; //date create/update
81 unsigned short FirstCluster;
82 unsigned long FileSize;
83 } __attribute__((packed));
84
85 typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
86
87 struct _slot
88 {
89 unsigned char id; // sequence number for slot
90 WCHAR name0_4[5]; // first 5 characters in name
91 unsigned char attr; // attribute byte
92 unsigned char reserved; // always 0
93 unsigned char alias_checksum; // checksum for 8.3 alias
94 WCHAR name5_10[6]; // 6 more characters in name
95 unsigned char start[2]; // starting cluster number
96 WCHAR name11_12[2]; // last 2 characters in name
97 } __attribute__((packed));
98
99
100 typedef struct _slot slot;
101
102 #define BLOCKSIZE 512
103
104 #define FAT16 (1)
105 #define FAT12 (2)
106 #define FAT32 (3)
107
108 #define VCB_VOLUME_LOCKED 0x0001
109 #define VCB_DISMOUNT_PENDING 0x0002
110
111 typedef struct
112 {
113 ULONG VolumeID;
114 ULONG FATStart;
115 ULONG FATCount;
116 ULONG FATSectors;
117 ULONG rootDirectorySectors;
118 ULONG rootStart;
119 ULONG dataStart;
120 ULONG RootCluster;
121 ULONG SectorsPerCluster;
122 ULONG BytesPerSector;
123 ULONG BytesPerCluster;
124 ULONG NumberOfClusters;
125 ULONG FatType;
126 ULONG Sectors;
127 } FATINFO, *PFATINFO;
128
129 struct _VFATFCB;
130
131 typedef struct _HASHENTRY
132 {
133 ULONG Hash;
134 struct _VFATFCB* self;
135 struct _HASHENTRY* next;
136 }
137 HASHENTRY;
138
139 #define FCB_HASH_TABLE_SIZE 1024
140
141 typedef struct
142 {
143 ERESOURCE DirResource;
144 ERESOURCE FatResource;
145
146 KSPIN_LOCK FcbListLock;
147 LIST_ENTRY FcbListHead;
148
149 PDEVICE_OBJECT StorageDevice;
150 PFILE_OBJECT FATFileObject;
151 FATINFO FatInfo;
152 ULONG LastAvailableCluster;
153 ULONG AvailableClusters;
154 BOOLEAN AvailableClustersValid;
155 ULONG Flags;
156 struct _VFATFCB * VolumeFcb;
157 struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
158 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
159
160 typedef struct
161 {
162 PDRIVER_OBJECT DriverObject;
163 PDEVICE_OBJECT DeviceObject;
164 ULONG Flags;
165 NPAGED_LOOKASIDE_LIST FcbLookasideList;
166 NPAGED_LOOKASIDE_LIST CcbLookasideList;
167 NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
168 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
169
170 extern PVFAT_GLOBAL_DATA VfatGlobalData;
171
172 #define FCB_CACHE_INITIALIZED 0x0001
173 #define FCB_DELETE_PENDING 0x0002
174 #define FCB_IS_FAT 0x0004
175 #define FCB_IS_PAGE_FILE 0x0008
176 #define FCB_IS_VOLUME 0x0010
177 #define FCB_UPDATE_DIRENTRY 0x0020
178
179 typedef struct _VFATFCB
180 {
181 REACTOS_COMMON_FCB_HEADER RFCB;
182 SECTION_OBJECT_POINTERS SectionObjectPointers;
183 FATDirEntry entry;
184 /* point on filename (250 chars max) in PathName */
185 WCHAR *ObjectName;
186 /* path+filename 260 max */
187 WCHAR PathName[MAX_PATH];
188 WCHAR ShortName[14];
189 LONG RefCount;
190 PDEVICE_EXTENSION pDevExt;
191 LIST_ENTRY FcbListEntry;
192 struct _VFATFCB* parentFcb;
193 ULONG Flags;
194 PFILE_OBJECT FileObject;
195 ULONG dirIndex;
196 ULONG startIndex;
197 ERESOURCE PagingIoResource;
198 ERESOURCE MainResource;
199 ULONG TimerCount;
200 SHARE_ACCESS FCBShareAccess;
201 HASHENTRY Hash;
202 HASHENTRY ShortHash;
203
204 /* Structure members used only for paging files. */
205 ULONG FatChainSize;
206 PULONG FatChain;
207 } VFATFCB, *PVFATFCB;
208
209 typedef struct _VFATCCB
210 {
211 VFATFCB * pFcb;
212 LIST_ENTRY NextCCB;
213 PFILE_OBJECT PtrFileObject;
214 LARGE_INTEGER CurrentByteOffset;
215 /* for DirectoryControl */
216 ULONG Entry;
217 /* for DirectoryControl */
218 PWCHAR DirectorySearchPattern;
219 ULONG LastCluster;
220 ULONG LastOffset;
221
222 } VFATCCB, *PVFATCCB;
223
224 #ifndef TAG
225 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
226 #endif
227
228 #define TAG_CCB TAG('V', 'C', 'C', 'B')
229 #define TAG_FCB TAG('V', 'F', 'C', 'B')
230 #define TAG_IRP TAG('V', 'I', 'R', 'P')
231
232 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
233
234 typedef struct __DOSTIME
235 {
236 WORD Second:5;
237 WORD Minute:6;
238 WORD Hour:5;
239 }
240 DOSTIME, *PDOSTIME;
241
242 typedef struct __DOSDATE
243 {
244 WORD Day:5;
245 WORD Month:4;
246 WORD Year:5;
247 }
248 DOSDATE, *PDOSDATE;
249
250 #define IRPCONTEXT_CANWAIT 0x0001
251
252 typedef struct
253 {
254 PIRP Irp;
255 PDEVICE_OBJECT DeviceObject;
256 PDEVICE_EXTENSION DeviceExt;
257 ULONG Flags;
258 WORK_QUEUE_ITEM WorkQueueItem;
259 PIO_STACK_LOCATION Stack;
260 UCHAR MajorFunction;
261 UCHAR MinorFunction;
262 PFILE_OBJECT FileObject;
263 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
264
265 /* ------------------------------------------------------ shutdown.c */
266
267 NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
268 PIRP Irp);
269
270 /* -------------------------------------------------------- volume.c */
271
272 NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
273
274 NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
275
276 /* ------------------------------------------------------ blockdev.c */
277
278 NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject,
279 IN PLARGE_INTEGER ReadOffset,
280 IN ULONG ReadLength,
281 IN PUCHAR Buffer);
282
283 NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject,
284 IN PLARGE_INTEGER WriteOffset,
285 IN ULONG WriteLength,
286 IN PUCHAR Buffer);
287
288 NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
289 IN ULONG CtlCode,
290 IN PVOID InputBuffer,
291 IN ULONG InputBufferSize,
292 IN OUT PVOID OutputBuffer,
293 IN OUT PULONG pOutputBufferSize);
294
295 /* ----------------------------------------------------------- dir.c */
296
297 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
298
299 BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
300 WORD wDosTime,
301 TIME *FileTime);
302
303 BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
304 WORD *pwDosDate,
305 WORD *pwDosTime);
306
307 /* -------------------------------------------------------- create.c */
308
309 NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
310
311 NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
312 PFILE_OBJECT FileObject,
313 PWSTR FileName);
314
315 NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
316 PVFATFCB Fcb,
317 PVFATFCB Parent,
318 PWSTR FileToFind,
319 PULONG pDirIndex,
320 PULONG pDirIndex2);
321
322 VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry,
323 PWSTR pName);
324
325 NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
326 PVPB Vpb);
327
328 BOOLEAN IsDeletedEntry (PVOID Block,
329 ULONG Offset);
330
331 BOOLEAN IsLastEntry (PVOID Block,
332 ULONG Offset);
333
334 /* --------------------------------------------------------- close.c */
335
336 NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
337
338 NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
339 PFILE_OBJECT FileObject);
340
341 /* ------------------------------------------------------- cleanup.c */
342
343 NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
344
345 /* --------------------------------------------------------- fsctl.c */
346
347 NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
348
349 /* --------------------------------------------------------- finfo.c */
350
351 NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
352
353 NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
354
355 NTSTATUS
356 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
357 PVFATFCB Fcb,
358 PDEVICE_EXTENSION DeviceExt,
359 PLARGE_INTEGER AllocationSize);
360
361 /* --------------------------------------------------------- iface.c */
362
363 NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
364 PUNICODE_STRING RegistryPath);
365
366 /* --------------------------------------------------------- dirwr.c */
367
368 NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
369 PFILE_OBJECT pFileObject,
370 ULONG RequestedOptions,UCHAR ReqAttr);
371
372 NTSTATUS VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt,
373 PFILE_OBJECT pFileObject);
374
375 NTSTATUS delEntry(PDEVICE_EXTENSION,
376 PFILE_OBJECT);
377
378 /* -------------------------------------------------------- string.c */
379
380 BOOLEAN wstrcmpjoki (PWSTR s1,
381 PWSTR s2);
382
383 PWCHAR vfatGetNextPathElement (PWCHAR pFileName);
384
385 VOID vfatWSubString (PWCHAR pTarget,
386 const PWCHAR pSource,
387 size_t pLength);
388
389 BOOL vfatIsFileNameValid (PWCHAR pFileName);
390
391 /* ----------------------------------------------------------- fat.c */
392
393 NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
394 PVFATFCB Fcb,
395 ULONG FirstCluster,
396 ULONG FileOffset,
397 PULONG Cluster,
398 BOOLEAN Extend);
399
400 ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
401 ULONG Cluster);
402
403 NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
404 ULONG CurrentCluster,
405 PULONG NextCluster,
406 BOOLEAN Extend);
407
408 NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
409 PLARGE_INTEGER Clusters);
410
411 /* ------------------------------------------------------ direntry.c */
412
413 ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
414 PFAT_DIR_ENTRY pDirEntry);
415
416 BOOL vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
417
418 BOOL vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
419
420 BOOL vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
421
422 VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
423 PWSTR pEntryName);
424
425 NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
426 PVOID * pPage,
427 IN PVFATFCB pDirFcb,
428 IN OUT PULONG pDirIndex,
429 OUT PWSTR pFileName,
430 OUT PFAT_DIR_ENTRY pDirEntry,
431 OUT PULONG pStartIndex);
432
433 /* ----------------------------------------------------------- fcb.c */
434
435 PVFATFCB vfatNewFCB (PWCHAR pFileName);
436
437 VOID vfatDestroyFCB (PVFATFCB pFCB);
438
439 VOID vfatGrabFCB (PDEVICE_EXTENSION pVCB,
440 PVFATFCB pFCB);
441
442 VOID vfatReleaseFCB (PDEVICE_EXTENSION pVCB,
443 PVFATFCB pFCB);
444
445 VOID vfatAddFCBToTable (PDEVICE_EXTENSION pVCB,
446 PVFATFCB pFCB);
447
448 PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt,
449 PWSTR pFileName);
450
451 PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
452
453 PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
454
455 BOOL vfatFCBIsDirectory (PVFATFCB FCB);
456
457 NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
458 PVFATFCB fcb,
459 PFILE_OBJECT fileObject);
460
461 NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB,
462 PVFATFCB parentFCB,
463 PWSTR elementName,
464 PVFATFCB * fileFCB);
465
466 NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
467 PVFATFCB *pParentFCB,
468 PVFATFCB *pFCB,
469 const PWSTR pFileName);
470
471 NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb,
472 PVFATFCB directoryFCB,
473 PWSTR longName,
474 PFAT_DIR_ENTRY dirEntry,
475 ULONG startIndex,
476 ULONG dirIndex,
477 PVFATFCB * fileFCB);
478
479 /* ------------------------------------------------------------ rw.c */
480
481 NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
482
483 NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
484
485 NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
486 PVFATFCB Fcb,
487 ULONG FirstCluster,
488 PULONG CurrentCluster,
489 BOOLEAN Extend);
490
491 /* ----------------------------------------------------------- misc.c */
492
493 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
494
495 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
496 PIRP Irp);
497
498 VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
499
500 NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
501 PIRP Irp);
502
503 PVOID VfatGetUserBuffer(IN PIRP);
504
505 NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
506 IN LOCK_OPERATION);
507
508 NTSTATUS
509 VfatSetExtendedAttributes(PFILE_OBJECT FileObject,
510 PVOID Ea,
511 ULONG EaLength);
512 /* EOF */