e58b61bb5763ef67077e55bd81b0863adc86fb71
[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)(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(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 } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
574
575 typedef struct _VFAT_MOVE_CONTEXT
576 {
577 ULONG FirstCluster;
578 ULONG FileSize;
579 USHORT CreationDate;
580 USHORT CreationTime;
581 BOOLEAN InPlace;
582 } VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
583
584 FORCEINLINE
585 NTSTATUS
586 VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
587 {
588 PULONG Flags = &IrpContext->Flags;
589
590 *Flags &= ~IRPCONTEXT_COMPLETE;
591 *Flags |= IRPCONTEXT_QUEUE;
592
593 return STATUS_PENDING;
594 }
595
596 FORCEINLINE
597 BOOLEAN
598 vfatFCBIsDirectory(PVFATFCB FCB)
599 {
600 return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_DIRECTORY);
601 }
602
603 FORCEINLINE
604 BOOLEAN
605 vfatFCBIsReadOnly(PVFATFCB FCB)
606 {
607 return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_READONLY);
608 }
609
610 FORCEINLINE
611 BOOLEAN
612 vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
613 {
614 return BooleanFlagOn(DeviceExt->Flags, VCB_IS_FATX);
615 }
616
617 FORCEINLINE
618 VOID
619 vfatReportChange(
620 IN PDEVICE_EXTENSION DeviceExt,
621 IN PVFATFCB Fcb,
622 IN ULONG FilterMatch,
623 IN ULONG Action)
624 {
625 FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
626 &(DeviceExt->NotifyList),
627 (PSTRING)&Fcb->PathNameU,
628 Fcb->PathNameU.Length - Fcb->LongNameU.Length,
629 NULL, NULL, FilterMatch, Action, NULL);
630 }
631
632 #define vfatAddToStat(Vcb, Stat, Inc) \
633 { \
634 PSTATISTICS Stats = &(Vcb)->Statistics[KeGetCurrentProcessorNumber() % VfatGlobalData->NumberProcessors]; \
635 Stats->Stat += Inc; \
636 }
637
638 /* blockdev.c */
639
640 NTSTATUS
641 VfatReadDisk(
642 IN PDEVICE_OBJECT pDeviceObject,
643 IN PLARGE_INTEGER ReadOffset,
644 IN ULONG ReadLength,
645 IN PUCHAR Buffer,
646 IN BOOLEAN Override);
647
648 NTSTATUS
649 VfatReadDiskPartial(
650 IN PVFAT_IRP_CONTEXT IrpContext,
651 IN PLARGE_INTEGER ReadOffset,
652 IN ULONG ReadLength,
653 IN ULONG BufferOffset,
654 IN BOOLEAN Wait);
655
656 NTSTATUS
657 VfatWriteDiskPartial(
658 IN PVFAT_IRP_CONTEXT IrpContext,
659 IN PLARGE_INTEGER WriteOffset,
660 IN ULONG WriteLength,
661 IN ULONG BufferOffset,
662 IN BOOLEAN Wait);
663
664 NTSTATUS
665 VfatBlockDeviceIoControl(
666 IN PDEVICE_OBJECT DeviceObject,
667 IN ULONG CtlCode,
668 IN PVOID InputBuffer,
669 IN ULONG InputBufferSize,
670 IN OUT PVOID OutputBuffer,
671 IN OUT PULONG pOutputBufferSize,
672 IN BOOLEAN Override);
673
674 /* cleanup.c */
675
676 NTSTATUS
677 VfatCleanup(
678 PVFAT_IRP_CONTEXT IrpContext);
679
680 /* close.c */
681
682 NTSTATUS
683 VfatClose(
684 PVFAT_IRP_CONTEXT IrpContext);
685
686 NTSTATUS
687 VfatCloseFile(
688 PDEVICE_EXTENSION DeviceExt,
689 PFILE_OBJECT FileObject);
690
691 /* create.c */
692
693 NTSTATUS
694 VfatCreate(
695 PVFAT_IRP_CONTEXT IrpContext);
696
697 NTSTATUS
698 FindFile(
699 PDEVICE_EXTENSION DeviceExt,
700 PVFATFCB Parent,
701 PUNICODE_STRING FileToFindU,
702 PVFAT_DIRENTRY_CONTEXT DirContext,
703 BOOLEAN First);
704
705 VOID
706 vfat8Dot3ToString(
707 PFAT_DIR_ENTRY pEntry,
708 PUNICODE_STRING NameU);
709
710 /* dir.c */
711
712 NTSTATUS
713 VfatDirectoryControl(
714 PVFAT_IRP_CONTEXT IrpContext);
715
716 BOOLEAN
717 FsdDosDateTimeToSystemTime(
718 PDEVICE_EXTENSION DeviceExt,
719 USHORT DosDate,
720 USHORT DosTime,
721 PLARGE_INTEGER SystemTime);
722
723 BOOLEAN
724 FsdSystemTimeToDosDateTime(
725 PDEVICE_EXTENSION DeviceExt,
726 PLARGE_INTEGER SystemTime,
727 USHORT *pDosDate,
728 USHORT *pDosTime);
729
730 /* direntry.c */
731
732 ULONG
733 vfatDirEntryGetFirstCluster(
734 PDEVICE_EXTENSION pDeviceExt,
735 PDIR_ENTRY pDirEntry);
736
737 /* dirwr.c */
738
739 NTSTATUS
740 VfatUpdateEntry(
741 PVFATFCB pFcb,
742 IN BOOLEAN IsFatX);
743
744 BOOLEAN
745 vfatFindDirSpace(
746 PDEVICE_EXTENSION DeviceExt,
747 PVFATFCB pDirFcb,
748 ULONG nbSlots,
749 PULONG start);
750
751 NTSTATUS
752 vfatRenameEntry(
753 IN PDEVICE_EXTENSION DeviceExt,
754 IN PVFATFCB pFcb,
755 IN PUNICODE_STRING FileName,
756 IN BOOLEAN CaseChangeOnly);
757
758 NTSTATUS
759 VfatMoveEntry(
760 IN PDEVICE_EXTENSION DeviceExt,
761 IN PVFATFCB pFcb,
762 IN PUNICODE_STRING FileName,
763 IN PVFATFCB ParentFcb);
764
765 /* ea.h */
766
767 NTSTATUS
768 VfatSetExtendedAttributes(
769 PFILE_OBJECT FileObject,
770 PVOID Ea,
771 ULONG EaLength);
772
773 /* fastio.c */
774
775 VOID
776 VfatInitFastIoRoutines(
777 PFAST_IO_DISPATCH FastIoDispatch);
778
779 BOOLEAN
780 NTAPI
781 VfatAcquireForLazyWrite(
782 IN PVOID Context,
783 IN BOOLEAN Wait);
784
785 VOID
786 NTAPI
787 VfatReleaseFromLazyWrite(
788 IN PVOID Context);
789
790 /* fat.c */
791
792 NTSTATUS
793 FAT12GetNextCluster(
794 PDEVICE_EXTENSION DeviceExt,
795 ULONG CurrentCluster,
796 PULONG NextCluster);
797
798 NTSTATUS
799 FAT12FindAndMarkAvailableCluster(
800 PDEVICE_EXTENSION DeviceExt,
801 PULONG Cluster);
802
803 NTSTATUS
804 FAT12WriteCluster(
805 PDEVICE_EXTENSION DeviceExt,
806 ULONG ClusterToWrite,
807 ULONG NewValue,
808 PULONG OldValue);
809
810 NTSTATUS
811 FAT16GetNextCluster(
812 PDEVICE_EXTENSION DeviceExt,
813 ULONG CurrentCluster,
814 PULONG NextCluster);
815
816 NTSTATUS
817 FAT16FindAndMarkAvailableCluster(
818 PDEVICE_EXTENSION DeviceExt,
819 PULONG Cluster);
820
821 NTSTATUS
822 FAT16WriteCluster(
823 PDEVICE_EXTENSION DeviceExt,
824 ULONG ClusterToWrite,
825 ULONG NewValue,
826 PULONG OldValue);
827
828 NTSTATUS
829 FAT32GetNextCluster(
830 PDEVICE_EXTENSION DeviceExt,
831 ULONG CurrentCluster,
832 PULONG NextCluster);
833
834 NTSTATUS
835 FAT32FindAndMarkAvailableCluster(
836 PDEVICE_EXTENSION DeviceExt,
837 PULONG Cluster);
838
839 NTSTATUS
840 FAT32WriteCluster(
841 PDEVICE_EXTENSION DeviceExt,
842 ULONG ClusterToWrite,
843 ULONG NewValue,
844 PULONG OldValue);
845
846 NTSTATUS
847 OffsetToCluster(
848 PDEVICE_EXTENSION DeviceExt,
849 ULONG FirstCluster,
850 ULONG FileOffset,
851 PULONG Cluster,
852 BOOLEAN Extend);
853
854 ULONGLONG
855 ClusterToSector(
856 PDEVICE_EXTENSION DeviceExt,
857 ULONG Cluster);
858
859 NTSTATUS
860 GetNextCluster(
861 PDEVICE_EXTENSION DeviceExt,
862 ULONG CurrentCluster,
863 PULONG NextCluster);
864
865 NTSTATUS
866 GetNextClusterExtend(
867 PDEVICE_EXTENSION DeviceExt,
868 ULONG CurrentCluster,
869 PULONG NextCluster);
870
871 NTSTATUS
872 CountAvailableClusters(
873 PDEVICE_EXTENSION DeviceExt,
874 PLARGE_INTEGER Clusters);
875
876 NTSTATUS
877 WriteCluster(
878 PDEVICE_EXTENSION DeviceExt,
879 ULONG ClusterToWrite,
880 ULONG NewValue);
881
882 /* fcb.c */
883
884 PVFATFCB
885 vfatNewFCB(
886 PDEVICE_EXTENSION pVCB,
887 PUNICODE_STRING pFileNameU);
888
889 NTSTATUS
890 vfatSetFCBNewDirName(
891 PDEVICE_EXTENSION pVCB,
892 PVFATFCB Fcb,
893 PVFATFCB ParentFcb);
894
895 NTSTATUS
896 vfatUpdateFCB(
897 PDEVICE_EXTENSION pVCB,
898 PVFATFCB Fcb,
899 PVFAT_DIRENTRY_CONTEXT DirContext,
900 PVFATFCB ParentFcb);
901
902 VOID
903 vfatDestroyFCB(
904 PVFATFCB pFCB);
905
906 VOID
907 vfatDestroyCCB(
908 PVFATCCB pCcb);
909
910 VOID
911 #ifndef KDBG
912 vfatGrabFCB(
913 #else
914 _vfatGrabFCB(
915 #endif
916 PDEVICE_EXTENSION pVCB,
917 PVFATFCB pFCB
918 #ifdef KDBG
919 ,
920 PCSTR File,
921 ULONG Line,
922 PCSTR Func
923 #endif
924 );
925
926 VOID
927 #ifndef KDBG
928 vfatReleaseFCB(
929 #else
930 _vfatReleaseFCB(
931 #endif
932 PDEVICE_EXTENSION pVCB,
933 PVFATFCB pFCB
934 #ifdef KDBG
935 ,
936 PCSTR File,
937 ULONG Line,
938 PCSTR Func
939 #endif
940 );
941
942 #ifdef KDBG
943 #define vfatGrabFCB(v, f) _vfatGrabFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
944 #define vfatReleaseFCB(v, f) _vfatReleaseFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
945 #endif
946
947 PVFATFCB
948 vfatGrabFCBFromTable(
949 PDEVICE_EXTENSION pDeviceExt,
950 PUNICODE_STRING pFileNameU);
951
952 PVFATFCB
953 vfatMakeRootFCB(
954 PDEVICE_EXTENSION pVCB);
955
956 PVFATFCB
957 vfatOpenRootFCB(
958 PDEVICE_EXTENSION pVCB);
959
960 BOOLEAN
961 vfatFCBIsDirectory(
962 PVFATFCB FCB);
963
964 BOOLEAN
965 vfatFCBIsRoot(
966 PVFATFCB FCB);
967
968 NTSTATUS
969 vfatAttachFCBToFileObject(
970 PDEVICE_EXTENSION vcb,
971 PVFATFCB fcb,
972 PFILE_OBJECT fileObject);
973
974 NTSTATUS
975 vfatDirFindFile(
976 PDEVICE_EXTENSION pVCB,
977 PVFATFCB parentFCB,
978 PUNICODE_STRING FileToFindU,
979 PVFATFCB *fileFCB);
980
981 NTSTATUS
982 vfatGetFCBForFile(
983 PDEVICE_EXTENSION pVCB,
984 PVFATFCB *pParentFCB,
985 PVFATFCB *pFCB,
986 PUNICODE_STRING pFileNameU);
987
988 NTSTATUS
989 vfatMakeFCBFromDirEntry(
990 PVCB vcb,
991 PVFATFCB directoryFCB,
992 PVFAT_DIRENTRY_CONTEXT DirContext,
993 PVFATFCB *fileFCB);
994
995 /* finfo.c */
996
997 NTSTATUS
998 VfatGetStandardInformation(
999 PVFATFCB FCB,
1000 PFILE_STANDARD_INFORMATION StandardInfo,
1001 PULONG BufferLength);
1002
1003 NTSTATUS
1004 VfatGetBasicInformation(
1005 PFILE_OBJECT FileObject,
1006 PVFATFCB FCB,
1007 PDEVICE_EXTENSION DeviceExt,
1008 PFILE_BASIC_INFORMATION BasicInfo,
1009 PULONG BufferLength);
1010
1011 NTSTATUS
1012 VfatQueryInformation(
1013 PVFAT_IRP_CONTEXT IrpContext);
1014
1015 NTSTATUS
1016 VfatSetInformation(
1017 PVFAT_IRP_CONTEXT IrpContext);
1018
1019 NTSTATUS
1020 VfatSetAllocationSizeInformation(
1021 PFILE_OBJECT FileObject,
1022 PVFATFCB Fcb,
1023 PDEVICE_EXTENSION DeviceExt,
1024 PLARGE_INTEGER AllocationSize);
1025
1026 /* flush.c */
1027
1028 NTSTATUS
1029 VfatFlush(
1030 PVFAT_IRP_CONTEXT IrpContext);
1031
1032 NTSTATUS
1033 VfatFlushVolume(
1034 PDEVICE_EXTENSION DeviceExt,
1035 PVFATFCB VolumeFcb);
1036
1037 /* fsctl.c */
1038
1039 NTSTATUS
1040 VfatFileSystemControl(
1041 PVFAT_IRP_CONTEXT IrpContext);
1042
1043 /* iface.c */
1044
1045 NTSTATUS
1046 NTAPI
1047 DriverEntry(
1048 PDRIVER_OBJECT DriverObject,
1049 PUNICODE_STRING RegistryPath);
1050
1051 #ifdef KDBG
1052 /* kdbg.c */
1053 KDBG_CLI_ROUTINE vfatKdbgHandler;
1054 #endif
1055
1056 /* misc.c */
1057
1058 DRIVER_DISPATCH
1059 VfatBuildRequest;
1060
1061 NTSTATUS
1062 NTAPI
1063 VfatBuildRequest(
1064 PDEVICE_OBJECT DeviceObject,
1065 PIRP Irp);
1066
1067 PVOID
1068 VfatGetUserBuffer(
1069 IN PIRP,
1070 IN BOOLEAN Paging);
1071
1072 NTSTATUS
1073 VfatLockUserBuffer(
1074 IN PIRP,
1075 IN ULONG,
1076 IN LOCK_OPERATION);
1077
1078 BOOLEAN
1079 VfatCheckForDismount(
1080 IN PDEVICE_EXTENSION DeviceExt,
1081 IN BOOLEAN Create);
1082
1083 VOID
1084 vfatReportChange(
1085 IN PDEVICE_EXTENSION DeviceExt,
1086 IN PVFATFCB Fcb,
1087 IN ULONG FilterMatch,
1088 IN ULONG Action);
1089
1090 VOID
1091 NTAPI
1092 VfatHandleDeferredWrite(
1093 IN PVOID IrpContext,
1094 IN PVOID Unused);
1095
1096 /* pnp.c */
1097
1098 NTSTATUS
1099 VfatPnp(
1100 PVFAT_IRP_CONTEXT IrpContext);
1101
1102 /* rw.c */
1103
1104 NTSTATUS
1105 VfatRead(
1106 PVFAT_IRP_CONTEXT IrpContext);
1107
1108 NTSTATUS
1109 VfatWrite(
1110 PVFAT_IRP_CONTEXT IrpContext);
1111
1112 NTSTATUS
1113 NextCluster(
1114 PDEVICE_EXTENSION DeviceExt,
1115 ULONG FirstCluster,
1116 PULONG CurrentCluster,
1117 BOOLEAN Extend);
1118
1119 /* shutdown.c */
1120
1121 DRIVER_DISPATCH
1122 VfatShutdown;
1123
1124 NTSTATUS
1125 NTAPI
1126 VfatShutdown(
1127 PDEVICE_OBJECT DeviceObject,
1128 PIRP Irp);
1129
1130 /* string.c */
1131
1132 VOID
1133 vfatSplitPathName(
1134 PUNICODE_STRING PathNameU,
1135 PUNICODE_STRING DirNameU,
1136 PUNICODE_STRING FileNameU);
1137
1138 BOOLEAN
1139 vfatIsLongIllegal(
1140 WCHAR c);
1141
1142 BOOLEAN
1143 wstrcmpjoki(
1144 PWSTR s1,
1145 PWSTR s2);
1146
1147 /* volume.c */
1148
1149 NTSTATUS
1150 VfatQueryVolumeInformation(
1151 PVFAT_IRP_CONTEXT IrpContext);
1152
1153 NTSTATUS
1154 VfatSetVolumeInformation(
1155 PVFAT_IRP_CONTEXT IrpContext);
1156
1157 #endif /* _FASTFAT_PCH_ */