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