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