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