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