- Improved removable media support.
[reactos.git] / reactos / drivers / fs / vfat / vfat.h
1 /* $Id: vfat.h,v 1.64 2004/06/23 20:23:59 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[448];
24 unsigned short 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 short BootBackup; // 50
45 unsigned char Res3[12]; // 52
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[420]; // 90
52 unsigned short Signature1; // 510
53 } __attribute__((packed));
54
55 struct _FsInfoSector
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 #define ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5)
72 #define ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0)
73 #define ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f)
74 #define ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
75
76 struct _FATDirEntry
77 {
78 unsigned char Filename[8], Ext[3];
79 unsigned char Attrib;
80 unsigned char lCase;
81 unsigned char CreationTimeMs;
82 unsigned short CreationTime,CreationDate,AccessDate;
83 unsigned short FirstClusterHigh; // higher
84 unsigned short UpdateTime; //time create/update
85 unsigned short UpdateDate; //date create/update
86 unsigned short FirstCluster;
87 unsigned long FileSize;
88 } __attribute__((packed));
89
90 typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
91
92 struct _slot
93 {
94 unsigned char id; // sequence number for slot
95 WCHAR name0_4[5]; // first 5 characters in name
96 unsigned char attr; // attribute byte
97 unsigned char reserved; // always 0
98 unsigned char alias_checksum; // checksum for 8.3 alias
99 WCHAR name5_10[6]; // 6 more characters in name
100 unsigned char start[2]; // starting cluster number
101 WCHAR name11_12[2]; // last 2 characters in name
102 } __attribute__((packed));
103
104
105 typedef struct _slot slot;
106
107 #define BLOCKSIZE 512
108
109 #define FAT16 (1)
110 #define FAT12 (2)
111 #define FAT32 (3)
112
113 #define VCB_VOLUME_LOCKED 0x0001
114 #define VCB_DISMOUNT_PENDING 0x0002
115
116 typedef struct
117 {
118 ULONG VolumeID;
119 ULONG FATStart;
120 ULONG FATCount;
121 ULONG FATSectors;
122 ULONG rootDirectorySectors;
123 ULONG rootStart;
124 ULONG dataStart;
125 ULONG RootCluster;
126 ULONG SectorsPerCluster;
127 ULONG BytesPerSector;
128 ULONG BytesPerCluster;
129 ULONG NumberOfClusters;
130 ULONG FatType;
131 ULONG Sectors;
132 BOOL FixedMedia;
133 } FATINFO, *PFATINFO;
134
135 struct _VFATFCB;
136
137 typedef struct _HASHENTRY
138 {
139 ULONG Hash;
140 struct _VFATFCB* self;
141 struct _HASHENTRY* next;
142 }
143 HASHENTRY;
144
145 #define FCB_HASH_TABLE_SIZE 1024
146
147 typedef struct
148 {
149 ERESOURCE DirResource;
150 ERESOURCE FatResource;
151
152 KSPIN_LOCK FcbListLock;
153 LIST_ENTRY FcbListHead;
154 struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
155
156 PDEVICE_OBJECT StorageDevice;
157 PFILE_OBJECT FATFileObject;
158 FATINFO FatInfo;
159 ULONG LastAvailableCluster;
160 ULONG AvailableClusters;
161 BOOLEAN AvailableClustersValid;
162 ULONG Flags;
163 struct _VFATFCB * VolumeFcb;
164
165 LIST_ENTRY VolumeListEntry;
166
167 ULONG MediaChangeCount;
168
169 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
170
171 typedef struct
172 {
173 PDRIVER_OBJECT DriverObject;
174 PDEVICE_OBJECT DeviceObject;
175 ULONG Flags;
176 ERESOURCE VolumeListLock;
177 LIST_ENTRY VolumeListHead;
178 NPAGED_LOOKASIDE_LIST FcbLookasideList;
179 NPAGED_LOOKASIDE_LIST CcbLookasideList;
180 NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
181 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
182
183 extern PVFAT_GLOBAL_DATA VfatGlobalData;
184
185 #define FCB_CACHE_INITIALIZED 0x0001
186 #define FCB_DELETE_PENDING 0x0002
187 #define FCB_IS_FAT 0x0004
188 #define FCB_IS_PAGE_FILE 0x0008
189 #define FCB_IS_VOLUME 0x0010
190 #define FCB_IS_DIRTY 0x0020
191
192 typedef struct _VFATFCB
193 {
194 /* FCB header required by ROS/NT */
195 FSRTL_COMMON_FCB_HEADER RFCB;
196 SECTION_OBJECT_POINTERS SectionObjectPointers;
197 ERESOURCE MainResource;
198 ERESOURCE PagingIoResource;
199 /* end FCB header required by ROS/NT */
200
201 /* directory entry for this file or directory */
202 FATDirEntry entry;
203
204 /* long file name, points into PathNameBuffer */
205 UNICODE_STRING LongNameU;
206
207 /* short file name */
208 UNICODE_STRING ShortNameU;
209
210 /* directory name, points into PathNameBuffer */
211 UNICODE_STRING DirNameU;
212
213 /* path + long file name 260 max*/
214 UNICODE_STRING PathNameU;
215
216 /* buffer for PathNameU */
217 WCHAR PathNameBuffer[MAX_PATH];
218
219 /* buffer for ShortNameU */
220 WCHAR ShortNameBuffer[13];
221
222 /* */
223 LONG RefCount;
224
225 /* List of FCB's for this volume */
226 LIST_ENTRY FcbListEntry;
227
228 /* pointer to the parent fcb */
229 struct _VFATFCB* parentFcb;
230
231 /* Flags for the fcb */
232 ULONG Flags;
233
234 /* pointer to the file object which has initialized the fcb */
235 PFILE_OBJECT FileObject;
236
237 /* Directory index for the short name entry */
238 ULONG dirIndex;
239
240 /* Directory index where the long name starts */
241 ULONG startIndex;
242
243 /* Share access for the file object */
244 SHARE_ACCESS FCBShareAccess;
245
246 /* Entry into the hash table for the path + long name */
247 HASHENTRY Hash;
248
249 /* Entry into the hash table for the path + short name */
250 HASHENTRY ShortHash;
251
252 /* List of byte-range locks for this file */
253 FILE_LOCK FileLock;
254
255 } VFATFCB, *PVFATFCB;
256
257 typedef struct _VFATCCB
258 {
259 LARGE_INTEGER CurrentByteOffset;
260 /* for DirectoryControl */
261 ULONG Entry;
262 /* for DirectoryControl */
263 UNICODE_STRING SearchPattern;
264 ULONG LastCluster;
265 ULONG LastOffset;
266
267 } VFATCCB, *PVFATCCB;
268
269 #ifndef TAG
270 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
271 #endif
272
273 #define TAG_CCB TAG('V', 'C', 'C', 'B')
274 #define TAG_FCB TAG('V', 'F', 'C', 'B')
275 #define TAG_IRP TAG('V', 'I', 'R', 'P')
276
277 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
278
279 typedef struct __DOSTIME
280 {
281 WORD Second:5;
282 WORD Minute:6;
283 WORD Hour:5;
284 }
285 DOSTIME, *PDOSTIME;
286
287 typedef struct __DOSDATE
288 {
289 WORD Day:5;
290 WORD Month:4;
291 WORD Year:5;
292 }
293 DOSDATE, *PDOSDATE;
294
295 #define IRPCONTEXT_CANWAIT 0x0001
296 #define IRPCONTEXT_PENDINGRETURNED 0x0002
297
298 typedef struct
299 {
300 PIRP Irp;
301 PDEVICE_OBJECT DeviceObject;
302 PDEVICE_EXTENSION DeviceExt;
303 ULONG Flags;
304 WORK_QUEUE_ITEM WorkQueueItem;
305 PIO_STACK_LOCATION Stack;
306 UCHAR MajorFunction;
307 UCHAR MinorFunction;
308 PFILE_OBJECT FileObject;
309 ULONG RefCount;
310 KEVENT Event;
311 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
312
313 typedef struct _VFAT_DIRENTRY_CONTEXT
314 {
315 ULONG StartIndex;
316 ULONG DirIndex;
317 FAT_DIR_ENTRY FatDirEntry;
318 UNICODE_STRING LongNameU;
319 UNICODE_STRING ShortNameU;
320 } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
321
322
323 /* ------------------------------------------------------ shutdown.c */
324
325 NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
326 PIRP Irp);
327
328 /* -------------------------------------------------------- volume.c */
329
330 NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
331
332 NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
333
334 /* ------------------------------------------------------ blockdev.c */
335
336 NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject,
337 IN PLARGE_INTEGER ReadOffset,
338 IN ULONG ReadLength,
339 IN PUCHAR Buffer,
340 IN BOOLEAN Override);
341
342 NTSTATUS VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
343 IN PLARGE_INTEGER ReadOffset,
344 IN ULONG ReadLength,
345 IN ULONG BufferOffset,
346 IN BOOLEAN Wait);
347
348 NTSTATUS VfatWriteDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext,
349 IN PLARGE_INTEGER WriteOffset,
350 IN ULONG WriteLength,
351 IN ULONG BufferOffset,
352 IN BOOLEAN Wait);
353
354 NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
355 IN ULONG CtlCode,
356 IN PVOID InputBuffer,
357 IN ULONG InputBufferSize,
358 IN OUT PVOID OutputBuffer,
359 IN OUT PULONG pOutputBufferSize,
360 IN BOOLEAN Override);
361
362 /* ----------------------------------------------------------- dir.c */
363
364 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
365
366 BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
367 WORD wDosTime,
368 TIME *FileTime);
369
370 BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
371 WORD *pwDosDate,
372 WORD *pwDosTime);
373
374 /* -------------------------------------------------------- create.c */
375
376 NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
377
378 NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
379 PFILE_OBJECT FileObject,
380 PUNICODE_STRING FileNameU);
381
382 NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
383 PVFATFCB Parent,
384 PUNICODE_STRING FileToFindU,
385 PVFAT_DIRENTRY_CONTEXT DirContext,
386 BOOLEAN First);
387
388 VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry,
389 PUNICODE_STRING NameU);
390
391 NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
392 PVPB Vpb);
393
394 /* --------------------------------------------------------- close.c */
395
396 NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
397
398 NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
399 PFILE_OBJECT FileObject);
400
401 /* ------------------------------------------------------- cleanup.c */
402
403 NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
404
405 /* --------------------------------------------------------- fsctl.c */
406
407 NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
408
409 /* --------------------------------------------------------- finfo.c */
410
411 NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
412
413 NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
414
415 NTSTATUS
416 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
417 PVFATFCB Fcb,
418 PDEVICE_EXTENSION DeviceExt,
419 PLARGE_INTEGER AllocationSize);
420
421 /* --------------------------------------------------------- iface.c */
422
423 NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
424 PUNICODE_STRING RegistryPath);
425
426 /* --------------------------------------------------------- dirwr.c */
427
428 NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
429 PUNICODE_STRING PathNameU,
430 PFILE_OBJECT pFileObject,
431 ULONG RequestedOptions,
432 UCHAR ReqAttr);
433
434 NTSTATUS VfatUpdateEntry (PVFATFCB pFcb);
435
436 NTSTATUS VfatDelEntry(PDEVICE_EXTENSION, PVFATFCB);
437
438 /* -------------------------------------------------------- string.c */
439
440 VOID
441 vfatSplitPathName(PUNICODE_STRING PathNameU,
442 PUNICODE_STRING DirNameU,
443 PUNICODE_STRING FileNameU);
444
445 BOOLEAN vfatIsLongIllegal(WCHAR c);
446
447 BOOLEAN wstrcmpjoki (PWSTR s1,
448 PWSTR s2);
449
450 /* ----------------------------------------------------------- fat.c */
451
452 NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
453 ULONG FirstCluster,
454 ULONG FileOffset,
455 PULONG Cluster,
456 BOOLEAN Extend);
457
458 ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
459 ULONG Cluster);
460
461 NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
462 ULONG CurrentCluster,
463 PULONG NextCluster,
464 BOOLEAN Extend);
465
466 NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
467 PLARGE_INTEGER Clusters);
468
469 NTSTATUS
470 WriteCluster(PDEVICE_EXTENSION DeviceExt,
471 ULONG ClusterToWrite,
472 ULONG NewValue);
473
474 /* ------------------------------------------------------ direntry.c */
475
476 ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
477 PFAT_DIR_ENTRY pDirEntry);
478
479 BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb);
480
481 NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
482 PVOID * pPage,
483 IN PVFATFCB pDirFcb,
484 IN PVFAT_DIRENTRY_CONTEXT DirContext,
485 BOOLEAN First);
486
487 /* ----------------------------------------------------------- fcb.c */
488
489 PVFATFCB vfatNewFCB (PUNICODE_STRING pFileNameU);
490
491 VOID vfatDestroyFCB (PVFATFCB pFCB);
492
493 VOID vfatDestroyCCB(PVFATCCB pCcb);
494
495 VOID vfatGrabFCB (PDEVICE_EXTENSION pVCB,
496 PVFATFCB pFCB);
497
498 VOID vfatReleaseFCB (PDEVICE_EXTENSION pVCB,
499 PVFATFCB pFCB);
500
501 VOID vfatAddFCBToTable (PDEVICE_EXTENSION pVCB,
502 PVFATFCB pFCB);
503
504 PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt,
505 PUNICODE_STRING pFileNameU);
506
507 PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
508
509 PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
510
511 BOOL vfatFCBIsDirectory (PVFATFCB FCB);
512
513 BOOL vfatFCBIsRoot(PVFATFCB FCB);
514
515 NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
516 PVFATFCB fcb,
517 PFILE_OBJECT fileObject);
518
519 NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB,
520 PVFATFCB parentFCB,
521 PUNICODE_STRING FileToFindU,
522 PVFATFCB * fileFCB);
523
524 NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
525 PVFATFCB *pParentFCB,
526 PVFATFCB *pFCB,
527 PUNICODE_STRING pFileNameU);
528
529 NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb,
530 PVFATFCB directoryFCB,
531 PVFAT_DIRENTRY_CONTEXT DirContext,
532 PVFATFCB * fileFCB);
533
534 /* ------------------------------------------------------------ rw.c */
535
536 NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
537
538 NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
539
540 NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
541 ULONG FirstCluster,
542 PULONG CurrentCluster,
543 BOOLEAN Extend);
544
545 /* ----------------------------------------------------------- misc.c */
546
547 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
548
549 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
550 PIRP Irp);
551
552 VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
553
554 NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
555 PIRP Irp);
556
557 PVOID VfatGetUserBuffer(IN PIRP);
558
559 NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
560 IN LOCK_OPERATION);
561
562 NTSTATUS
563 VfatSetExtendedAttributes(PFILE_OBJECT FileObject,
564 PVOID Ea,
565 ULONG EaLength);
566 /* ------------------------------------------------------------- flush.c */
567
568 NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext);
569
570 NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb);
571
572
573 /* EOF */