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