[FASTFAT] Use the FastFAT mechanism for counting clusters already implemented
[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 ULONG FSInfoSector;
267 } FATINFO, *PFATINFO;
268
269 struct _VFATFCB;
270 struct _VFAT_DIRENTRY_CONTEXT;
271 struct _VFAT_MOVE_CONTEXT;
272
273 typedef struct _HASHENTRY
274 {
275 ULONG Hash;
276 struct _VFATFCB* self;
277 struct _HASHENTRY* next;
278 }
279 HASHENTRY;
280
281 typedef struct DEVICE_EXTENSION *PDEVICE_EXTENSION;
282
283 typedef NTSTATUS (*PGET_NEXT_CLUSTER)(PDEVICE_EXTENSION,ULONG,PULONG);
284 typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
285 typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
286
287 typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(PDEVICE_EXTENSION,struct _VFATFCB*);
288 typedef NTSTATUS (*PADD_ENTRY)(PDEVICE_EXTENSION,PUNICODE_STRING,struct _VFATFCB**,struct _VFATFCB*,ULONG,UCHAR,struct _VFAT_MOVE_CONTEXT*);
289 typedef NTSTATUS (*PDEL_ENTRY)(PDEVICE_EXTENSION,struct _VFATFCB*,struct _VFAT_MOVE_CONTEXT*);
290 typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN);
291 typedef NTSTATUS (*PGET_DIRTY_STATUS)(PDEVICE_EXTENSION,PBOOLEAN);
292 typedef NTSTATUS (*PSET_DIRTY_STATUS)(PDEVICE_EXTENSION,BOOLEAN);
293
294 typedef struct _VFAT_DISPATCH
295 {
296 PIS_DIRECTORY_EMPTY IsDirectoryEmpty;
297 PADD_ENTRY AddEntry;
298 PDEL_ENTRY DelEntry;
299 PGET_NEXT_DIR_ENTRY GetNextDirEntry;
300 } VFAT_DISPATCH, *PVFAT_DISPATCH;
301
302 #define STATISTICS_SIZE_NO_PAD (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS))
303 typedef struct _STATISTICS {
304 FILESYSTEM_STATISTICS Base;
305 FAT_STATISTICS Fat;
306 UCHAR Pad[((STATISTICS_SIZE_NO_PAD + 0x3f) & ~0x3f) - STATISTICS_SIZE_NO_PAD];
307 } STATISTICS, *PSTATISTICS;
308
309 typedef struct DEVICE_EXTENSION
310 {
311 ERESOURCE DirResource;
312 ERESOURCE FatResource;
313
314 KSPIN_LOCK FcbListLock;
315 LIST_ENTRY FcbListHead;
316 ULONG HashTableSize;
317 struct _HASHENTRY **FcbHashTable;
318
319 PDEVICE_OBJECT VolumeDevice;
320 PDEVICE_OBJECT StorageDevice;
321 PFILE_OBJECT FATFileObject;
322 FATINFO FatInfo;
323 ULONG LastAvailableCluster;
324 ULONG AvailableClusters;
325 BOOLEAN AvailableClustersValid;
326 ULONG Flags;
327 struct _VFATFCB *VolumeFcb;
328 PSTATISTICS Statistics;
329
330 /* Pointers to functions for manipulating FAT. */
331 PGET_NEXT_CLUSTER GetNextCluster;
332 PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
333 PWRITE_CLUSTER WriteCluster;
334 PGET_DIRTY_STATUS GetDirtyStatus;
335 PSET_DIRTY_STATUS SetDirtyStatus;
336
337 ULONG BaseDateYear;
338
339 LIST_ENTRY VolumeListEntry;
340
341 /* Notifications */
342 LIST_ENTRY NotifyList;
343 PNOTIFY_SYNC NotifySync;
344
345 /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE */
346 ULONG OpenHandleCount;
347
348 /* VPBs for dismount */
349 PVPB IoVPB;
350 PVPB SpareVPB;
351
352 /* Pointers to functions for manipulating directory entries. */
353 VFAT_DISPATCH Dispatch;
354 } DEVICE_EXTENSION, VCB, *PVCB;
355
356 FORCEINLINE
357 BOOLEAN
358 VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,
359 struct _VFATFCB* Fcb)
360 {
361 return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, Fcb);
362 }
363
364 FORCEINLINE
365 NTSTATUS
366 VfatAddEntry(PDEVICE_EXTENSION DeviceExt,
367 PUNICODE_STRING NameU,
368 struct _VFATFCB** Fcb,
369 struct _VFATFCB* ParentFcb,
370 ULONG RequestedOptions,
371 UCHAR ReqAttr,
372 struct _VFAT_MOVE_CONTEXT* MoveContext)
373 {
374 return DeviceExt->Dispatch.AddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr, MoveContext);
375 }
376
377 FORCEINLINE
378 NTSTATUS
379 VfatDelEntry(PDEVICE_EXTENSION DeviceExt,
380 struct _VFATFCB* Fcb,
381 struct _VFAT_MOVE_CONTEXT* MoveContext)
382 {
383 return DeviceExt->Dispatch.DelEntry(DeviceExt, Fcb, MoveContext);
384 }
385
386 FORCEINLINE
387 NTSTATUS
388 VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt,
389 PVOID *pContext,
390 PVOID *pPage,
391 struct _VFATFCB* pDirFcb,
392 struct _VFAT_DIRENTRY_CONTEXT* DirContext,
393 BOOLEAN First)
394 {
395 return DeviceExt->Dispatch.GetNextDirEntry(pContext, pPage, pDirFcb, DirContext, First);
396 }
397
398 #define VFAT_BREAK_ON_CORRUPTION 1
399
400 typedef struct
401 {
402 PDRIVER_OBJECT DriverObject;
403 PDEVICE_OBJECT DeviceObject;
404 ULONG Flags;
405 ULONG NumberProcessors;
406 ERESOURCE VolumeListLock;
407 LIST_ENTRY VolumeListHead;
408 NPAGED_LOOKASIDE_LIST FcbLookasideList;
409 NPAGED_LOOKASIDE_LIST CcbLookasideList;
410 NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
411 FAST_IO_DISPATCH FastIoDispatch;
412 CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
413 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
414
415 extern PVFAT_GLOBAL_DATA VfatGlobalData;
416
417 #define FCB_CACHE_INITIALIZED 0x0001
418 #define FCB_DELETE_PENDING 0x0002
419 #define FCB_IS_FAT 0x0004
420 #define FCB_IS_PAGE_FILE 0x0008
421 #define FCB_IS_VOLUME 0x0010
422 #define FCB_IS_DIRTY 0x0020
423 #ifdef KDBG
424 #define FCB_CLEANED_UP 0x0040
425 #define FCB_CLOSED 0x0080
426 #endif
427
428 #define NODE_TYPE_FCB ((CSHORT)0x0502)
429
430 typedef struct _VFATFCB
431 {
432 /* FCB header required by ROS/NT */
433 FSRTL_COMMON_FCB_HEADER RFCB;
434 SECTION_OBJECT_POINTERS SectionObjectPointers;
435 ERESOURCE MainResource;
436 ERESOURCE PagingIoResource;
437 /* end FCB header required by ROS/NT */
438
439 /* directory entry for this file or directory */
440 DIR_ENTRY entry;
441
442 /* Pointer to attributes in entry */
443 PUCHAR Attributes;
444
445 /* long file name, points into PathNameBuffer */
446 UNICODE_STRING LongNameU;
447
448 /* short file name */
449 UNICODE_STRING ShortNameU;
450
451 /* directory name, points into PathNameBuffer */
452 UNICODE_STRING DirNameU;
453
454 /* path + long file name 260 max*/
455 UNICODE_STRING PathNameU;
456
457 /* buffer for PathNameU */
458 PWCHAR PathNameBuffer;
459
460 /* buffer for ShortNameU */
461 WCHAR ShortNameBuffer[13];
462
463 /* */
464 LONG RefCount;
465
466 /* List of FCB's for this volume */
467 LIST_ENTRY FcbListEntry;
468
469 /* List of FCB's for the parent */
470 LIST_ENTRY ParentListEntry;
471
472 /* pointer to the parent fcb */
473 struct _VFATFCB *parentFcb;
474
475 /* List for the children */
476 LIST_ENTRY ParentListHead;
477
478 /* Flags for the fcb */
479 ULONG Flags;
480
481 /* pointer to the file object which has initialized the fcb */
482 PFILE_OBJECT FileObject;
483
484 /* Directory index for the short name entry */
485 ULONG dirIndex;
486
487 /* Directory index where the long name starts */
488 ULONG startIndex;
489
490 /* Share access for the file object */
491 SHARE_ACCESS FCBShareAccess;
492
493 /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */
494 ULONG OpenHandleCount;
495
496 /* Entry into the hash table for the path + long name */
497 HASHENTRY Hash;
498
499 /* Entry into the hash table for the path + short name */
500 HASHENTRY ShortHash;
501
502 /* List of byte-range locks for this file */
503 FILE_LOCK FileLock;
504
505 /*
506 * Optimization: caching of last read/write cluster+offset pair. Can't
507 * be in VFATCCB because it must be reset everytime the allocated clusters
508 * change.
509 */
510 FAST_MUTEX LastMutex;
511 ULONG LastCluster;
512 ULONG LastOffset;
513 } VFATFCB, *PVFATFCB;
514
515 #define CCB_DELETE_ON_CLOSE 0x0001
516
517 typedef struct _VFATCCB
518 {
519 LARGE_INTEGER CurrentByteOffset;
520 ULONG Flags;
521 /* for DirectoryControl */
522 ULONG Entry;
523 /* for DirectoryControl */
524 UNICODE_STRING SearchPattern;
525 } VFATCCB, *PVFATCCB;
526
527 #define TAG_CCB 'BCCV'
528 #define TAG_FCB 'BCFV'
529 #define TAG_IRP 'PRIV'
530 #define TAG_VFAT 'TAFV'
531
532 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
533
534 typedef struct __DOSTIME
535 {
536 USHORT Second:5;
537 USHORT Minute:6;
538 USHORT Hour:5;
539 }
540 DOSTIME, *PDOSTIME;
541
542 typedef struct __DOSDATE
543 {
544 USHORT Day:5;
545 USHORT Month:4;
546 USHORT Year:7;
547 }
548 DOSDATE, *PDOSDATE;
549
550 #define IRPCONTEXT_CANWAIT 0x0001
551 #define IRPCONTEXT_COMPLETE 0x0002
552 #define IRPCONTEXT_QUEUE 0x0004
553 #define IRPCONTEXT_PENDINGRETURNED 0x0008
554 #define IRPCONTEXT_DEFERRED_WRITE 0x0010
555
556 typedef struct
557 {
558 PIRP Irp;
559 PDEVICE_OBJECT DeviceObject;
560 PDEVICE_EXTENSION DeviceExt;
561 ULONG Flags;
562 WORK_QUEUE_ITEM WorkQueueItem;
563 PIO_STACK_LOCATION Stack;
564 UCHAR MajorFunction;
565 UCHAR MinorFunction;
566 PFILE_OBJECT FileObject;
567 ULONG RefCount;
568 KEVENT Event;
569 CCHAR PriorityBoost;
570 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
571
572 typedef struct _VFAT_DIRENTRY_CONTEXT
573 {
574 ULONG StartIndex;
575 ULONG DirIndex;
576 DIR_ENTRY DirEntry;
577 UNICODE_STRING LongNameU;
578 UNICODE_STRING ShortNameU;
579 PDEVICE_EXTENSION DeviceExt;
580 } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
581
582 typedef struct _VFAT_MOVE_CONTEXT
583 {
584 ULONG FirstCluster;
585 ULONG FileSize;
586 USHORT CreationDate;
587 USHORT CreationTime;
588 BOOLEAN InPlace;
589 } VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
590
591 FORCEINLINE
592 NTSTATUS
593 VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
594 {
595 PULONG Flags = &IrpContext->Flags;
596
597 *Flags &= ~IRPCONTEXT_COMPLETE;
598 *Flags |= IRPCONTEXT_QUEUE;
599
600 return STATUS_PENDING;
601 }
602
603 FORCEINLINE
604 BOOLEAN
605 vfatFCBIsDirectory(PVFATFCB FCB)
606 {
607 return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_DIRECTORY);
608 }
609
610 FORCEINLINE
611 BOOLEAN
612 vfatFCBIsReadOnly(PVFATFCB FCB)
613 {
614 return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_READONLY);
615 }
616
617 FORCEINLINE
618 BOOLEAN
619 vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
620 {
621 return BooleanFlagOn(DeviceExt->Flags, VCB_IS_FATX);
622 }
623
624 FORCEINLINE
625 VOID
626 vfatReportChange(
627 IN PDEVICE_EXTENSION DeviceExt,
628 IN PVFATFCB Fcb,
629 IN ULONG FilterMatch,
630 IN ULONG Action)
631 {
632 FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
633 &(DeviceExt->NotifyList),
634 (PSTRING)&Fcb->PathNameU,
635 Fcb->PathNameU.Length - Fcb->LongNameU.Length,
636 NULL, NULL, FilterMatch, Action, NULL);
637 }
638
639 #define vfatAddToStat(Vcb, Stat, Inc) \
640 { \
641 PSTATISTICS Stats = &(Vcb)->Statistics[KeGetCurrentProcessorNumber() % VfatGlobalData->NumberProcessors]; \
642 Stats->Stat += Inc; \
643 }
644
645 /* blockdev.c */
646
647 NTSTATUS
648 VfatReadDisk(
649 IN PDEVICE_OBJECT pDeviceObject,
650 IN PLARGE_INTEGER ReadOffset,
651 IN ULONG ReadLength,
652 IN PUCHAR Buffer,
653 IN BOOLEAN Override);
654
655 NTSTATUS
656 VfatReadDiskPartial(
657 IN PVFAT_IRP_CONTEXT IrpContext,
658 IN PLARGE_INTEGER ReadOffset,
659 IN ULONG ReadLength,
660 IN ULONG BufferOffset,
661 IN BOOLEAN Wait);
662
663 NTSTATUS
664 VfatWriteDisk(
665 IN PDEVICE_OBJECT pDeviceObject,
666 IN PLARGE_INTEGER WriteOffset,
667 IN ULONG WriteLength,
668 IN OUT PUCHAR Buffer,
669 IN BOOLEAN Override);
670
671 NTSTATUS
672 VfatWriteDiskPartial(
673 IN PVFAT_IRP_CONTEXT IrpContext,
674 IN PLARGE_INTEGER WriteOffset,
675 IN ULONG WriteLength,
676 IN ULONG BufferOffset,
677 IN BOOLEAN Wait);
678
679 NTSTATUS
680 VfatBlockDeviceIoControl(
681 IN PDEVICE_OBJECT DeviceObject,
682 IN ULONG CtlCode,
683 IN PVOID InputBuffer,
684 IN ULONG InputBufferSize,
685 IN OUT PVOID OutputBuffer,
686 IN OUT PULONG pOutputBufferSize,
687 IN BOOLEAN Override);
688
689 /* cleanup.c */
690
691 NTSTATUS
692 VfatCleanup(
693 PVFAT_IRP_CONTEXT IrpContext);
694
695 /* close.c */
696
697 NTSTATUS
698 VfatClose(
699 PVFAT_IRP_CONTEXT IrpContext);
700
701 NTSTATUS
702 VfatCloseFile(
703 PDEVICE_EXTENSION DeviceExt,
704 PFILE_OBJECT FileObject);
705
706 /* create.c */
707
708 NTSTATUS
709 VfatCreate(
710 PVFAT_IRP_CONTEXT IrpContext);
711
712 NTSTATUS
713 FindFile(
714 PDEVICE_EXTENSION DeviceExt,
715 PVFATFCB Parent,
716 PUNICODE_STRING FileToFindU,
717 PVFAT_DIRENTRY_CONTEXT DirContext,
718 BOOLEAN First);
719
720 VOID
721 vfat8Dot3ToString(
722 PFAT_DIR_ENTRY pEntry,
723 PUNICODE_STRING NameU);
724
725 /* dir.c */
726
727 NTSTATUS
728 VfatDirectoryControl(
729 PVFAT_IRP_CONTEXT IrpContext);
730
731 BOOLEAN
732 FsdDosDateTimeToSystemTime(
733 PDEVICE_EXTENSION DeviceExt,
734 USHORT DosDate,
735 USHORT DosTime,
736 PLARGE_INTEGER SystemTime);
737
738 BOOLEAN
739 FsdSystemTimeToDosDateTime(
740 PDEVICE_EXTENSION DeviceExt,
741 PLARGE_INTEGER SystemTime,
742 USHORT *pDosDate,
743 USHORT *pDosTime);
744
745 /* direntry.c */
746
747 ULONG
748 vfatDirEntryGetFirstCluster(
749 PDEVICE_EXTENSION pDeviceExt,
750 PDIR_ENTRY pDirEntry);
751
752 /* dirwr.c */
753
754 NTSTATUS
755 vfatFCBInitializeCacheFromVolume(
756 PVCB vcb,
757 PVFATFCB fcb);
758
759 NTSTATUS
760 VfatUpdateEntry(
761 IN PDEVICE_EXTENSION DeviceExt,
762 PVFATFCB pFcb);
763
764 BOOLEAN
765 vfatFindDirSpace(
766 PDEVICE_EXTENSION DeviceExt,
767 PVFATFCB pDirFcb,
768 ULONG nbSlots,
769 PULONG start);
770
771 NTSTATUS
772 vfatRenameEntry(
773 IN PDEVICE_EXTENSION DeviceExt,
774 IN PVFATFCB pFcb,
775 IN PUNICODE_STRING FileName,
776 IN BOOLEAN CaseChangeOnly);
777
778 NTSTATUS
779 VfatMoveEntry(
780 IN PDEVICE_EXTENSION DeviceExt,
781 IN PVFATFCB pFcb,
782 IN PUNICODE_STRING FileName,
783 IN PVFATFCB ParentFcb);
784
785 /* ea.h */
786
787 NTSTATUS
788 VfatSetExtendedAttributes(
789 PFILE_OBJECT FileObject,
790 PVOID Ea,
791 ULONG EaLength);
792
793 /* fastio.c */
794
795 VOID
796 VfatInitFastIoRoutines(
797 PFAST_IO_DISPATCH FastIoDispatch);
798
799 BOOLEAN
800 NTAPI
801 VfatAcquireForLazyWrite(
802 IN PVOID Context,
803 IN BOOLEAN Wait);
804
805 VOID
806 NTAPI
807 VfatReleaseFromLazyWrite(
808 IN PVOID Context);
809
810 /* fat.c */
811
812 NTSTATUS
813 FAT12GetNextCluster(
814 PDEVICE_EXTENSION DeviceExt,
815 ULONG CurrentCluster,
816 PULONG NextCluster);
817
818 NTSTATUS
819 FAT12FindAndMarkAvailableCluster(
820 PDEVICE_EXTENSION DeviceExt,
821 PULONG Cluster);
822
823 NTSTATUS
824 FAT12WriteCluster(
825 PDEVICE_EXTENSION DeviceExt,
826 ULONG ClusterToWrite,
827 ULONG NewValue,
828 PULONG OldValue);
829
830 NTSTATUS
831 FAT16GetNextCluster(
832 PDEVICE_EXTENSION DeviceExt,
833 ULONG CurrentCluster,
834 PULONG NextCluster);
835
836 NTSTATUS
837 FAT16FindAndMarkAvailableCluster(
838 PDEVICE_EXTENSION DeviceExt,
839 PULONG Cluster);
840
841 NTSTATUS
842 FAT16WriteCluster(
843 PDEVICE_EXTENSION DeviceExt,
844 ULONG ClusterToWrite,
845 ULONG NewValue,
846 PULONG OldValue);
847
848 NTSTATUS
849 FAT32GetNextCluster(
850 PDEVICE_EXTENSION DeviceExt,
851 ULONG CurrentCluster,
852 PULONG NextCluster);
853
854 NTSTATUS
855 FAT32FindAndMarkAvailableCluster(
856 PDEVICE_EXTENSION DeviceExt,
857 PULONG Cluster);
858
859 NTSTATUS
860 FAT32WriteCluster(
861 PDEVICE_EXTENSION DeviceExt,
862 ULONG ClusterToWrite,
863 ULONG NewValue,
864 PULONG OldValue);
865
866 NTSTATUS
867 OffsetToCluster(
868 PDEVICE_EXTENSION DeviceExt,
869 ULONG FirstCluster,
870 ULONG FileOffset,
871 PULONG Cluster,
872 BOOLEAN Extend);
873
874 ULONGLONG
875 ClusterToSector(
876 PDEVICE_EXTENSION DeviceExt,
877 ULONG Cluster);
878
879 NTSTATUS
880 GetNextCluster(
881 PDEVICE_EXTENSION DeviceExt,
882 ULONG CurrentCluster,
883 PULONG NextCluster);
884
885 NTSTATUS
886 GetNextClusterExtend(
887 PDEVICE_EXTENSION DeviceExt,
888 ULONG CurrentCluster,
889 PULONG NextCluster);
890
891 NTSTATUS
892 CountAvailableClusters(
893 PDEVICE_EXTENSION DeviceExt,
894 PLARGE_INTEGER Clusters);
895
896 NTSTATUS
897 WriteCluster(
898 PDEVICE_EXTENSION DeviceExt,
899 ULONG ClusterToWrite,
900 ULONG NewValue);
901
902 NTSTATUS
903 GetDirtyStatus(
904 PDEVICE_EXTENSION DeviceExt,
905 PBOOLEAN DirtyStatus);
906
907 NTSTATUS
908 FAT16GetDirtyStatus(
909 PDEVICE_EXTENSION DeviceExt,
910 PBOOLEAN DirtyStatus);
911
912 NTSTATUS
913 FAT32GetDirtyStatus(
914 PDEVICE_EXTENSION DeviceExt,
915 PBOOLEAN DirtyStatus);
916
917 NTSTATUS
918 SetDirtyStatus(
919 PDEVICE_EXTENSION DeviceExt,
920 BOOLEAN DirtyStatus);
921
922 NTSTATUS
923 FAT16SetDirtyStatus(
924 PDEVICE_EXTENSION DeviceExt,
925 BOOLEAN DirtyStatus);
926
927 NTSTATUS
928 FAT32SetDirtyStatus(
929 PDEVICE_EXTENSION DeviceExt,
930 BOOLEAN DirtyStatus);
931
932 NTSTATUS
933 FAT32UpdateFreeClustersCount(
934 PDEVICE_EXTENSION DeviceExt);
935
936 /* fcb.c */
937
938 PVFATFCB
939 vfatNewFCB(
940 PDEVICE_EXTENSION pVCB,
941 PUNICODE_STRING pFileNameU);
942
943 NTSTATUS
944 vfatSetFCBNewDirName(
945 PDEVICE_EXTENSION pVCB,
946 PVFATFCB Fcb,
947 PVFATFCB ParentFcb);
948
949 NTSTATUS
950 vfatUpdateFCB(
951 PDEVICE_EXTENSION pVCB,
952 PVFATFCB Fcb,
953 PVFAT_DIRENTRY_CONTEXT DirContext,
954 PVFATFCB ParentFcb);
955
956 VOID
957 vfatDestroyFCB(
958 PVFATFCB pFCB);
959
960 VOID
961 vfatDestroyCCB(
962 PVFATCCB pCcb);
963
964 VOID
965 #ifndef KDBG
966 vfatGrabFCB(
967 #else
968 _vfatGrabFCB(
969 #endif
970 PDEVICE_EXTENSION pVCB,
971 PVFATFCB pFCB
972 #ifdef KDBG
973 ,
974 PCSTR File,
975 ULONG Line,
976 PCSTR Func
977 #endif
978 );
979
980 VOID
981 #ifndef KDBG
982 vfatReleaseFCB(
983 #else
984 _vfatReleaseFCB(
985 #endif
986 PDEVICE_EXTENSION pVCB,
987 PVFATFCB pFCB
988 #ifdef KDBG
989 ,
990 PCSTR File,
991 ULONG Line,
992 PCSTR Func
993 #endif
994 );
995
996 #ifdef KDBG
997 #define vfatGrabFCB(v, f) _vfatGrabFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
998 #define vfatReleaseFCB(v, f) _vfatReleaseFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
999 #endif
1000
1001 PVFATFCB
1002 vfatGrabFCBFromTable(
1003 PDEVICE_EXTENSION pDeviceExt,
1004 PUNICODE_STRING pFileNameU);
1005
1006 PVFATFCB
1007 vfatMakeRootFCB(
1008 PDEVICE_EXTENSION pVCB);
1009
1010 PVFATFCB
1011 vfatOpenRootFCB(
1012 PDEVICE_EXTENSION pVCB);
1013
1014 BOOLEAN
1015 vfatFCBIsDirectory(
1016 PVFATFCB FCB);
1017
1018 BOOLEAN
1019 vfatFCBIsRoot(
1020 PVFATFCB FCB);
1021
1022 NTSTATUS
1023 vfatAttachFCBToFileObject(
1024 PDEVICE_EXTENSION vcb,
1025 PVFATFCB fcb,
1026 PFILE_OBJECT fileObject);
1027
1028 NTSTATUS
1029 vfatDirFindFile(
1030 PDEVICE_EXTENSION pVCB,
1031 PVFATFCB parentFCB,
1032 PUNICODE_STRING FileToFindU,
1033 PVFATFCB *fileFCB);
1034
1035 NTSTATUS
1036 vfatGetFCBForFile(
1037 PDEVICE_EXTENSION pVCB,
1038 PVFATFCB *pParentFCB,
1039 PVFATFCB *pFCB,
1040 PUNICODE_STRING pFileNameU);
1041
1042 NTSTATUS
1043 vfatMakeFCBFromDirEntry(
1044 PVCB vcb,
1045 PVFATFCB directoryFCB,
1046 PVFAT_DIRENTRY_CONTEXT DirContext,
1047 PVFATFCB *fileFCB);
1048
1049 /* finfo.c */
1050
1051 NTSTATUS
1052 VfatGetStandardInformation(
1053 PVFATFCB FCB,
1054 PFILE_STANDARD_INFORMATION StandardInfo,
1055 PULONG BufferLength);
1056
1057 NTSTATUS
1058 VfatGetBasicInformation(
1059 PFILE_OBJECT FileObject,
1060 PVFATFCB FCB,
1061 PDEVICE_EXTENSION DeviceExt,
1062 PFILE_BASIC_INFORMATION BasicInfo,
1063 PULONG BufferLength);
1064
1065 NTSTATUS
1066 VfatQueryInformation(
1067 PVFAT_IRP_CONTEXT IrpContext);
1068
1069 NTSTATUS
1070 VfatSetInformation(
1071 PVFAT_IRP_CONTEXT IrpContext);
1072
1073 NTSTATUS
1074 VfatSetAllocationSizeInformation(
1075 PFILE_OBJECT FileObject,
1076 PVFATFCB Fcb,
1077 PDEVICE_EXTENSION DeviceExt,
1078 PLARGE_INTEGER AllocationSize);
1079
1080 /* flush.c */
1081
1082 NTSTATUS
1083 VfatFlush(
1084 PVFAT_IRP_CONTEXT IrpContext);
1085
1086 NTSTATUS
1087 VfatFlushVolume(
1088 PDEVICE_EXTENSION DeviceExt,
1089 PVFATFCB VolumeFcb);
1090
1091 /* fsctl.c */
1092
1093 NTSTATUS
1094 VfatFileSystemControl(
1095 PVFAT_IRP_CONTEXT IrpContext);
1096
1097 /* iface.c */
1098
1099 NTSTATUS
1100 NTAPI
1101 DriverEntry(
1102 PDRIVER_OBJECT DriverObject,
1103 PUNICODE_STRING RegistryPath);
1104
1105 #ifdef KDBG
1106 /* kdbg.c */
1107 KDBG_CLI_ROUTINE vfatKdbgHandler;
1108 #endif
1109
1110 /* misc.c */
1111
1112 DRIVER_DISPATCH
1113 VfatBuildRequest;
1114
1115 NTSTATUS
1116 NTAPI
1117 VfatBuildRequest(
1118 PDEVICE_OBJECT DeviceObject,
1119 PIRP Irp);
1120
1121 PVOID
1122 VfatGetUserBuffer(
1123 IN PIRP,
1124 IN BOOLEAN Paging);
1125
1126 NTSTATUS
1127 VfatLockUserBuffer(
1128 IN PIRP,
1129 IN ULONG,
1130 IN LOCK_OPERATION);
1131
1132 BOOLEAN
1133 VfatCheckForDismount(
1134 IN PDEVICE_EXTENSION DeviceExt,
1135 IN BOOLEAN Create);
1136
1137 VOID
1138 vfatReportChange(
1139 IN PDEVICE_EXTENSION DeviceExt,
1140 IN PVFATFCB Fcb,
1141 IN ULONG FilterMatch,
1142 IN ULONG Action);
1143
1144 VOID
1145 NTAPI
1146 VfatHandleDeferredWrite(
1147 IN PVOID IrpContext,
1148 IN PVOID Unused);
1149
1150 /* pnp.c */
1151
1152 NTSTATUS
1153 VfatPnp(
1154 PVFAT_IRP_CONTEXT IrpContext);
1155
1156 /* rw.c */
1157
1158 NTSTATUS
1159 VfatRead(
1160 PVFAT_IRP_CONTEXT IrpContext);
1161
1162 NTSTATUS
1163 VfatWrite(
1164 PVFAT_IRP_CONTEXT IrpContext);
1165
1166 NTSTATUS
1167 NextCluster(
1168 PDEVICE_EXTENSION DeviceExt,
1169 ULONG FirstCluster,
1170 PULONG CurrentCluster,
1171 BOOLEAN Extend);
1172
1173 /* shutdown.c */
1174
1175 DRIVER_DISPATCH
1176 VfatShutdown;
1177
1178 NTSTATUS
1179 NTAPI
1180 VfatShutdown(
1181 PDEVICE_OBJECT DeviceObject,
1182 PIRP Irp);
1183
1184 /* string.c */
1185
1186 VOID
1187 vfatSplitPathName(
1188 PUNICODE_STRING PathNameU,
1189 PUNICODE_STRING DirNameU,
1190 PUNICODE_STRING FileNameU);
1191
1192 BOOLEAN
1193 vfatIsLongIllegal(
1194 WCHAR c);
1195
1196 BOOLEAN
1197 wstrcmpjoki(
1198 PWSTR s1,
1199 PWSTR s2);
1200
1201 /* volume.c */
1202
1203 NTSTATUS
1204 VfatQueryVolumeInformation(
1205 PVFAT_IRP_CONTEXT IrpContext);
1206
1207 NTSTATUS
1208 VfatSetVolumeInformation(
1209 PVFAT_IRP_CONTEXT IrpContext);
1210
1211 #endif /* _FASTFAT_PCH_ */