[FASTFAT] Fix size checking in VfatGetFileNameInformation()
[reactos.git] / drivers / filesystems / fastfat_new / fatstruc.h
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 FatStruc.h
8
9 Abstract:
10
11 This module defines the data structures that make up the major internal
12 part of the Fat file system.
13
14
15 --*/
16
17 #ifndef _FATSTRUC_
18 #define _FATSTRUC_
19
20 typedef PVOID PBCB; //**** Bcb's are now part of the cache module
21
22 \f
23 //
24 // The FAT_DATA record is the top record in the Fat file system in-memory
25 // data structure. This structure must be allocated from non-paged pool.
26 //
27
28 typedef struct _FAT_DATA {
29
30 //
31 // The type and size of this record (must be FAT_NTC_DATA_HEADER)
32 //
33
34 NODE_TYPE_CODE NodeTypeCode;
35 NODE_BYTE_SIZE NodeByteSize;
36
37
38 PVOID LazyWriteThread;
39
40
41 //
42 // A queue of all the devices that are mounted by the file system.
43 //
44
45 LIST_ENTRY VcbQueue;
46
47 //
48 // A pointer to the Driver object we were initialized with
49 //
50
51 PDRIVER_OBJECT DriverObject;
52
53 //
54 // A pointer to the filesystem device objects we created.
55 //
56
57 PVOID DiskFileSystemDeviceObject;
58 PVOID CdromFileSystemDeviceObject;
59
60 //
61 // A resource variable to control access to the global Fat data record
62 //
63
64 ERESOURCE Resource;
65
66 //
67 // A pointer to our EPROCESS struct, which is a required input to the
68 // Cache Management subsystem.
69 //
70
71 PEPROCESS OurProcess;
72
73 //
74 // Number of processors when the driver loaded.
75 //
76
77 ULONG NumberProcessors;
78
79 //
80 // The following tells us if we should use Chicago extensions.
81 //
82
83 BOOLEAN ChicagoMode:1;
84
85 //
86 // The following field tells us if we are running on a Fujitsu
87 // FMR Series. These machines supports extra formats on the
88 // FAT file system.
89 //
90
91 BOOLEAN FujitsuFMR:1;
92
93 //
94 // Inidicates that FspClose is currently processing closes.
95 //
96
97 BOOLEAN AsyncCloseActive:1;
98
99 //
100 // The following BOOLEAN says shutdown has started on FAT. It
101 // instructs FspClose to not keep the Vcb resources anymore.
102 //
103
104 BOOLEAN ShutdownStarted:1;
105
106 //
107 // The following flag tells us if we are going to generate LFNs
108 // for valid 8.3 names with extended characters.
109 //
110
111 BOOLEAN CodePageInvariant:1;
112
113 //
114 // The following flags tell us if we are in an aggresive push to lower
115 // the size of the deferred close queues.
116 //
117
118 BOOLEAN HighAsync:1;
119 BOOLEAN HighDelayed:1;
120
121
122 //
123 // The following list entry is used for performing closes that can't
124 // be done in the context of the original caller.
125 //
126
127 ULONG AsyncCloseCount;
128 LIST_ENTRY AsyncCloseList;
129
130 //
131 // The following two fields record if we are delaying a close.
132 //
133
134 ULONG DelayedCloseCount;
135 LIST_ENTRY DelayedCloseList;
136
137 //
138 // This is the ExWorkerItem that does both kinds of deferred closes.
139 //
140
141 PIO_WORKITEM FatCloseItem;
142
143 //
144 // This spinlock protects several rapid-fire operations. NOTE: this is
145 // pretty horrible style.
146 //
147
148 KSPIN_LOCK GeneralSpinLock;
149
150 //
151 // Cache manager call back structures, which must be passed on each call
152 // to CcInitializeCacheMap.
153 //
154
155 CACHE_MANAGER_CALLBACKS CacheManagerCallbacks;
156 CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks;
157
158
159 PVOID ZeroPage;
160
161 } FAT_DATA;
162 typedef FAT_DATA *PFAT_DATA;
163
164 //
165 // An array of these structures will keep
166
167 typedef struct _FAT_WINDOW {
168
169 ULONG FirstCluster; // The first cluster in this window.
170 ULONG LastCluster; // The last cluster in this window.
171 ULONG ClustersFree; // The number of clusters free in this window.
172
173 } FAT_WINDOW;
174 typedef FAT_WINDOW *PFAT_WINDOW;
175
176 //
177 // Forward reference some circular referenced structures.
178 //
179
180 typedef struct _VCB VCB;
181 typedef VCB *PVCB;
182
183 typedef struct _FCB FCB;
184 typedef FCB *PFCB;
185
186 //
187 // This structure is used to keep track of information needed to do a
188 // deferred close. It is now embedded in a CCB so we don't have to
189 // allocate one in the close path (with mustsucceed).
190 //
191
192 typedef struct {
193
194 //
195 // Two sets of links, one for the global list and one for closes
196 // on a particular volume.
197 //
198
199 LIST_ENTRY GlobalLinks;
200 LIST_ENTRY VcbLinks;
201
202 PVCB Vcb;
203 PFCB Fcb;
204 enum _TYPE_OF_OPEN TypeOfOpen;
205 BOOLEAN Free;
206
207 } CLOSE_CONTEXT;
208
209 typedef CLOSE_CONTEXT *PCLOSE_CONTEXT;
210
211
212 //
213 // The Vcb (Volume control Block) record corresponds to every volume mounted
214 // by the file system. They are ordered in a queue off of FatData.VcbQueue.
215 // This structure must be allocated from non-paged pool
216 //
217
218 typedef enum _VCB_CONDITION {
219 VcbGood = 1,
220 VcbNotMounted,
221 VcbBad
222 } VCB_CONDITION;
223
224 typedef struct _VCB {
225
226 //
227 // This is a common head for the FAT volume file
228 //
229
230 FSRTL_ADVANCED_FCB_HEADER VolumeFileHeader;
231
232 //
233 // The links for the device queue off of FatData.VcbQueue
234 //
235
236 LIST_ENTRY VcbLinks;
237
238 //
239 // A pointer the device object passed in by the I/O system on a mount
240 // This is the target device object that the file system talks to when it
241 // needs to do any I/O (e.g., the disk stripper device object).
242 //
243 //
244
245 PDEVICE_OBJECT TargetDeviceObject;
246
247 #if (NTDDI_VERSION > NTDDI_WIN8)
248 //
249 // The volume GUID of the target device object.
250 //
251
252 GUID VolumeGuid;
253 #endif
254
255 //
256 // The volume GUID path of the target device object.
257 //
258
259 UNICODE_STRING VolumeGuidPath;
260
261
262 //
263 // A pointer to the VPB for the volume passed in by the I/O system on
264 // a mount.
265 //
266
267 PVPB Vpb;
268
269 //
270 // The internal state of the device. This is a collection of fsd device
271 // state flags.
272 //
273
274 ULONG VcbState;
275 VCB_CONDITION VcbCondition;
276
277 //
278 // A pointer to the root DCB for this volume
279 //
280
281 struct _FCB *RootDcb;
282
283 //
284 // If the FAT has so many entries that the free cluster bitmap would
285 // be too large, we split the FAT into buckets, and only one bucket's
286 // worth of bits are kept in the bitmap.
287 //
288
289 ULONG NumberOfWindows;
290 PFAT_WINDOW Windows;
291 PFAT_WINDOW CurrentWindow;
292
293 //
294 // A count of the number of file objects that have opened the volume
295 // for direct access, and their share access state.
296 //
297
298 CLONG DirectAccessOpenCount;
299 SHARE_ACCESS ShareAccess;
300
301 //
302 // A count of the number of file objects that have any file/directory
303 // opened on this volume, not including direct access. And also the
304 // count of the number of file objects that have a file opened for
305 // only read access (i.e., they cannot be modifying the disk).
306 //
307
308 CLONG OpenFileCount;
309 CLONG ReadOnlyCount;
310
311 //
312 // A count of the number of internal opens on this VCB.
313 //
314
315 __volatile ULONG InternalOpenCount;
316
317 //
318 // A count of the number of residual opens on this volume.
319 // This is usually two or three. One is for the virutal volume
320 // file. One is for the root directory. And one is for the
321 // EA file, if there is one.
322 //
323
324 __volatile ULONG ResidualOpenCount;
325
326 //
327 // The bios parameter block field contains
328 // an unpacked copy of the bpb for the volume, it is initialized
329 // during mount time and can be read by everyone else after that.
330 //
331
332 BIOS_PARAMETER_BLOCK Bpb;
333
334 PUCHAR First0x24BytesOfBootSector;
335
336 //
337 // The following structure contains information useful to the
338 // allocation support routines. Many of them are computed from
339 // elements of the Bpb, but are too involved to recompute every time
340 // they are needed.
341 //
342
343 struct {
344
345 LBO RootDirectoryLbo; // Lbo of beginning of root directory
346 LBO FileAreaLbo; // Lbo of beginning of file area
347 ULONG RootDirectorySize; // size of root directory in bytes
348
349 ULONG NumberOfClusters; // total number of clusters on the volume
350 ULONG NumberOfFreeClusters; // number of free clusters on the volume
351
352
353 UCHAR FatIndexBitSize; // indicates if 12, 16, or 32 bit fat table
354
355 UCHAR LogOfBytesPerSector; // Log(Bios->BytesPerSector)
356 UCHAR LogOfBytesPerCluster; // Log(Bios->SectorsPerCluster)
357
358 } AllocationSupport;
359
360 //
361 // The following Mcb is used to keep track of dirty sectors in the Fat.
362 // Runs of holes denote clean sectors while runs of LBO == VBO denote
363 // dirty sectors. The VBOs are that of the volume file, starting at
364 // 0. The granuality of dirt is one sectors, and additions are only
365 // made in sector chunks to prevent problems with several simultaneous
366 // updaters.
367 //
368
369 LARGE_MCB DirtyFatMcb;
370
371 //
372 // The following MCB contains a list of all the bad clusters on the volume.
373 // It is empty until the first time the bad sectors on the volume are queried
374 // by calling FSCTL_GET_RETRIEVAL_POINTERS with a volume handle.
375 //
376
377 LARGE_MCB BadBlockMcb;
378
379 //
380 // The FreeClusterBitMap keeps track of all the clusters in the fat.
381 // A 1 means occupied while a 0 means free. It allows quick location
382 // of contiguous runs of free clusters. It is initialized on mount
383 // or verify.
384 //
385
386 RTL_BITMAP FreeClusterBitMap;
387
388 //
389 // The following fast mutex controls access to the free cluster bit map
390 // and the buckets.
391 //
392
393 FAST_MUTEX FreeClusterBitMapMutex;
394
395 //
396 // A resource variable to control access to the volume specific data
397 // structures
398 //
399
400 ERESOURCE Resource;
401
402 //
403 // A resource to make sure no one changes the volume bitmap while
404 // you're using it. Only for volumes with NumberOfWindows > 1.
405 //
406
407 ERESOURCE ChangeBitMapResource;
408
409
410 //
411 // The following field points to the file object used to do I/O to
412 // the virtual volume file. The virtual volume file maps sectors
413 // 0 through the end of fat and is of a fixed size (determined during
414 // mount)
415 //
416
417 PFILE_OBJECT VirtualVolumeFile;
418
419 //
420 // The following field contains a record of special pointers used by
421 // MM and Cache to manipluate section objects. Note that the values
422 // are set outside of the file system. However the file system on an
423 // open/create will set the file object's SectionObject field to point
424 // to this field
425 //
426
427 SECTION_OBJECT_POINTERS SectionObjectPointers;
428
429 //
430 // The following fields is a hint cluster index used by the file system
431 // when allocating a new cluster.
432 //
433
434 ULONG ClusterHint;
435
436 //
437 // This field contains the "DeviceObject" that this volume is
438 // currently mounted on. Note Vcb->Vpb->RealDevice is constant.
439 //
440
441 PDEVICE_OBJECT CurrentDevice;
442
443 //
444 // This is a pointer to the file object and the Fcb which represent the ea data.
445 //
446
447 PFILE_OBJECT VirtualEaFile;
448 struct _FCB *EaFcb;
449
450 //
451 // The following field is a pointer to the file object that has the
452 // volume locked. if the VcbState has the locked flag set.
453 //
454
455 PFILE_OBJECT FileObjectWithVcbLocked;
456
457 //
458 // The following is the head of a list of notify Irps.
459 //
460
461 LIST_ENTRY DirNotifyList;
462
463 //
464 // The following is used to synchronize the dir notify list.
465 //
466
467 PNOTIFY_SYNC NotifySync;
468
469 //
470 // The following fast mutex is used to synchronize directory stream
471 // file object creation.
472 //
473
474 FAST_MUTEX DirectoryFileCreationMutex;
475
476 //
477 // This field holds the thread address of the current (or most recent
478 // depending on VcbState) thread doing a verify operation on this volume.
479 //
480
481 PKTHREAD VerifyThread;
482
483 //
484 // The following two structures are used for CleanVolume callbacks.
485 //
486
487 KDPC CleanVolumeDpc;
488 KTIMER CleanVolumeTimer;
489
490 //
491 // This field records the last time FatMarkVolumeDirty was called, and
492 // avoids excessive calls to push the CleanVolume forward in time.
493 //
494
495 LARGE_INTEGER LastFatMarkVolumeDirtyCall;
496
497 //
498 // The following fields holds a pointer to a struct which is used to
499 // hold performance counters.
500 //
501
502 struct _FILE_SYSTEM_STATISTICS *Statistics;
503
504 //
505 // The property tunneling cache for this volume
506 //
507
508 TUNNEL Tunnel;
509
510 //
511 // The media change count is returned by IOCTL_CHECK_VERIFY and
512 // is used to verify that no user-mode app has swallowed a media change
513 // notification. This is only meaningful for removable media.
514 //
515
516 ULONG ChangeCount;
517
518 //
519 // The device number of the underlying storage device.
520 //
521
522 ULONG DeviceNumber;
523
524 //
525 // Preallocated VPB for swapout, so we are not forced to consider
526 // must succeed pool.
527 //
528
529 PVPB SwapVpb;
530
531 //
532 // Per volume threading of the close queues.
533 //
534
535 LIST_ENTRY AsyncCloseList;
536 LIST_ENTRY DelayedCloseList;
537
538 //
539 // Fast mutex used by the ADVANCED FCB HEADER in this structure
540 //
541
542 FAST_MUTEX AdvancedFcbHeaderMutex;
543
544
545 //
546 // How many close contexts were preallocated on this Vcb
547 //
548 #if DBG
549 ULONG CloseContextCount;
550 #endif
551
552 } VCB;
553 typedef VCB *PVCB;
554
555 #define VCB_STATE_FLAG_LOCKED (0x00000001)
556 #define VCB_STATE_FLAG_REMOVABLE_MEDIA (0x00000002)
557 #define VCB_STATE_FLAG_VOLUME_DIRTY (0x00000004)
558 #define VCB_STATE_FLAG_MOUNTED_DIRTY (0x00000010)
559 #define VCB_STATE_FLAG_SHUTDOWN (0x00000040)
560 #define VCB_STATE_FLAG_CLOSE_IN_PROGRESS (0x00000080)
561 #define VCB_STATE_FLAG_DELETED_FCB (0x00000100)
562 #define VCB_STATE_FLAG_CREATE_IN_PROGRESS (0x00000200)
563 #define VCB_STATE_FLAG_BOOT_OR_PAGING_FILE (0x00000800)
564 #define VCB_STATE_FLAG_DEFERRED_FLUSH (0x00001000)
565 #define VCB_STATE_FLAG_ASYNC_CLOSE_ACTIVE (0x00002000)
566 #define VCB_STATE_FLAG_WRITE_PROTECTED (0x00004000)
567 #define VCB_STATE_FLAG_REMOVAL_PREVENTED (0x00008000)
568 #define VCB_STATE_FLAG_VOLUME_DISMOUNTED (0x00010000)
569 #define VCB_STATE_VPB_NOT_ON_DEVICE (0x00020000)
570 #define VCB_STATE_FLAG_VPB_MUST_BE_FREED (0x00040000)
571 #define VCB_STATE_FLAG_DISMOUNT_IN_PROGRESS (0x00080000)
572 #define VCB_STATE_FLAG_BAD_BLOCKS_POPULATED (0x00100000)
573 #define VCB_STATE_FLAG_HOTPLUGGABLE (0x00200000)
574 #define VCB_STATE_FLAG_MOUNT_IN_PROGRESS (0x00800000)
575
576
577 //
578 // N.B - VOLUME_DISMOUNTED is an indication that FSCTL_DISMOUNT volume was
579 // executed on a volume. It does not replace VcbCondition as an indication
580 // that the volume is invalid/unrecoverable.
581 //
582
583 //
584 // Define the file system statistics struct. Vcb->Statistics points to an
585 // array of these (one per processor) and they must be 64 byte aligned to
586 // prevent cache line tearing.
587 //
588
589 #define FILE_SYSTEM_STATISTICS_WITHOUT_PAD (sizeof( FILESYSTEM_STATISTICS ) + sizeof( FAT_STATISTICS ))
590
591 typedef struct _FILE_SYSTEM_STATISTICS {
592
593 //
594 // This contains the actual data.
595 //
596
597 FILESYSTEM_STATISTICS Common;
598 FAT_STATISTICS Fat;
599
600 //
601 // Pad this structure to a multiple of 64 bytes.
602 //
603
604 UCHAR Pad[((FILE_SYSTEM_STATISTICS_WITHOUT_PAD + 0x3f) & ~0x3f) - FILE_SYSTEM_STATISTICS_WITHOUT_PAD];
605
606 } FILE_SYSTEM_STATISTICS;
607
608 typedef FILE_SYSTEM_STATISTICS *PFILE_SYSTEM_STATISTICS;
609
610 \f
611 //
612 // The Volume Device Object is an I/O system device object with a workqueue
613 // and an VCB record appended to the end. There are multiple of these
614 // records, one for every mounted volume, and are created during
615 // a volume mount operation. The work queue is for handling an overload of
616 // work requests to the volume.
617 //
618
619 typedef struct _VOLUME_DEVICE_OBJECT {
620
621 DEVICE_OBJECT DeviceObject;
622
623 //
624 // The following field tells how many requests for this volume have
625 // either been enqueued to ExWorker threads or are currently being
626 // serviced by ExWorker threads. If the number goes above
627 // a certain threshold, put the request on the overflow queue to be
628 // executed later.
629 //
630
631 ULONG PostedRequestCount;
632
633 //
634 // The following field indicates the number of IRP's waiting
635 // to be serviced in the overflow queue.
636 //
637
638 ULONG OverflowQueueCount;
639
640 //
641 // The following field contains the queue header of the overflow queue.
642 // The Overflow queue is a list of IRP's linked via the IRP's ListEntry
643 // field.
644 //
645
646 LIST_ENTRY OverflowQueue;
647
648 //
649 // The following spinlock protects access to all the above fields.
650 //
651
652 KSPIN_LOCK OverflowQueueSpinLock;
653
654 //
655 // This is a common head for the FAT volume file
656 //
657
658 FSRTL_COMMON_FCB_HEADER VolumeFileHeader;
659
660 //
661 // This is the file system specific volume control block.
662 //
663
664 VCB Vcb;
665
666 } VOLUME_DEVICE_OBJECT;
667
668 typedef VOLUME_DEVICE_OBJECT *PVOLUME_DEVICE_OBJECT;
669
670 \f
671 //
672 // This is the structure used to contains the short name for a file
673 //
674
675 typedef struct _FILE_NAME_NODE {
676
677 //
678 // This points back to the Fcb for this file.
679 //
680
681 struct _FCB *Fcb;
682
683 //
684 // This is the name of this node.
685 //
686
687 union {
688
689 OEM_STRING Oem;
690
691 UNICODE_STRING Unicode;
692
693 } Name;
694
695 //
696 // Marker so we can figure out what kind of name we opened up in
697 // Fcb searches
698 //
699
700 BOOLEAN FileNameDos;
701
702 //
703 // And the links. Our parent Dcb has a pointer to the root entry.
704 //
705
706 RTL_SPLAY_LINKS Links;
707
708 } FILE_NAME_NODE;
709 typedef FILE_NAME_NODE *PFILE_NAME_NODE;
710
711 //
712 // This structure contains fields which must be in non-paged pool.
713 //
714
715 typedef struct _NON_PAGED_FCB {
716
717 //
718 // The following field contains a record of special pointers used by
719 // MM and Cache to manipluate section objects. Note that the values
720 // are set outside of the file system. However the file system on an
721 // open/create will set the file object's SectionObject field to point
722 // to this field
723 //
724
725 SECTION_OBJECT_POINTERS SectionObjectPointers;
726
727 //
728 // This context is non-zero only if the file currently has asynchronous
729 // non-cached valid data length extending writes. It allows
730 // synchronization between pending writes and other operations.
731 //
732
733 ULONG OutstandingAsyncWrites;
734
735 //
736 // This event is set when OutstandingAsyncWrites transitions to zero.
737 //
738
739 PKEVENT OutstandingAsyncEvent;
740
741 //
742 // This is the mutex that is inserted into the FCB_ADVANCED_HEADER
743 // FastMutex field
744 //
745
746 FAST_MUTEX AdvancedFcbHeaderMutex;
747
748
749 } NON_PAGED_FCB;
750
751 typedef NON_PAGED_FCB *PNON_PAGED_FCB;
752
753 //
754 // The Fcb/Dcb record corresponds to every open file and directory, and to
755 // every directory on an opened path. They are ordered in two queues, one
756 // queue contains every Fcb/Dcb record off of FatData.FcbQueue, the other
757 // queue contains only device specific records off of Vcb.VcbSpecificFcbQueue
758 //
759
760 typedef enum _FCB_CONDITION {
761 FcbGood = 1,
762 FcbBad,
763 FcbNeedsToBeVerified
764 } FCB_CONDITION;
765
766 typedef struct _FCB {
767
768 //
769 // The following field is used for fast I/O
770 //
771 // The following comments refer to the use of the AllocationSize field
772 // of the FsRtl-defined header to the nonpaged Fcb.
773 //
774 // For a directory when we create a Dcb we will not immediately
775 // initialize the cache map, instead we will postpone it until our first
776 // call to FatReadDirectoryFile or FatPrepareWriteDirectoryFile.
777 // At that time we will search the Fat to find out the current allocation
778 // size (by calling FatLookupFileAllocationSize) and then initialize the
779 // cache map to this allocation size.
780 //
781 // For a file when we create an Fcb we will not immediately initialize
782 // the cache map, instead we will postpone it until we need it and
783 // then we determine the allocation size from either searching the
784 // fat to determine the real file allocation, or from the allocation
785 // that we've just allocated if we're creating a file.
786 //
787 // A value of -1 indicates that we do not know what the current allocation
788 // size really is, and need to examine the fat to find it. A value
789 // of than -1 is the real file/directory allocation size.
790 //
791 // Whenever we need to extend the allocation size we call
792 // FatAddFileAllocation which (if we're really extending the allocation)
793 // will modify the Fat, Mcb, and update this field. The caller
794 // of FatAddFileAllocation is then responsible for altering the Cache
795 // map size.
796 //
797 // We are now using the ADVANCED fcb header to support filter contexts
798 // at the stream level
799 //
800
801 FSRTL_ADVANCED_FCB_HEADER Header;
802
803 //
804 // This structure contains fields which must be in non-paged pool.
805 //
806
807 PNON_PAGED_FCB NonPaged;
808
809 //
810 // The head of the fat alloaction chain. FirstClusterOfFile == 0
811 // means that the file has no current allocation.
812 //
813
814 ULONG FirstClusterOfFile;
815
816
817 //
818 // The links for the queue of all fcbs for a specific dcb off of
819 // Dcb.ParentDcbQueue. For the root directory this queue is empty
820 // For a non-existent fcb this queue is off of the non existent
821 // fcb queue entry in the vcb.
822 //
823
824 LIST_ENTRY ParentDcbLinks;
825
826 //
827 // A pointer to the Dcb that is the parent directory containing
828 // this fcb. If this record itself is the root dcb then this field
829 // is null.
830 //
831
832 struct _FCB *ParentDcb;
833
834 //
835 // A pointer to the Vcb containing this Fcb
836 //
837
838 PVCB Vcb;
839
840 //
841 // The internal state of the Fcb. This is a collection Fcb state flags.
842 // Also the shared access for each time this file/directory is opened.
843 //
844
845 ULONG FcbState;
846 FCB_CONDITION FcbCondition;
847 SHARE_ACCESS ShareAccess;
848
849 #ifdef SYSCACHE_COMPILE
850
851 //
852 // For syscache we keep a bitmask that tells us if we have dispatched IO for
853 // the page aligned chunks of the stream.
854 //
855
856 PULONG WriteMask;
857 ULONG WriteMaskData;
858
859 #endif
860
861 //
862 // A count of the number of file objects that have been opened for
863 // this file/directory, but not yet been cleaned up yet. This count
864 // is only used for data file objects, not for the Acl or Ea stream
865 // file objects. This count gets decremented in FatCommonCleanup,
866 // while the OpenCount below gets decremented in FatCommonClose.
867 //
868
869 CLONG UncleanCount;
870
871 //
872 // A count of the number of file objects that have opened
873 // this file/directory. For files & directories the FsContext of the
874 // file object points to this record.
875 //
876
877 CLONG OpenCount;
878
879 //
880 // A count of how many of "UncleanCount" handles were opened for
881 // non-cached I/O.
882 //
883
884 CLONG NonCachedUncleanCount;
885
886 //
887 // A count of purge failure mode references. A non zero count means
888 // purge failure mode is enabled. The count is synchronized by the
889 // Fcb.
890 //
891
892 CLONG PurgeFailureModeEnableCount;
893
894 //
895 // The following field is used to locate the dirent for this fcb/dcb.
896 // All directory are opened as mapped files so the only additional
897 // information we need to locate this dirent (beside its parent directory)
898 // is the byte offset for the dirent. Note that for the root dcb
899 // this field is not used.
900 //
901
902 VBO DirentOffsetWithinDirectory;
903
904 //
905 // The following field is filled in when there is an Lfn associated
906 // with this file. It is the STARTING offset of the Lfn.
907 //
908
909 VBO LfnOffsetWithinDirectory;
910
911 //
912 // Thess entries is kept in ssync with the dirent. It allows a more
913 // accurate verify capability and speeds up FatFastQueryBasicInfo().
914 //
915
916 LARGE_INTEGER CreationTime;
917 LARGE_INTEGER LastAccessTime;
918 LARGE_INTEGER LastWriteTime;
919
920 //
921 // Valid data to disk
922 //
923
924 ULONG ValidDataToDisk;
925
926 //
927 // The following field contains the retrieval mapping structure
928 // for the file/directory. Note that for the Root Dcb this
929 // structure is set at mount time. Also note that in this
930 // implementation of Fat the Mcb really maps VBOs to LBOs and not
931 // VBNs to LBNs.
932 //
933
934 LARGE_MCB Mcb;
935
936 //
937 // The following union is cased off of the node type code for the fcb.
938 // There is a seperate case for the directory versus file fcbs.
939 //
940
941 union {
942
943 //
944 // A Directory Control Block (Dcb)
945 //
946
947 struct {
948
949 //
950 // A queue of all the fcbs/dcbs that are opened under this
951 // Dcb.
952 //
953
954 LIST_ENTRY ParentDcbQueue;
955
956 //
957 // The following field points to the file object used to do I/O to
958 // the directory file for this dcb. The directory file maps the
959 // sectors for the directory. This field is initialized by
960 // CreateRootDcb but is left null by CreateDcb. It isn't
961 // until we try to read/write the directory file that we
962 // create the stream file object for non root dcbs.
963 //
964
965 __volatile ULONG DirectoryFileOpenCount;
966 PFILE_OBJECT DirectoryFile;
967
968
969 //
970 // If the UnusedDirentVbo is != 0xffffffff, then the dirent at this
971 // offset is guarenteed to unused. A value of 0xffffffff means
972 // it has yet to be initialized. Note that a value beyond the
973 // end of allocation means that there an unused dirent, but we
974 // will have to allocate another cluster to use it.
975 //
976 // DeletedDirentHint contains lowest possible VBO of a deleted
977 // dirent (assuming as above that it is not 0xffffffff).
978 //
979
980 VBO UnusedDirentVbo;
981 VBO DeletedDirentHint;
982
983 //
984 // The following two entries links together all the Fcbs
985 // opened under this Dcb sorted in a splay tree by name.
986 //
987 // I'd like to go into why we have (and must have) two separate
988 // splay trees within the current fastfat architecture. I will
989 // provide some insight into what would have to change if we
990 // wanted to have a single UNICODE tree.
991 //
992 // What makes FAT unique is that both Oem and Unicode names sit
993 // side by side on disk. Several unique UNICODE names coming
994 // into fastfat can match a single OEM on-disk name, and there
995 // is really no way to enumerate all the possible UNICODE
996 // source strings that can map to a given OEM name. This argues
997 // for converting the incomming UNICODE name into OEM, and then
998 // running through an OEM splay tree of the open files. This
999 // works well when there are only OEM names on disk.
1000 //
1001 // The UNICODE name on disk can be VERY different from the short
1002 // name in the DIRENT and not even representable in the OEM code
1003 // page. Even if it were representable in OEM, it is possible
1004 // that a case varient of the original UNICODE name would match
1005 // a different OEM name, causing us to miss the Fcb in the
1006 // prefix lookup phase. In these cases, we must put UNICODE
1007 // name in the splay to guarentee that we find any case varient
1008 // of the input UNICODE name. See the routine description of
1009 // FatConstructNamesInFcb() for a detailed analysis of how we
1010 // detect this case.
1011 //
1012 // The fundamental limitation we are imposing here is that if
1013 // an Fcb exists for an open file, we MUST find it during the
1014 // prefix stage. This is a basic premise of the create path
1015 // in fastfat. In fact if we later find it gravelling through
1016 // the disk (but not the splay tree), we will bug check if we
1017 // try to add a duplicate entry to the splay tree (not to
1018 // mention having two Fcbs). If we had some mechanism to deal
1019 // with cases (and they would be rare) that we don't find the
1020 // entry in the splay tree, but the Fcb is actually in there,
1021 // then we could go to a single UNICODE splay tree. While
1022 // this uses more pool for the splay tree, and makes string
1023 // compares maybe take a bit as longer, it would eliminate the
1024 // need for any NLS conversion during the prefix phase, so it
1025 // might really be a net win.
1026 //
1027 // The current scheme was optimized for non-extended names
1028 // (i.e. US names). As soon as you start using extended
1029 // characters, then it is clearly a win as many code paths
1030 // become active that would otherwise not be needed if we
1031 // only had a single UNICODE splay tree.
1032 //
1033 // We may think about changing this someday.
1034 //
1035
1036 PRTL_SPLAY_LINKS RootOemNode;
1037 PRTL_SPLAY_LINKS RootUnicodeNode;
1038
1039 //
1040 // The following field keeps track of free dirents, i.e.,
1041 // dirents that are either unallocated for deleted.
1042 //
1043
1044 RTL_BITMAP FreeDirentBitmap;
1045
1046 //
1047 // Since the FCB specific part of this union is larger, use
1048 // the slack here for an initial bitmap buffer. Currently
1049 // there is enough space here for an 8K cluster.
1050 //
1051
1052 ULONG FreeDirentBitmapBuffer[1];
1053
1054 } Dcb;
1055
1056 //
1057 // A File Control Block (Fcb)
1058 //
1059
1060 struct {
1061
1062 //
1063 // The following field is used by the filelock module
1064 // to maintain current byte range locking information.
1065 //
1066
1067 FILE_LOCK FileLock;
1068
1069 #if (NTDDI_VERSION < NTDDI_WIN8)
1070 //
1071 // The following field is used by the oplock module
1072 // to maintain current oplock information.
1073 //
1074
1075 OPLOCK Oplock;
1076 #endif
1077
1078 //
1079 // This pointer is used to detect writes that eminated in the
1080 // cache manager's lazywriter. It prevents lazy writer threads,
1081 // who already have the Fcb shared, from trying to acquire it
1082 // exclusive, and thus causing a deadlock.
1083 //
1084
1085 PVOID LazyWriteThread;
1086
1087
1088 } Fcb;
1089
1090 } Specific;
1091
1092 //
1093 // The following field is used to verify that the Ea's for a file
1094 // have not changed between calls to query for Ea's. It is compared
1095 // with a similar field in a Ccb.
1096 //
1097 // IMPORTANT!! **** DO NOT MOVE THIS FIELD ****
1098 //
1099 // The slack space in the union above is computed from
1100 // the field offset of the EaModificationCount.
1101 //
1102
1103 ULONG EaModificationCount;
1104
1105 //
1106 // The following field is the fully qualified file name for this FCB/DCB
1107 // starting from the root of the volume, and last file name in the
1108 // fully qualified name.
1109 //
1110
1111 FILE_NAME_NODE ShortName;
1112
1113 //
1114 // The following field is only filled in if it is needed with the user's
1115 // opened path
1116 //
1117
1118 UNICODE_STRING FullFileName;
1119
1120 USHORT FinalNameLength;
1121
1122 //
1123 // To make life simpler we also keep in the Fcb/Dcb a current copy of
1124 // the fat attribute byte for the file/directory. This field must
1125 // also be updated when we create the Fcb, modify the File, or verify
1126 // the Fcb
1127 //
1128
1129 UCHAR DirentFatFlags;
1130
1131 //
1132 // The case preserved long filename
1133 //
1134
1135 UNICODE_STRING ExactCaseLongName;
1136
1137 //
1138 // If the UNICODE Lfn is fully expressible in the system Oem code
1139 // page, then we will store it in a prefix table, otherwise we will
1140 // store the last UNICODE name in the Fcb. In both cases the name
1141 // has been upcased.
1142 //
1143 // Note that we may need neither of these fields if an LFN was strict
1144 // 8.3 or differed only in case. Indeed if there wasn't an LFN, we
1145 // don't need them at all.
1146 //
1147
1148 union {
1149
1150 //
1151 // This first field is present if FCB_STATE_HAS_OEM_LONG_NAME
1152 // is set in the FcbState.
1153 //
1154
1155 FILE_NAME_NODE Oem;
1156
1157 //
1158 // This first field is present if FCB_STATE_HAS_UNICODE_LONG_NAME
1159 // is set in the FcbState.
1160 //
1161
1162 FILE_NAME_NODE Unicode;
1163
1164 } LongName;
1165
1166 //
1167 // Defragmentation / ReallocateOnWrite synchronization object. This
1168 // is filled in by FatMoveFile() and affects the read and write paths.
1169 //
1170
1171 PKEVENT MoveFileEvent;
1172
1173 } FCB, *PFCB;
1174
1175 #ifndef BUILDING_FSKDEXT
1176 //
1177 // DCB clashes with a type defined outside the filesystems, in headers
1178 // pulled in by FSKD. We don't need this typedef for fskd anyway....
1179 //
1180 typedef FCB DCB;
1181 typedef DCB *PDCB;
1182 #endif
1183
1184
1185 //
1186 // Here are the Fcb state fields.
1187 //
1188
1189 #define FCB_STATE_DELETE_ON_CLOSE (0x00000001)
1190 #define FCB_STATE_TRUNCATE_ON_CLOSE (0x00000002)
1191 #define FCB_STATE_PAGING_FILE (0x00000004)
1192 #define FCB_STATE_FORCE_MISS_IN_PROGRESS (0x00000008)
1193 #define FCB_STATE_FLUSH_FAT (0x00000010)
1194 #define FCB_STATE_TEMPORARY (0x00000020)
1195 #define FCB_STATE_SYSTEM_FILE (0x00000080)
1196 #define FCB_STATE_NAMES_IN_SPLAY_TREE (0x00000100)
1197 #define FCB_STATE_HAS_OEM_LONG_NAME (0x00000200)
1198 #define FCB_STATE_HAS_UNICODE_LONG_NAME (0x00000400)
1199 #define FCB_STATE_DELAY_CLOSE (0x00000800)
1200
1201 //
1202 // Copies of the dirent's FAT_DIRENT_NT_BYTE_* flags for
1203 // preserving case of the short name of a file
1204 //
1205
1206 #define FCB_STATE_8_LOWER_CASE (0x00001000)
1207 #define FCB_STATE_3_LOWER_CASE (0x00002000)
1208
1209 //
1210 // indicates FSCTL_MOVE_FILE is denied on this FCB
1211 //
1212
1213 #define FCB_STATE_DENY_DEFRAG (0x00004000)
1214
1215
1216 //
1217 // Flag to indicate we should zero any deallocations from this file.
1218 //
1219
1220 #define FCB_STATE_ZERO_ON_DEALLOCATION (0x00080000)
1221
1222 //
1223 // This is the slack allocation in the Dcb part of the UNION above
1224 //
1225
1226 #define DCB_UNION_SLACK_SPACE ((ULONG) \
1227 (FIELD_OFFSET(DCB, EaModificationCount) - \
1228 FIELD_OFFSET(DCB, Specific.Dcb.FreeDirentBitmapBuffer)) \
1229 )
1230
1231 //
1232 // This is the special (64bit) allocation size that indicates the
1233 // real size must be retrieved from disk. Define it here so we
1234 // avoid excessive magic numbering around the driver.
1235 //
1236
1237 #define FCB_LOOKUP_ALLOCATIONSIZE_HINT ((LONGLONG) -1)
1238
1239 \f
1240 //
1241 // The Ccb record is allocated for every file object. Note that this
1242 // record is exactly 0x34 long on x86 so that it will fit into a 0x40
1243 // piece of pool. Please carefully consider modifications.
1244 //
1245 // Define the Flags field.
1246 //
1247
1248 #define CCB_FLAG_MATCH_ALL (0x0001)
1249 #define CCB_FLAG_SKIP_SHORT_NAME_COMPARE (0x0002)
1250
1251 //
1252 // This tells us whether we allocated buffers to hold search templates.
1253 //
1254
1255 #define CCB_FLAG_FREE_OEM_BEST_FIT (0x0004)
1256 #define CCB_FLAG_FREE_UNICODE (0x0008)
1257
1258 //
1259 // These flags prevents cleanup from updating the modify time, etc.
1260 //
1261
1262 #define CCB_FLAG_USER_SET_LAST_WRITE (0x0010)
1263 #define CCB_FLAG_USER_SET_LAST_ACCESS (0x0020)
1264 #define CCB_FLAG_USER_SET_CREATION (0x0040)
1265
1266 //
1267 // This bit says the file object associated with this Ccb was opened for
1268 // read only access.
1269 //
1270
1271 #define CCB_FLAG_READ_ONLY (0x0080)
1272
1273 //
1274 // These flags, are used is DASD handles in read and write.
1275 //
1276
1277 #define CCB_FLAG_DASD_FLUSH_DONE (0x0100)
1278 #define CCB_FLAG_DASD_PURGE_DONE (0x0200)
1279
1280 //
1281 // This flag keeps track of a handle that was opened for
1282 // DELETE_ON_CLOSE.
1283 //
1284
1285 #define CCB_FLAG_DELETE_ON_CLOSE (0x0400)
1286
1287 //
1288 // This flag keeps track of which side of the name pair on the file
1289 // associated with the handle was opened
1290 //
1291
1292 #define CCB_FLAG_OPENED_BY_SHORTNAME (0x0800)
1293
1294 //
1295 // This flag indicates that the query template has not been upcased
1296 // (i.e., query should be case-insensitive)
1297 //
1298
1299 #define CCB_FLAG_QUERY_TEMPLATE_MIXED (0x1000)
1300
1301 //
1302 // This flag indicates that reads and writes via this DASD handle
1303 // are allowed to start or extend past the end of file.
1304 //
1305
1306 #define CCB_FLAG_ALLOW_EXTENDED_DASD_IO (0x2000)
1307
1308 //
1309 // This flag indicates we want to match volume labels in directory
1310 // searches (important for the root dir defrag).
1311 //
1312
1313 #define CCB_FLAG_MATCH_VOLUME_ID (0x4000)
1314
1315 //
1316 // This flag indicates the ccb has been converted over into a
1317 // close context for asynchronous/delayed closing of the handle.
1318 //
1319
1320 #define CCB_FLAG_CLOSE_CONTEXT (0x8000)
1321
1322 //
1323 // This flag indicates that when the handle is closed, we want
1324 // a physical dismount to occur.
1325 //
1326
1327 #define CCB_FLAG_COMPLETE_DISMOUNT (0x10000)
1328
1329 //
1330 // This flag indicates the handle may not call priveleged
1331 // FSCTL which modify the volume.
1332 //
1333
1334 #define CCB_FLAG_MANAGE_VOLUME_ACCESS (0x20000)
1335
1336 //
1337 // This flag indicates that a format unit commmand was issued
1338 // on this handle and all subsequent writes need to ignore verify.
1339 //
1340
1341 #define CCB_FLAG_SENT_FORMAT_UNIT (0x40000)
1342
1343 //
1344 // This flag indicates that this CCB was the one that marked the
1345 // handle as non-movable.
1346 //
1347
1348 #define CCB_FLAG_DENY_DEFRAG (0x80000)
1349
1350 //
1351 // This flag indicates that this CCB wrote to the file.
1352 //
1353
1354 #define CCB_FLAG_FIRST_WRITE_SEEN (0x100000)
1355
1356 typedef struct _CCB {
1357
1358 //
1359 // Type and size of this record (must be FAT_NTC_CCB)
1360 //
1361
1362 NODE_TYPE_CODE NodeTypeCode;
1363 NODE_BYTE_SIZE NodeByteSize;
1364
1365 //
1366 // Define a 24bit wide field for Flags, but a UCHAR for Wild Cards Present
1367 // since it is used so often. Line these up on byte boundaries for grins.
1368 //
1369
1370 ULONG Flags:24;
1371 BOOLEAN ContainsWildCards;
1372
1373 //
1374 // Pointer to EDP context.
1375 //
1376
1377 PVOID EncryptionOnCloseContext;
1378
1379 //
1380 // Overlay a close context on the data of the CCB. The remaining
1381 // fields are not useful during close, and we would like to avoid
1382 // paying extra pool for it.
1383 //
1384
1385 union {
1386
1387 struct {
1388
1389 //
1390 // Save the offset to start search from.
1391 //
1392
1393 VBO OffsetToStartSearchFrom;
1394
1395 //
1396 // The query template is used to filter directory query requests.
1397 // It originally is set to null and on the first call the NtQueryDirectory
1398 // it is set to the input filename or "*" if the name is not supplied.
1399 // All subsquent queries then use this template.
1400 //
1401 // The Oem structure are unions because if the name is wild we store
1402 // the arbitrary length string, while if the name is constant we store
1403 // 8.3 representation for fast comparison.
1404 //
1405
1406 union {
1407
1408 //
1409 // If the template contains a wild card use this.
1410 //
1411
1412 OEM_STRING Wild;
1413
1414 //
1415 // If the name is constant, use this part.
1416 //
1417
1418 FAT8DOT3 Constant;
1419
1420 } OemQueryTemplate;
1421
1422 UNICODE_STRING UnicodeQueryTemplate;
1423
1424 //
1425 // The field is compared with the similar field in the Fcb to determine
1426 // if the Ea's for a file have been modified.
1427 //
1428
1429 ULONG EaModificationCount;
1430
1431 //
1432 // The following field is used as an offset into the Eas for a
1433 // particular file. This will be the offset for the next
1434 // Ea to return. A value of 0xffffffff indicates that the
1435 // Ea's are exhausted.
1436 //
1437
1438 ULONG OffsetOfNextEaToReturn;
1439
1440 };
1441
1442 CLOSE_CONTEXT CloseContext;
1443 };
1444
1445 } CCB;
1446 typedef CCB *PCCB;
1447 \f
1448 //
1449 // The Irp Context record is allocated for every orginating Irp. It is
1450 // created by the Fsd dispatch routines, and deallocated by the FatComplete
1451 // request routine. It contains a structure called of type REPINNED_BCBS
1452 // which is used to retain pinned bcbs needed to handle abnormal termination
1453 // unwinding.
1454 //
1455
1456 #define REPINNED_BCBS_ARRAY_SIZE (4)
1457
1458 typedef struct _REPINNED_BCBS {
1459
1460 //
1461 // A pointer to the next structure contains additional repinned bcbs
1462 //
1463
1464 struct _REPINNED_BCBS *Next;
1465
1466 //
1467 // A fixed size array of pinned bcbs. Whenever a new bcb is added to
1468 // the repinned bcb structure it is added to this array. If the
1469 // array is already full then another repinned bcb structure is allocated
1470 // and pointed to with Next.
1471 //
1472
1473 PBCB Bcb[ REPINNED_BCBS_ARRAY_SIZE ];
1474
1475 } REPINNED_BCBS;
1476 typedef REPINNED_BCBS *PREPINNED_BCBS;
1477
1478 typedef struct _IRP_CONTEXT {
1479
1480 //
1481 // Type and size of this record (must be FAT_NTC_IRP_CONTEXT)
1482 //
1483
1484 NODE_TYPE_CODE NodeTypeCode;
1485 NODE_BYTE_SIZE NodeByteSize;
1486
1487 //
1488 // This structure is used for posting to the Ex worker threads.
1489 //
1490
1491 WORK_QUEUE_ITEM WorkQueueItem;
1492
1493 //
1494 // A pointer to the originating Irp.
1495 //
1496
1497 PIRP OriginatingIrp;
1498
1499 //
1500 // Originating Device (required for workque algorithms)
1501 //
1502
1503 PDEVICE_OBJECT RealDevice;
1504
1505 //
1506 // Originating Vcb (required for exception handling)
1507 // On mounts, this will be set before any exceptions
1508 // indicating corruption can be thrown.
1509 //
1510
1511 PVCB Vcb;
1512
1513 //
1514 // Major and minor function codes copied from the Irp
1515 //
1516
1517 UCHAR MajorFunction;
1518 UCHAR MinorFunction;
1519
1520 //
1521 // The following fields indicate if we can wait/block for a resource
1522 // or I/O, if we are to do everything write through, and if this
1523 // entry into the Fsd is a recursive call.
1524 //
1525
1526 UCHAR PinCount;
1527
1528 ULONG Flags;
1529
1530 //
1531 // The following field contains the NTSTATUS value used when we are
1532 // unwinding due to an exception
1533 //
1534
1535 NTSTATUS ExceptionStatus;
1536
1537 //
1538 // The following context block is used for non-cached Io
1539 //
1540
1541 struct _FAT_IO_CONTEXT *FatIoContext;
1542
1543 //
1544 // For a abnormal termination unwinding this field contains the Bcbs
1545 // that are kept pinned until the Irp is completed.
1546 //
1547
1548 REPINNED_BCBS Repinned;
1549
1550
1551 } IRP_CONTEXT;
1552 typedef IRP_CONTEXT *PIRP_CONTEXT;
1553
1554 #define IRP_CONTEXT_FLAG_DISABLE_DIRTY (0x00000001)
1555 #define IRP_CONTEXT_FLAG_WAIT (0x00000002)
1556 #define IRP_CONTEXT_FLAG_WRITE_THROUGH (0x00000004)
1557 #define IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH (0x00000008)
1558 #define IRP_CONTEXT_FLAG_RECURSIVE_CALL (0x00000010)
1559 #define IRP_CONTEXT_FLAG_DISABLE_POPUPS (0x00000020)
1560 #define IRP_CONTEXT_FLAG_DEFERRED_WRITE (0x00000040)
1561 #define IRP_CONTEXT_FLAG_VERIFY_READ (0x00000080)
1562 #define IRP_CONTEXT_STACK_IO_CONTEXT (0x00000100)
1563 #define IRP_CONTEXT_FLAG_IN_FSP (0x00000200)
1564 #define IRP_CONTEXT_FLAG_USER_IO (0x00000400) // for performance counters
1565 #define IRP_CONTEXT_FLAG_DISABLE_RAISE (0x00000800)
1566 #define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY (0x00001000)
1567 #define IRP_CONTEXT_FLAG_CLEANUP_BREAKING_OPLOCK (0x00002000)
1568
1569
1570 #if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
1571 #define IRP_CONTEXT_FLAG_SWAPPED_STACK (0x00100000)
1572 #endif
1573
1574 #define IRP_CONTEXT_FLAG_PARENT_BY_CHILD (0x80000000)
1575
1576 \f
1577 //
1578 // Context structure for non-cached I/O calls. Most of these fields
1579 // are actually only required for the Read/Write Multiple routines, but
1580 // the caller must allocate one as a local variable anyway before knowing
1581 // whether there are multiple requests are not. Therefore, a single
1582 // structure is used for simplicity.
1583 //
1584
1585 typedef struct _FAT_IO_CONTEXT {
1586
1587 //
1588 // A copy of the IrpContext flags preserved for use in
1589 // async I/O completion.
1590 //
1591
1592 ULONG IrpContextFlags;
1593
1594 //
1595 // These two field are used for multiple run Io
1596 //
1597
1598 __volatile LONG IrpCount;
1599 PIRP MasterIrp;
1600
1601 //
1602 // MDL to describe partial sector zeroing
1603 //
1604
1605 PMDL ZeroMdl;
1606
1607 union {
1608
1609 //
1610 // This element handles the asychronous non-cached Io
1611 //
1612
1613 struct {
1614 PERESOURCE Resource;
1615 PERESOURCE Resource2;
1616 ERESOURCE_THREAD ResourceThreadId;
1617 ULONG RequestedByteCount;
1618 PFILE_OBJECT FileObject;
1619 PNON_PAGED_FCB NonPagedFcb;
1620 } Async;
1621
1622 //
1623 // and this element the sycnrhonous non-cached Io
1624 //
1625
1626 KEVENT SyncEvent;
1627
1628 } Wait;
1629
1630
1631 } FAT_IO_CONTEXT;
1632
1633 typedef FAT_IO_CONTEXT *PFAT_IO_CONTEXT;
1634
1635 //
1636 // An array of these structures is passed to FatMultipleAsync describing
1637 // a set of runs to execute in parallel.
1638 //
1639
1640 typedef struct _IO_RUNS {
1641
1642 LBO Lbo;
1643 VBO Vbo;
1644 ULONG Offset;
1645 ULONG ByteCount;
1646 PIRP SavedIrp;
1647
1648 } IO_RUN;
1649
1650 typedef IO_RUN *PIO_RUN;
1651
1652 //
1653 // This structure is used by FatDeleteDirent to preserve the first cluster
1654 // and file size info for undelete utilities.
1655 //
1656
1657 typedef struct _DELETE_CONTEXT {
1658
1659 ULONG FileSize;
1660 ULONG FirstClusterOfFile;
1661
1662 } DELETE_CONTEXT;
1663
1664 typedef DELETE_CONTEXT *PDELETE_CONTEXT;
1665
1666 //
1667 // This record is used with to set a flush to go off one second after the
1668 // first write on slow devices with a physical indication of activity, like
1669 // a floppy. This is an attempt to keep the red light on.
1670 //
1671
1672 typedef struct _DEFERRED_FLUSH_CONTEXT {
1673
1674 KDPC Dpc;
1675 KTIMER Timer;
1676 WORK_QUEUE_ITEM Item;
1677
1678 PFILE_OBJECT File;
1679
1680 } DEFERRED_FLUSH_CONTEXT;
1681
1682 typedef DEFERRED_FLUSH_CONTEXT *PDEFERRED_FLUSH_CONTEXT;
1683
1684 //
1685 // This structure is used for the FatMarkVolumeClean callbacks.
1686 //
1687
1688 typedef struct _CLEAN_AND_DIRTY_VOLUME_PACKET {
1689
1690 WORK_QUEUE_ITEM Item;
1691 PIRP Irp;
1692 PVCB Vcb;
1693 PKEVENT Event;
1694 } CLEAN_AND_DIRTY_VOLUME_PACKET, *PCLEAN_AND_DIRTY_VOLUME_PACKET;
1695
1696 //
1697 // This structure is used when a page fault is running out of stack.
1698 //
1699
1700 typedef struct _PAGING_FILE_OVERFLOW_PACKET {
1701 PIRP Irp;
1702 PFCB Fcb;
1703 } PAGING_FILE_OVERFLOW_PACKET, *PPAGING_FILE_OVERFLOW_PACKET;
1704
1705 //
1706 // This structure is used to access the EaFile.
1707 //
1708
1709 #define EA_BCB_ARRAY_SIZE 8
1710
1711 typedef struct _EA_RANGE {
1712
1713 PCHAR Data;
1714 ULONG StartingVbo;
1715 ULONG Length;
1716 USHORT BcbChainLength;
1717 BOOLEAN AuxilaryBuffer;
1718 PBCB *BcbChain;
1719 PBCB BcbArray[EA_BCB_ARRAY_SIZE];
1720
1721 } EA_RANGE, *PEA_RANGE;
1722
1723 #define EA_RANGE_HEADER_SIZE (FIELD_OFFSET( EA_RANGE, BcbArray ))
1724
1725 //
1726 // These symbols are used by the upcase/downcase routines.
1727 //
1728
1729 #define WIDE_LATIN_CAPITAL_A (0xff21)
1730 #define WIDE_LATIN_CAPITAL_Z (0xff3a)
1731 #define WIDE_LATIN_SMALL_A (0xff41)
1732 #define WIDE_LATIN_SMALL_Z (0xff5a)
1733
1734 //
1735 // These values are returned by FatInterpretClusterType.
1736 //
1737
1738 typedef enum _CLUSTER_TYPE {
1739 FatClusterAvailable,
1740 FatClusterReserved,
1741 FatClusterBad,
1742 FatClusterLast,
1743 FatClusterNext
1744 } CLUSTER_TYPE;
1745
1746 #if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
1747 // ============================================================================
1748 // ============================================================================
1749 //
1750 // Stack Swapping Support
1751 //
1752 // ============================================================================
1753 // ============================================================================
1754
1755 //
1756 // This structure is used when doing a callout on a new stack.
1757 // It contains the parameters for various functions and a place
1758 // to store the return code.
1759 //
1760
1761 typedef struct _FAT_CALLOUT_PARAMETERS {
1762
1763 union {
1764
1765 //
1766 // Parameters for a create request via FatCommonCreate().
1767 //
1768
1769 struct {
1770
1771 PIRP_CONTEXT IrpContext;
1772 PIRP Irp;
1773
1774 } Create;
1775
1776 };
1777
1778 NTSTATUS IrpStatus;
1779 NTSTATUS ExceptionStatus;
1780
1781 } FAT_CALLOUT_PARAMETERS, *PFAT_CALLOUT_PARAMETERS;
1782 #endif
1783
1784 #endif // _FATSTRUC_
1785
1786