1 /*++ 2 3 Copyright (c) 1989-2000 Microsoft Corporation 4 5 Module Name: 6 7 CdStruc.h 8 9 Abstract: 10 11 This module defines the data structures that make up the major internal 12 part of the Cdfs file system. 13 14 In-Memory structures: 15 16 The global data structures with the CdDataRecord. It contains a pointer 17 to a File System Device object and a queue of Vcb's. There is a Vcb for 18 every currently or previously mounted volumes. We may be in the process 19 of tearing down the Vcb's which have been dismounted. The Vcb's are 20 allocated as an extension to a volume device object. 21 22 +--------+ 23 | CdData | +--------+ 24 | | --> |FilSysDo| 25 | | | | 26 | | <+ +--------+ 27 +--------+ | 28 | 29 | +--------+ +--------+ 30 | |VolDo | |VolDo | 31 | | | | | 32 | +--------+ +--------+ 33 +> |Vcb | <-> |Vcb | <-> ... 34 | | | | 35 +--------+ +--------+ 36 37 38 Each Vcb contains a table of all the Fcbs for the volume indexed by 39 their FileId. Each Vcb contains a pointer to the root directory of 40 the volume. Each directory Fcb contains a queue of child Fcb's for 41 its children. There can also be detached subtrees due to open operations 42 by Id where the Fcb's are not connected to the root. 43 44 The following diagram shows the root structure. 45 46 +--------+ +--------+ 47 | Vcb |---->| Fcb |-----------------------------------------------+ 48 | | | Table |--------------------------------------------+ | | 49 | |--+ | |-----------------------------------------+ | | | 50 +--------+ | +--------+ | | | 51 | | | | | | | 52 | | | +--------------------+ | | | 53 | V +---------+ | | | | 54 | +--------+ | | | | | 55 | |RootFcb | V V | | | 56 +->| | +--------+ +--------+ | | | 57 | |-->|Child | |Child | | | | 58 +--------+ | Fcb |<-->| Fcb |<--> ... | | | 59 | | | | | | | 60 +--------+ +--------+ | | | 61 | | | 62 (Freestanding sub-tree) | | | 63 +--------+ | | | 64 |OpenById|<-----------------------------------------+ | | 65 | Dir | +--------+ | | 66 | |--->|OpenById|<------------------------------+ | 67 +--------+ | Child | +--------+ | 68 | Dir |--->|OpenById|<-------------------+ 69 +--------+ | Child | 70 | File | 71 +--------+ 72 73 Attached to each Directory Fcb is a prefix table containing the names 74 of children of this directory for which there is an Fcb. Not all Fcb's 75 will necessarily have an entry in this table. 76 77 +--------+ +--------+ 78 | Dir | | Prefix | 79 | Fcb |----->| Table |--------------------+ 80 | | | |-------+ | 81 +--------+ +--------+ | | 82 | | | | 83 | | | | 84 | V V V 85 | +--------+ +--------+ +--------+ +--------+ 86 | | Fcb | | Fcb | | Fcb | | Fcb | 87 +---------->| |<-->| |<-->| |<-->| | 88 | | | | | | | | 89 +--------+ +--------+ +--------+ +--------+ 90 91 92 Each file object open on a CDROM volume contains two context pointers. The 93 first will point back to the Fcb for the file object. The second, if present, 94 points to a Ccb (ContextControlBlock) which contains the per-handle information. 95 This includes the state of any directory enumeration. 96 97 +--------+ +--------+ +--------+ 98 | Fcb |<------| File | | Ccb | 99 | | | Object|--->| | 100 | | | | | | 101 +--------+ +--------+ +--------+ 102 ^ ^ 103 | | +--------+ +--------+ 104 | | | File | | Ccb | 105 | +---------| Object|--->| | 106 | | | | | 107 | +--------+ +--------+ 108 | 109 | +--------+ 110 | |Stream | 111 +--------------| File | 112 | Object| 113 +--------+ 114 115 116 Synchronization: 117 118 1. A resource in the CdData synchronizes access to the Vcb queue. This 119 is used during mount/verify/dismount operations. 120 121 2. A resource in the Vcb is used to synchronize access to Vcb for 122 open/close operations. Typically acquired shared, it 123 is acquired exclusively to lock out these operations. 124 125 3. A second resource in the Vcb is used to synchronize all file operations. 126 Typically acquired shared, it is acquired exclusively to lock 127 out all file operations. Acquiring both Vcb resources will lock 128 the entire volume. 129 130 4. A resource in the nonpaged Fcb will synchronize open/close operations 131 on an Fcb. 132 133 5. A fast mutex in the Vcb will protect access to the Fcb table and 134 the open counts in the Vcb. It is also used to modify the reference 135 counts in all Fcbs. This mutex cannot be acquired 136 exclusely and is an end resource. 137 138 6. A fast mutex in the Fcb will synchronize access to all Fcb fields 139 which aren't synchronized in some other way. A thread may acquire 140 mutexes for multiple Fcb's as long as it works it way toward the 141 root of the tree. This mutex can also be acquired recursively. 142 143 7. Normal locking order is CdData/Vcb/Fcb starting at any point in this 144 chain. The Vcb is required prior to acquiring resources for multiple 145 files. Shared ownership of the Vcb is sufficient in this case. 146 147 8. Normal locking order when acquiring multiple Fcb's is from some 148 starting Fcb and walking towards the root of tree. Create typically 149 walks down the tree. In this case we will attempt to acquire the 150 next node optimistically and if that fails we will reference 151 the current node in the tree, release it and acquire the next node. 152 At that point it will be safe to reacquire the parent node. 153 154 9. Locking order for the Fcb (via the fast mutex) will be from leaf of 155 tree back towards the root. No other resource may be acquired 156 after locking the Vcb (other than in-page reads). 157 158 10. Cleanup operations only lock the Vcb and Fcb long enough to change the 159 critical counts and share access fields. No reason to synchronize 160 otherwise. None of the structures can go away from beneath us 161 in this case. 162 163 164 --*/ 165 166 #ifndef _CDSTRUC_ 167 #define _CDSTRUC_ 168 169 typedef PVOID PBCB; //**** Bcb's are now part of the cache module 170 171 #define BYTE_COUNT_EMBEDDED_NAME (32) 172 173 #ifdef __REACTOS__ 174 #define __volatile volatile 175 #define _Unreferenced_parameter_ 176 #define __field_range(a,b) 177 #define __analysis_assert(x) 178 #endif 179 180 // 181 // The CD_MCB is used to store the mapping of logical file offset to 182 // logical disk offset. NOTE - This package only deals with the 183 // logical 2048 sectors. Translating to 'raw' sectors happens in 184 // software. We will embed a single MCB_ENTRY in the Fcb since this 185 // will be the typical case. 186 // 187 188 typedef struct _CD_MCB { 189 190 // 191 // Size and current count of the Mcb entries. 192 // 193 194 ULONG MaximumEntryCount; 195 ULONG CurrentEntryCount; 196 197 // 198 // Pointer to the start of the Mcb entries. 199 // 200 201 struct _CD_MCB_ENTRY *McbArray; 202 203 } CD_MCB; 204 typedef CD_MCB *PCD_MCB; 205 206 typedef struct _CD_MCB_ENTRY { 207 208 // 209 // Starting offset and number of bytes described by this entry. 210 // The Byte count is rounded to a logical block boundary if this is 211 // the last block. 212 // 213 214 LONGLONG DiskOffset; 215 LONGLONG ByteCount; 216 217 // 218 // Starting offset in the file of mapping described by this dirent. 219 // 220 221 LONGLONG FileOffset; 222 223 // 224 // Data length and block length. Data length is the length of each 225 // data block. Total length is the length of each data block and 226 // the skip size. 227 // 228 229 LONGLONG DataBlockByteCount; 230 LONGLONG TotalBlockByteCount; 231 232 } CD_MCB_ENTRY; 233 typedef CD_MCB_ENTRY *PCD_MCB_ENTRY; 234 235 236 // 237 // Cd name structure. The following structure is used to represent the 238 // full Cdrom name. This name can be stored in either Unicode or ANSI 239 // format. 240 // 241 242 typedef struct _CD_NAME { 243 244 // 245 // String containing name without the version number. 246 // The maximum length field for filename indicates the 247 // size of the buffer allocated for the two parts of the name. 248 // 249 250 UNICODE_STRING FileName; 251 252 // 253 // String containging the version number. 254 // 255 256 UNICODE_STRING VersionString; 257 258 } CD_NAME; 259 typedef CD_NAME *PCD_NAME; 260 261 // 262 // Following is the splay link structure for the prefix lookup. 263 // The names can be in either Unicode string or Ansi string format. 264 // 265 266 typedef struct _NAME_LINK { 267 268 RTL_SPLAY_LINKS Links; 269 UNICODE_STRING FileName; 270 271 } NAME_LINK; 272 typedef NAME_LINK *PNAME_LINK; 273 274 275 // 276 // Prefix entry. There is one of these for each name in the prefix table. 277 // An Fcb will have one of these embedded for the long name and an optional 278 // pointer to the short name entry. 279 // 280 281 typedef struct _PREFIX_ENTRY { 282 283 // 284 // Pointer to the Fcb for this entry. 285 // 286 287 struct _FCB *Fcb; 288 289 // 290 // Flags field. Used to indicate if the name is in the prefix table. 291 // 292 293 ULONG PrefixFlags; 294 295 // 296 // Exact case name match. 297 // 298 299 NAME_LINK ExactCaseName; 300 301 // 302 // Case-insensitive name link. 303 // 304 305 NAME_LINK IgnoreCaseName; 306 307 WCHAR FileNameBuffer[ BYTE_COUNT_EMBEDDED_NAME ]; 308 309 } PREFIX_ENTRY; 310 typedef PREFIX_ENTRY *PPREFIX_ENTRY; 311 312 #define PREFIX_FLAG_EXACT_CASE_IN_TREE (0x00000001) 313 #define PREFIX_FLAG_IGNORE_CASE_IN_TREE (0x00000002) 314 315 316 // 317 // The CD_DATA record is the top record in the CDROM file system in-memory 318 // data structure. This structure must be allocated from non-paged pool. 319 // 320 321 typedef struct _CD_DATA { 322 323 // 324 // The type and size of this record (must be CDFS_NTC_DATA_HEADER) 325 // 326 327 _Field_range_(==, CDFS_NTC_DATA_HEADER) NODE_TYPE_CODE NodeTypeCode; 328 NODE_BYTE_SIZE NodeByteSize; 329 330 // 331 // A pointer to the Driver object we were initialized with 332 // 333 334 PDRIVER_OBJECT DriverObject; 335 336 // 337 // Vcb queue. 338 // 339 340 LIST_ENTRY VcbQueue; 341 342 // 343 // The following fields are used to allocate IRP context structures 344 // using a lookaside list, and other fixed sized structures from a 345 // small cache. We use the CdData mutex to protext these structures. 346 // 347 348 ULONG IrpContextDepth; 349 ULONG IrpContextMaxDepth; 350 SINGLE_LIST_ENTRY IrpContextList; 351 352 // 353 // Filesystem device object for CDFS. 354 // 355 356 PDEVICE_OBJECT FileSystemDeviceObject; 357 358 #ifdef __REACTOS__ 359 PDEVICE_OBJECT HddFileSystemDeviceObject; 360 #endif 361 362 // 363 // Following are used to manage the async and delayed close queue. 364 // 365 // FspCloseActive - Indicates whether there is a thread processing the 366 // two close queues. 367 // ReduceDelayedClose - Indicates that we have hit the upper threshold 368 // for the delayed close queue and need to reduce it to lower threshold. 369 // Flags - CD flags. 370 // AsyncCloseQueue - Queue of IrpContext waiting for async close operation. 371 // AsyncCloseCount - Number of entries on the async close queue. 372 // 373 // DelayedCloseQueue - Queue of IrpContextLite waiting for delayed close 374 // operation. 375 // MaxDelayedCloseCount - Trigger delay close work at this threshold. 376 // MinDelayedCloseCount - Turn off delay close work at this threshold. 377 // DelayedCloseCount - Number of entries on the delayted close queue. 378 // 379 // CloseItem - Workqueue item used to start FspClose thread. 380 // 381 382 LIST_ENTRY AsyncCloseQueue; 383 ULONG AsyncCloseCount; 384 BOOLEAN FspCloseActive; 385 BOOLEAN ReduceDelayedClose; 386 USHORT Flags; 387 388 // 389 // The following fields describe the deferred close file objects. 390 // 391 392 LIST_ENTRY DelayedCloseQueue; 393 ULONG DelayedCloseCount; 394 ULONG MaxDelayedCloseCount; 395 ULONG MinDelayedCloseCount; 396 397 // 398 // Fast mutex used to lock the fields of this structure. 399 // 400 401 PVOID CdDataLockThread; 402 FAST_MUTEX CdDataMutex; 403 404 // 405 // A resource variable to control access to the global CDFS data record 406 // 407 408 ERESOURCE DataResource; 409 410 // 411 // Cache manager call back structure, which must be passed on each call 412 // to CcInitializeCacheMap. 413 // 414 415 CACHE_MANAGER_CALLBACKS CacheManagerCallbacks; 416 CACHE_MANAGER_CALLBACKS CacheManagerVolumeCallbacks; 417 418 // 419 // This is the ExWorkerItem that does both kinds of deferred closes. 420 // 421 422 PIO_WORKITEM CloseItem; 423 424 } CD_DATA; 425 typedef CD_DATA *PCD_DATA; 426 427 428 #define CD_FLAGS_SHUTDOWN (0x0001) 429 430 431 // 432 // Since DVD drives allow > 100 "sessions", we need to use a larger TOC 433 // than the legacy CD definition. The maximum is theoretically 0xaa-16 (max 434 // number of open tracks in a session), but it's quite possible that some 435 // drive does not enforce this, so we'll go with 169 (track 0xaa is always the 436 // leadout). 437 // 438 439 #define MAXIMUM_NUMBER_TRACKS_LARGE 0xAA 440 441 typedef struct _CDROM_TOC_LARGE { 442 443 // 444 // Header 445 // 446 447 UCHAR Length[2]; // add two bytes for this field 448 UCHAR FirstTrack; 449 UCHAR LastTrack; 450 451 // 452 // Track data 453 // 454 455 TRACK_DATA TrackData[ MAXIMUM_NUMBER_TRACKS_LARGE]; 456 457 } CDROM_TOC_LARGE, *PCDROM_TOC_LARGE; 458 459 typedef struct _CD_SECTOR_CACHE_CHUNK { 460 461 ULONG BaseLbn; 462 PUCHAR Buffer; 463 464 } CD_SECTOR_CACHE_CHUNK, *PCD_SECTOR_CACHE_CHUNK; 465 466 #define CD_SEC_CACHE_CHUNKS 4 467 #define CD_SEC_CHUNK_BLOCKS 0x18 468 469 // 470 // The Vcb (Volume control block) record corresponds to every 471 // volume mounted by the file system. They are ordered in a queue off 472 // of CdData.VcbQueue. 473 // 474 // The Vcb will be in several conditions during its lifespan. 475 // 476 // NotMounted - Disk is not currently mounted (i.e. removed 477 // from system) but cleanup and close operations are 478 // supported. 479 // 480 // MountInProgress - State of the Vcb from the time it is 481 // created until it is successfully mounted or the mount 482 // fails. 483 // 484 // Mounted - Volume is currently in the mounted state. 485 // 486 // Invalid - User has invalidated the volume. Only legal operations 487 // are cleanup and close. 488 // 489 // DismountInProgress - We have begun the process of tearing down the 490 // Vcb. It can be deleted when all the references to it 491 // have gone away. 492 // 493 494 typedef enum _VCB_CONDITION { 495 496 VcbNotMounted = 0, 497 VcbMountInProgress, 498 VcbMounted, 499 VcbInvalid, 500 VcbDismountInProgress 501 502 } VCB_CONDITION; 503 504 typedef struct _VCB { 505 506 // 507 // The type and size of this record (must be CDFS_NTC_VCB) 508 // 509 510 _Field_range_(==, CDFS_NTC_VCB) NODE_TYPE_CODE NodeTypeCode; 511 NODE_BYTE_SIZE NodeByteSize; 512 513 // 514 // Vpb for this volume. 515 // 516 517 PVPB Vpb; 518 519 // 520 // Device object for the driver below us. 521 // 522 523 PDEVICE_OBJECT TargetDeviceObject; 524 525 // 526 // File object used to lock the volume. 527 // 528 529 PFILE_OBJECT VolumeLockFileObject; 530 531 // 532 // Link into queue of Vcb's in the CdData structure. We will create a union with 533 // a LONGLONG to force the Vcb to be quad-aligned. 534 // 535 536 union { 537 538 LIST_ENTRY VcbLinks; 539 LONGLONG Alignment; 540 }; 541 542 // 543 // State flags and condition for the Vcb. 544 // 545 546 ULONG VcbState; 547 VCB_CONDITION VcbCondition; 548 549 // 550 // Various counts for this Vcb. 551 // 552 // VcbCleanup - Open handles left on this system. 553 // VcbReference - Number of reasons this Vcb is still present. 554 // VcbUserReference - Number of user file objects still present. 555 // 556 557 ULONG VcbCleanup; 558 __volatile LONG VcbReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ 559 __volatile LONG VcbUserReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ 560 561 // 562 // Fcb for the Volume Dasd file, root directory and the Path Table. 563 // 564 565 struct _FCB *VolumeDasdFcb; 566 struct _FCB *RootIndexFcb; 567 struct _FCB *PathTableFcb; 568 569 // 570 // Location of current session and offset of volume descriptors. 571 // 572 573 ULONG BaseSector; 574 ULONG VdSectorOffset; 575 ULONG PrimaryVdSectorOffset; 576 577 // 578 // Following is a sector from the last non-cached read of an XA file. 579 // Also the cooked offset on the disk. 580 // 581 582 PVOID XASector; 583 LONGLONG XADiskOffset; 584 585 // 586 // Vcb resource. This is used to synchronize open/cleanup/close operations. 587 // 588 589 ERESOURCE VcbResource; 590 591 // 592 // File resource. This is used to synchronize all file operations except 593 // open/cleanup/close. 594 // 595 596 ERESOURCE FileResource; 597 598 // 599 // Vcb fast mutex. This is used to synchronize the fields in the Vcb 600 // when modified when the Vcb is not held exclusively. Included here 601 // are the count fields and Fcb table. 602 // 603 // We also use this to synchronize changes to the Fcb reference field. 604 // 605 606 FAST_MUTEX VcbMutex; 607 PVOID VcbLockThread; 608 609 // 610 // The following is used to synchronize the dir notify package. 611 // 612 613 PNOTIFY_SYNC NotifySync; 614 615 // 616 // The following is the head of a list of notify Irps. 617 // 618 619 LIST_ENTRY DirNotifyList; 620 621 // 622 // Logical block size for this volume as well constant values 623 // associated with the block size. 624 // 625 626 ULONG BlockSize; 627 ULONG BlockToSectorShift; 628 ULONG BlockToByteShift; 629 ULONG BlocksPerSector; 630 ULONG BlockMask; 631 ULONG BlockInverseMask; 632 633 // 634 // Fcb table. Synchronized with the Vcb fast mutex. 635 // 636 637 RTL_GENERIC_TABLE FcbTable; 638 639 // 640 // Volume TOC. Cache this information for quick lookup. 641 // 642 643 PCDROM_TOC_LARGE CdromToc; 644 ULONG TocLength; 645 ULONG TrackCount; 646 ULONG DiskFlags; 647 648 // 649 // Block factor to determine last session information. 650 // 651 652 ULONG BlockFactor; 653 654 // 655 // Media change count from device driver for bulletproof detection 656 // of media movement 657 // 658 659 ULONG MediaChangeCount; 660 661 // 662 // For raw reads, CDFS must obey the port maximum transfer restrictions. 663 // 664 665 ULONG MaximumTransferRawSectors; 666 ULONG MaximumPhysicalPages; 667 668 // 669 // Preallocated VPB for swapout, so we are not forced to consider 670 // must succeed pool. 671 // 672 673 PVPB SwapVpb; 674 675 // 676 // Directory block cache. Read large numbers of blocks on directory 677 // reads, hoping to benefit from the fact that most mastered/pressed 678 // discs clump metadata in one place thus allowing us to crudely 679 // pre-cache and reduce seeks back to directory data during app install, 680 // file copy etc. 681 // 682 // Note that the purpose of this is to PRE cache unread data, 683 // not cache already read data (since Cc already provides that), thus 684 // speeding initial access to the volume. 685 // 686 687 PUCHAR SectorCacheBuffer; 688 CD_SECTOR_CACHE_CHUNK SecCacheChunks[ CD_SEC_CACHE_CHUNKS]; 689 ULONG SecCacheLRUChunkIndex; 690 691 PIRP SectorCacheIrp; 692 KEVENT SectorCacheEvent; 693 ERESOURCE SectorCacheResource; 694 695 #ifdef CDFS_TELEMETRY_DATA 696 697 // 698 // An ID that is common across the volume stack used to correlate volume events and for telemetry purposes. 699 // It may have a different value than the VolumeGuid. 700 // 701 702 GUID VolumeCorrelationId; 703 704 #endif // CDFS_TELEMETRY_DATA 705 706 #if DBG 707 ULONG SecCacheHits; 708 ULONG SecCacheMisses; 709 #endif 710 } VCB, *PVCB; 711 712 #define VCB_STATE_HSG (0x00000001) 713 #define VCB_STATE_ISO (0x00000002) 714 #define VCB_STATE_JOLIET (0x00000004) 715 #define VCB_STATE_LOCKED (0x00000010) 716 #define VCB_STATE_REMOVABLE_MEDIA (0x00000020) 717 #define VCB_STATE_CDXA (0x00000040) 718 #define VCB_STATE_AUDIO_DISK (0x00000080) 719 #define VCB_STATE_NOTIFY_REMOUNT (0x00000100) 720 #define VCB_STATE_VPB_NOT_ON_DEVICE (0x00000200) 721 #define VCB_STATE_SHUTDOWN (0x00000400) 722 #define VCB_STATE_DISMOUNTED (0x00000800) 723 724 725 // 726 // The Volume Device Object is an I/O system device object with a 727 // workqueue and an VCB record appended to the end. There are multiple 728 // of these records, one for every mounted volume, and are created during 729 // a volume mount operation. The work queue is for handling an overload 730 // of work requests to the volume. 731 // 732 733 typedef struct _VOLUME_DEVICE_OBJECT { 734 735 DEVICE_OBJECT DeviceObject; 736 737 // 738 // The following field tells how many requests for this volume have 739 // either been enqueued to ExWorker threads or are currently being 740 // serviced by ExWorker threads. If the number goes above 741 // a certain threshold, put the request on the overflow queue to be 742 // executed later. 743 // 744 745 __volatile LONG PostedRequestCount; /* ReactOS Change: GCC "pointer targets in passing argument 1 of 'InterlockedDecrement' differ in signedness" */ 746 747 // 748 // The following field indicates the number of IRP's waiting 749 // to be serviced in the overflow queue. 750 // 751 752 ULONG OverflowQueueCount; 753 754 // 755 // The following field contains the queue header of the overflow queue. 756 // The Overflow queue is a list of IRP's linked via the IRP's ListEntry 757 // field. 758 // 759 760 LIST_ENTRY OverflowQueue; 761 762 // 763 // The following spinlock protects access to all the above fields. 764 // 765 766 KSPIN_LOCK OverflowQueueSpinLock; 767 768 // 769 // This is the file system specific volume control block. 770 // 771 772 VCB Vcb; 773 774 } VOLUME_DEVICE_OBJECT; 775 typedef VOLUME_DEVICE_OBJECT *PVOLUME_DEVICE_OBJECT; 776 777 778 // 779 // The following two structures are the separate union structures for 780 // data and index Fcb's. The path table is actually the same structure 781 // as the index Fcb since it uses the first few fields. 782 // 783 784 typedef enum _FCB_CONDITION { 785 FcbGood = 1, 786 FcbBad, 787 FcbNeedsToBeVerified 788 } FCB_CONDITION; 789 790 typedef struct _FCB_DATA { 791 792 #if (NTDDI_VERSION < NTDDI_WIN8) 793 // 794 // The following field is used by the oplock module 795 // to maintain current oplock information. 796 // 797 798 OPLOCK Oplock; 799 #endif 800 801 // 802 // The following field is used by the filelock module 803 // to maintain current byte range locking information. 804 // A file lock is allocated as needed. 805 // 806 807 PFILE_LOCK FileLock; 808 809 } FCB_DATA; 810 typedef FCB_DATA *PFCB_DATA; 811 812 typedef struct _FCB_INDEX { 813 814 // 815 // Internal stream file. 816 // 817 818 PFILE_OBJECT FileObject; 819 820 // 821 // Offset of first entry in stream. This is for case where directory 822 // or path table does not begin on a sector boundary. This value is 823 // added to all offset values to determine the real offset. 824 // 825 826 ULONG StreamOffset; 827 828 // 829 // List of child fcbs. 830 // 831 832 LIST_ENTRY FcbQueue; 833 834 // 835 // Ordinal number for this directory. Combine this with the path table offset 836 // in the FileId and you have a starting point in the path table. 837 // 838 839 ULONG Ordinal; 840 841 // 842 // Children path table start. This is the offset in the path table 843 // for the first child of the directory. A value of zero indicates 844 // that we haven't found the first child yet. If there are no child 845 // directories we will position at a point in the path table so that 846 // subsequent searches will fail quickly. 847 // 848 849 ULONG ChildPathTableOffset; 850 ULONG ChildOrdinal; 851 852 // 853 // Root of splay trees for exact and ignore case prefix trees. 854 // 855 856 PRTL_SPLAY_LINKS ExactCaseRoot; 857 PRTL_SPLAY_LINKS IgnoreCaseRoot; 858 859 } FCB_INDEX; 860 typedef FCB_INDEX *PFCB_INDEX; 861 862 typedef struct _FCB_NONPAGED { 863 864 // 865 // Type and size of this record must be CDFS_NTC_FCB_NONPAGED 866 // 867 868 _Field_range_(==, CDFS_NTC_FCB_NONPAGED) NODE_TYPE_CODE NodeTypeCode; 869 NODE_BYTE_SIZE NodeByteSize; 870 871 // 872 // The following field contains a record of special pointers used by 873 // MM and Cache to manipluate section objects. Note that the values 874 // are set outside of the file system. However the file system on an 875 // open/create will set the file object's SectionObject field to 876 // point to this field 877 // 878 879 SECTION_OBJECT_POINTERS SegmentObject; 880 881 // 882 // This is the resource structure for this Fcb. 883 // 884 885 ERESOURCE FcbResource; 886 887 // 888 // This is the FastMutex for this Fcb. 889 // 890 891 FAST_MUTEX FcbMutex; 892 893 // 894 // This is the mutex that is inserted into the FCB_ADVANCED_HEADER 895 // FastMutex field 896 // 897 898 FAST_MUTEX AdvancedFcbHeaderMutex; 899 900 } FCB_NONPAGED; 901 typedef FCB_NONPAGED *PFCB_NONPAGED; 902 903 // 904 // The Fcb/Dcb record corresponds to every open file and directory, and to 905 // every directory on an opened path. 906 // 907 908 typedef struct _FCB { 909 910 // 911 // The following field is used for fast I/O. It contains the node 912 // type code and size, indicates if fast I/O is possible, contains 913 // allocation, file, and valid data size, a resource, and call back 914 // pointers for FastIoRead and FastMdlRead. 915 // 916 // 917 // Node type codes for the Fcb must be one of the following. 918 // 919 // CDFS_NTC_FCB_PATH_TABLE 920 // CDFS_NTC_FCB_INDEX 921 // CDFS_NTC_FCB_DATA 922 // 923 924 // 925 // Common Fsrtl Header. The named header is for the fieldoff.c output. We 926 // use the unnamed header internally. 927 // 928 929 union{ 930 931 FSRTL_ADVANCED_FCB_HEADER Header; 932 FSRTL_ADVANCED_FCB_HEADER; 933 }; 934 935 // 936 // Vcb for this Fcb. 937 // 938 939 PVCB Vcb; 940 941 // 942 // Parent Fcb for this Fcb. This may be NULL if this file was opened 943 // by ID, also for the root Fcb. 944 // 945 946 struct _FCB *ParentFcb; 947 948 // 949 // Links to the queue of Fcb's in the parent. 950 // 951 952 LIST_ENTRY FcbLinks; 953 954 // 955 // FileId for this file. 956 // 957 958 FILE_ID FileId; 959 960 // 961 // Counts on this Fcb. Cleanup count represents the number of open handles 962 // on this Fcb. Reference count represents the number of reasons this Fcb 963 // is still present. It includes file objects, children Fcb and anyone 964 // who wants to prevent this Fcb from going away. Cleanup count is synchronized 965 // with the FcbResource. The reference count is synchronized with the 966 // VcbMutex. 967 // 968 969 ULONG FcbCleanup; 970 __volatile LONG FcbReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ 971 ULONG FcbUserReference; 972 973 // 974 // State flags for this Fcb. 975 // 976 977 ULONG FcbState; 978 979 // 980 // NT style attributes for the Fcb. 981 // 982 983 ULONG FileAttributes; 984 985 // 986 // CDXA attributes for this file. 987 // 988 989 USHORT XAAttributes; 990 991 // 992 // File number from the system use area. 993 // 994 995 UCHAR XAFileNumber; 996 997 // 998 // This is the thread and count for the thread which has locked this 999 // Fcb. 1000 // 1001 1002 PVOID FcbLockThread; 1003 ULONG FcbLockCount; 1004 1005 // 1006 // Pointer to the Fcb non-paged structures. 1007 // 1008 1009 PFCB_NONPAGED FcbNonpaged; 1010 1011 // 1012 // Share access structure. 1013 // 1014 1015 SHARE_ACCESS ShareAccess; 1016 1017 // 1018 // Mcb for the on disk mapping and a single map entry. 1019 // 1020 1021 CD_MCB_ENTRY McbEntry; 1022 CD_MCB Mcb; 1023 1024 // 1025 // Embed the prefix entry for the longname. Store an optional pointer 1026 // to a prefix structure for the short name. 1027 // 1028 1029 PPREFIX_ENTRY ShortNamePrefix; 1030 PREFIX_ENTRY FileNamePrefix; 1031 1032 // 1033 // Time stamp for this file. 1034 // 1035 1036 LONGLONG CreationTime; 1037 1038 union{ 1039 1040 ULONG FcbType; 1041 FCB_DATA; 1042 FCB_INDEX; 1043 }; 1044 1045 } FCB; 1046 typedef FCB *PFCB; 1047 1048 #define FCB_STATE_INITIALIZED (0x00000001) 1049 #define FCB_STATE_IN_FCB_TABLE (0x00000002) 1050 #define FCB_STATE_MODE2FORM2_FILE (0x00000004) 1051 #define FCB_STATE_MODE2_FILE (0x00000008) 1052 #define FCB_STATE_DA_FILE (0x00000010) 1053 1054 // 1055 // These file types are read as raw 2352 byte sectors 1056 // 1057 1058 #define FCB_STATE_RAWSECTOR_MASK ( FCB_STATE_MODE2FORM2_FILE | \ 1059 FCB_STATE_MODE2_FILE | \ 1060 FCB_STATE_DA_FILE ) 1061 1062 #define SIZEOF_FCB_DATA \ 1063 (FIELD_OFFSET( FCB, FcbType ) + sizeof( FCB_DATA )) 1064 1065 #define SIZEOF_FCB_INDEX \ 1066 (FIELD_OFFSET( FCB, FcbType ) + sizeof( FCB_INDEX )) 1067 1068 1069 // 1070 // The Ccb record is allocated for every file object 1071 // 1072 1073 typedef struct _CCB { 1074 1075 // 1076 // Type and size of this record (must be CDFS_NTC_CCB) 1077 // 1078 1079 _Field_range_(==, CDFS_NTC_CCB) NODE_TYPE_CODE NodeTypeCode; 1080 NODE_BYTE_SIZE NodeByteSize; 1081 1082 // 1083 // Flags. Indicates flags to apply for the current open. 1084 // 1085 1086 ULONG Flags; 1087 1088 // 1089 // Fcb for the file being opened. 1090 // 1091 1092 PFCB Fcb; 1093 1094 // 1095 // We store state information in the Ccb for a directory 1096 // enumeration on this handle. 1097 // 1098 1099 // 1100 // Offset in the directory stream to base the next enumeration. 1101 // 1102 1103 ULONG CurrentDirentOffset; 1104 CD_NAME SearchExpression; 1105 1106 } CCB; 1107 typedef CCB *PCCB; 1108 1109 #define CCB_FLAG_OPEN_BY_ID (0x00000001) 1110 #define CCB_FLAG_OPEN_RELATIVE_BY_ID (0x00000002) 1111 #define CCB_FLAG_IGNORE_CASE (0x00000004) 1112 #define CCB_FLAG_OPEN_WITH_VERSION (0x00000008) 1113 #define CCB_FLAG_DISMOUNT_ON_CLOSE (0x00000010) 1114 #define CCB_FLAG_ALLOW_EXTENDED_DASD_IO (0x00000020) 1115 1116 // 1117 // Following flags refer to index enumeration. 1118 // 1119 1120 #define CCB_FLAG_ENUM_NAME_EXP_HAS_WILD (0x00010000) 1121 #define CCB_FLAG_ENUM_VERSION_EXP_HAS_WILD (0x00020000) 1122 #define CCB_FLAG_ENUM_MATCH_ALL (0x00040000) 1123 #define CCB_FLAG_ENUM_VERSION_MATCH_ALL (0x00080000) 1124 #define CCB_FLAG_ENUM_RETURN_NEXT (0x00100000) 1125 #define CCB_FLAG_ENUM_INITIALIZED (0x00200000) 1126 #define CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY (0x00400000) 1127 1128 1129 // 1130 // The Irp Context record is allocated for every orginating Irp. It is 1131 // created by the Fsd dispatch routines, and deallocated by the CdComplete 1132 // request routine 1133 // 1134 1135 typedef struct _IRP_CONTEXT { 1136 1137 // 1138 // Type and size of this record (must be CDFS_NTC_IRP_CONTEXT) 1139 // 1140 1141 _Field_range_(==, CDFS_NTC_IRP_CONTEXT) NODE_TYPE_CODE NodeTypeCode; 1142 NODE_BYTE_SIZE NodeByteSize; 1143 1144 // 1145 // Originating Irp for the request. 1146 // 1147 1148 PIRP Irp; 1149 1150 // 1151 // Vcb for this operation. When this is NULL it means we were called 1152 // with our filesystem device object instead of a volume device object. 1153 // (Mount will fill this in once the Vcb is created) 1154 // 1155 1156 PVCB Vcb; 1157 1158 // 1159 // Exception encountered during the request. Any error raised explicitly by 1160 // the file system will be stored here. Any other error raised by the system 1161 // is stored here after normalizing it. 1162 // 1163 1164 NTSTATUS ExceptionStatus; 1165 ULONG RaisedAtLineFile; 1166 1167 // 1168 // Flags for this request. 1169 // 1170 1171 ULONG Flags; 1172 1173 // 1174 // Real device object. This represents the physical device closest to the media. 1175 // 1176 1177 PDEVICE_OBJECT RealDevice; 1178 1179 // 1180 // Io context for a read request. 1181 // Address of Fcb for teardown oplock in create case. 1182 // 1183 1184 union { 1185 1186 struct _CD_IO_CONTEXT *IoContext; 1187 PFCB *TeardownFcb; 1188 }; 1189 1190 // 1191 // Top level irp context for this thread. 1192 // 1193 1194 struct _IRP_CONTEXT *TopLevel; 1195 1196 // 1197 // Major and minor function codes. 1198 // 1199 1200 UCHAR MajorFunction; 1201 UCHAR MinorFunction; 1202 1203 // 1204 // Pointer to the top-level context if this IrpContext is responsible 1205 // for cleaning it up. 1206 // 1207 1208 struct _THREAD_CONTEXT *ThreadContext; 1209 1210 // 1211 // This structure is used for posting to the Ex worker threads. 1212 // 1213 1214 WORK_QUEUE_ITEM WorkQueueItem; 1215 1216 } IRP_CONTEXT; 1217 typedef IRP_CONTEXT *PIRP_CONTEXT; 1218 1219 #define IRP_CONTEXT_FLAG_ON_STACK (0x00000001) 1220 #define IRP_CONTEXT_FLAG_MORE_PROCESSING (0x00000002) 1221 #define IRP_CONTEXT_FLAG_WAIT (0x00000004) 1222 #define IRP_CONTEXT_FLAG_FORCE_POST (0x00000008) 1223 #define IRP_CONTEXT_FLAG_TOP_LEVEL (0x00000010) 1224 #define IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS (0x00000020) 1225 #define IRP_CONTEXT_FLAG_IN_FSP (0x00000040) 1226 #define IRP_CONTEXT_FLAG_IN_TEARDOWN (0x00000080) 1227 #define IRP_CONTEXT_FLAG_ALLOC_IO (0x00000100) 1228 #define IRP_CONTEXT_FLAG_DISABLE_POPUPS (0x00000200) 1229 #define IRP_CONTEXT_FLAG_FORCE_VERIFY (0x00000400) 1230 1231 // 1232 // Flags used for create. 1233 // 1234 1235 #define IRP_CONTEXT_FLAG_FULL_NAME (0x10000000) 1236 #define IRP_CONTEXT_FLAG_TRAIL_BACKSLASH (0x20000000) 1237 1238 // 1239 // The following flags need to be cleared when a request is posted. 1240 // 1241 1242 #define IRP_CONTEXT_FLAGS_CLEAR_ON_POST ( \ 1243 IRP_CONTEXT_FLAG_MORE_PROCESSING | \ 1244 IRP_CONTEXT_FLAG_WAIT | \ 1245 IRP_CONTEXT_FLAG_FORCE_POST | \ 1246 IRP_CONTEXT_FLAG_TOP_LEVEL | \ 1247 IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS | \ 1248 IRP_CONTEXT_FLAG_IN_FSP | \ 1249 IRP_CONTEXT_FLAG_IN_TEARDOWN | \ 1250 IRP_CONTEXT_FLAG_DISABLE_POPUPS \ 1251 ) 1252 1253 // 1254 // The following flags need to be cleared when a request is retried. 1255 // 1256 1257 #define IRP_CONTEXT_FLAGS_CLEAR_ON_RETRY ( \ 1258 IRP_CONTEXT_FLAG_MORE_PROCESSING | \ 1259 IRP_CONTEXT_FLAG_IN_TEARDOWN | \ 1260 IRP_CONTEXT_FLAG_DISABLE_POPUPS \ 1261 ) 1262 1263 // 1264 // The following flags are set each time through the Fsp loop. 1265 // 1266 1267 #define IRP_CONTEXT_FSP_FLAGS ( \ 1268 IRP_CONTEXT_FLAG_WAIT | \ 1269 IRP_CONTEXT_FLAG_TOP_LEVEL | \ 1270 IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS | \ 1271 IRP_CONTEXT_FLAG_IN_FSP \ 1272 ) 1273 1274 1275 // 1276 // Following structure is used to queue a request to the delayed close queue. 1277 // This structure should be the minimum block allocation size. 1278 // 1279 1280 typedef struct _IRP_CONTEXT_LITE { 1281 1282 // 1283 // Type and size of this record (must be CDFS_NTC_IRP_CONTEXT_LITE) 1284 // 1285 1286 _Field_range_(==, CDFS_NTC_IRP_CONTEXT_LITE) NODE_TYPE_CODE NodeTypeCode; 1287 NODE_BYTE_SIZE NodeByteSize; 1288 1289 // 1290 // Fcb for the file object being closed. 1291 // 1292 1293 PFCB Fcb; 1294 1295 // 1296 // List entry to attach to delayed close queue. 1297 // 1298 1299 LIST_ENTRY DelayedCloseLinks; 1300 1301 // 1302 // User reference count for the file object being closed. 1303 // 1304 1305 ULONG UserReference; 1306 1307 // 1308 // Real device object. This represents the physical device closest to the media. 1309 // 1310 1311 PDEVICE_OBJECT RealDevice; 1312 1313 } IRP_CONTEXT_LITE; 1314 typedef IRP_CONTEXT_LITE *PIRP_CONTEXT_LITE; 1315 1316 1317 // 1318 // Context structure for asynchronous I/O calls. Most of these fields 1319 // are actually only required for the ReadMultiple routines, but 1320 // the caller must allocate one as a local variable anyway before knowing 1321 // whether there are multiple requests are not. Therefore, a single 1322 // structure is used for simplicity. 1323 // 1324 1325 typedef struct _CD_IO_CONTEXT { 1326 1327 // 1328 // These two fields are used for multiple run Io 1329 // 1330 1331 __volatile LONG IrpCount; 1332 PIRP MasterIrp; 1333 __volatile NTSTATUS Status; 1334 BOOLEAN AllocatedContext; 1335 1336 union { 1337 1338 // 1339 // This element handles the asynchronous non-cached Io 1340 // 1341 1342 struct { 1343 1344 PERESOURCE Resource; 1345 ERESOURCE_THREAD ResourceThreadId; 1346 ULONG RequestedByteCount; 1347 }; 1348 1349 // 1350 // and this element handles the synchronous non-cached Io. 1351 // 1352 1353 KEVENT SyncEvent; 1354 }; 1355 1356 } CD_IO_CONTEXT; 1357 typedef CD_IO_CONTEXT *PCD_IO_CONTEXT; 1358 1359 1360 // 1361 // Following structure is used to track the top level request. Each Cdfs 1362 // Fsd and Fsp entry point will examine the top level irp location in the 1363 // thread local storage to determine if this request is top level and/or 1364 // top level Cdfs. The top level Cdfs request will remember the previous 1365 // value and update that location with a stack location. This location 1366 // can be accessed by recursive Cdfs entry points. 1367 // 1368 1369 typedef struct _THREAD_CONTEXT { 1370 1371 // 1372 // CDFS signature. Used to confirm structure on stack is valid. 1373 // 1374 1375 ULONG Cdfs; 1376 1377 // 1378 // Previous value in top-level thread location. We restore this 1379 // when done. 1380 // 1381 1382 PIRP SavedTopLevelIrp; 1383 1384 // 1385 // Top level Cdfs IrpContext. Initial Cdfs entry point on stack 1386 // will store the IrpContext for the request in this stack location. 1387 // 1388 1389 PIRP_CONTEXT TopLevelIrpContext; 1390 1391 } THREAD_CONTEXT; 1392 typedef THREAD_CONTEXT *PTHREAD_CONTEXT; 1393 1394 1395 // 1396 // The following structure is used for enumerating the entries in the 1397 // path table. We will always map this two sectors at a time so we don't 1398 // have to worry about entries which span sectors. We move through 1399 // one sector at a time though. We will unpin and remap after 1400 // crossing a sector boundary. 1401 // 1402 // The only special case is where we span a cache view. In that case 1403 // we will allocate a buffer and read both pieces into it. 1404 // 1405 // This strategy takes advantage of the CC enhancement which allows 1406 // overlapping ranges. 1407 // 1408 1409 typedef struct _PATH_ENUM_CONTEXT { 1410 1411 // 1412 // Pointer to the current sector and the offset of this sector to 1413 // the beginning of the path table. The Data pointer may be 1414 // a pool block in the case where we cross a cache view 1415 // boundary. Also the length of the data for this block. 1416 // 1417 1418 PVOID Data; 1419 ULONG BaseOffset; 1420 ULONG DataLength; 1421 1422 // 1423 // Bcb for the sector. (We may actually have pinned two sectors) 1424 // This will be NULL for the case where we needed to allocate a 1425 // buffer in the case where we span a cache view. 1426 // 1427 1428 PBCB Bcb; 1429 1430 // 1431 // Offset to current entry within the current data block. 1432 // 1433 1434 ULONG DataOffset; 1435 1436 // 1437 // Did we allocate the buffer for the entry. 1438 // 1439 1440 BOOLEAN AllocatedData; 1441 1442 // 1443 // End of Path Table. This tells us whether the current data 1444 // block includes the end of the path table. This is the 1445 // only block where we need to do a careful check about whether 1446 // the path table entry fits into the buffer. 1447 // 1448 // Also once we have reached the end of the path table we don't 1449 // need to remap the data as we move into the final sector. 1450 // We always look at the last two sectors together. 1451 // 1452 1453 BOOLEAN LastDataBlock; 1454 1455 } PATH_ENUM_CONTEXT; 1456 typedef PATH_ENUM_CONTEXT *PPATH_ENUM_CONTEXT; 1457 1458 #define VACB_MAPPING_MASK (VACB_MAPPING_GRANULARITY - 1) 1459 #define LAST_VACB_SECTOR_OFFSET (VACB_MAPPING_GRANULARITY - SECTOR_SIZE) 1460 1461 1462 // 1463 // Path Entry. This is our representation of the on disk data. 1464 // 1465 1466 typedef struct _PATH_ENTRY { 1467 1468 // 1469 // Directory number and offset. This is the ordinal and the offset from 1470 // the beginning of the path table stream for this entry. 1471 // 1472 // 1473 1474 ULONG Ordinal; 1475 ULONG PathTableOffset; 1476 1477 // 1478 // Logical block Offset on the disk for this entry. We already bias 1479 // this by any Xar blocks. 1480 // 1481 1482 ULONG DiskOffset; 1483 1484 // 1485 // Length of on-disk path table entry. 1486 // 1487 1488 ULONG PathEntryLength; 1489 1490 // 1491 // Parent number. 1492 // 1493 1494 ULONG ParentOrdinal; 1495 1496 // 1497 // DirName length and Id. Typically the pointer here points to the raw on-disk 1498 // bytes. We will point to a fixed self entry if this is the root directory. 1499 // 1500 1501 ULONG DirNameLen; 1502 PCHAR DirName; 1503 1504 // 1505 // Following are the flags used to cleanup this structure. 1506 // 1507 1508 ULONG Flags; 1509 1510 // 1511 // The following is the filename string and version number strings. We embed a buffer 1512 // large enough to hold two 8.3 names. One for exact case and one for case insensitive. 1513 // 1514 1515 CD_NAME CdDirName; 1516 CD_NAME CdCaseDirName; 1517 1518 WCHAR NameBuffer[BYTE_COUNT_EMBEDDED_NAME / sizeof( WCHAR ) * 2]; 1519 1520 } PATH_ENTRY; 1521 typedef PATH_ENTRY *PPATH_ENTRY; 1522 1523 #define PATH_ENTRY_FLAG_ALLOC_BUFFER (0x00000001) 1524 1525 1526 // 1527 // Compound path entry. This structure combines the on-disk entries 1528 // with the in-memory structures. 1529 // 1530 1531 typedef struct _COMPOUND_PATH_ENTRY { 1532 1533 PATH_ENUM_CONTEXT PathContext; 1534 PATH_ENTRY PathEntry; 1535 1536 } COMPOUND_PATH_ENTRY; 1537 typedef COMPOUND_PATH_ENTRY *PCOMPOUND_PATH_ENTRY; 1538 1539 1540 // 1541 // The following is used for enumerating through a directory via the 1542 // dirents. 1543 // 1544 1545 typedef struct _DIRENT_ENUM_CONTEXT { 1546 1547 // 1548 // Pointer the current sector and the offset of this sector within 1549 // the directory file. Also the data length of this pinned block. 1550 // 1551 1552 PVOID Sector; 1553 ULONG BaseOffset; 1554 ULONG DataLength; 1555 1556 // 1557 // Bcb for the sector. 1558 // 1559 1560 PBCB Bcb; 1561 1562 // 1563 // Offset to the current dirent within this sector. 1564 // 1565 1566 ULONG SectorOffset; 1567 1568 // 1569 // Length to next dirent. A zero indicates to move to the next sector. 1570 // 1571 1572 ULONG NextDirentOffset; 1573 1574 } DIRENT_ENUM_CONTEXT; 1575 typedef DIRENT_ENUM_CONTEXT *PDIRENT_ENUM_CONTEXT; 1576 1577 1578 // 1579 // Following structure is used to smooth out the differences in the HSG, ISO 1580 // and Joliett directory entries. 1581 // 1582 1583 typedef struct _DIRENT { 1584 1585 // 1586 // Offset in the Directory of this entry. Note this includes 1587 // any bytes added to the beginning of the directory to pad 1588 // down to a sector boundary. 1589 // 1590 1591 ULONG DirentOffset; 1592 1593 ULONG DirentLength; 1594 1595 // 1596 // Starting offset on the disk including any Xar blocks. 1597 // 1598 1599 ULONG StartingOffset; 1600 1601 // 1602 // DataLength of the data. If not the last block then this should 1603 // be an integral number of logical blocks. 1604 // 1605 1606 ULONG DataLength; 1607 1608 // 1609 // The following field is the time stamp out of the directory entry. 1610 // Use a pointer into the dirent for this. 1611 // 1612 1613 PCHAR CdTime; 1614 1615 // 1616 // The following field is the dirent file flags field. 1617 // 1618 1619 UCHAR DirentFlags; 1620 1621 // 1622 // Following field is a Cdfs flag field used to clean up this structure. 1623 // 1624 1625 UCHAR Flags; 1626 1627 // 1628 // The following fields indicate the file unit size and interleave gap 1629 // for interleaved files. Each of these are in logical blocks. 1630 // 1631 1632 ULONG FileUnitSize; 1633 ULONG InterleaveGapSize; 1634 1635 // 1636 // System use offset. Zero value indicates no system use area. 1637 // 1638 1639 ULONG SystemUseOffset; 1640 1641 // 1642 // CDXA attributes and file number for this file. 1643 // 1644 1645 USHORT XAAttributes; 1646 UCHAR XAFileNumber; 1647 1648 // 1649 // Filename length and ID. We copy the length (in bytes) and keep 1650 // a pointer to the start of the name. 1651 // 1652 1653 ULONG FileNameLen; 1654 PCHAR FileName; 1655 1656 // 1657 // The following are the filenames stored by name and version numbers. 1658 // The fixed buffer here can hold two Unicode 8.3 names. This allows 1659 // us to upcase the name into a fixed buffer. 1660 // 1661 1662 CD_NAME CdFileName; 1663 CD_NAME CdCaseFileName; 1664 1665 // 1666 // Data stream type. Indicates if this is audio, XA mode2 form2 or cooked sectors. 1667 // 1668 1669 XA_EXTENT_TYPE ExtentType; 1670 1671 WCHAR NameBuffer[BYTE_COUNT_EMBEDDED_NAME / sizeof( WCHAR ) * 2]; 1672 1673 } DIRENT; 1674 typedef DIRENT *PDIRENT; 1675 1676 #define DIRENT_FLAG_ALLOC_BUFFER (0x01) 1677 #define DIRENT_FLAG_CONSTANT_ENTRY (0x02) 1678 1679 #define DIRENT_FLAG_NOT_PERSISTENT (0) 1680 1681 1682 // 1683 // Following structure combines the on-disk information with the normalized 1684 // structure. 1685 // 1686 1687 typedef struct _COMPOUND_DIRENT { 1688 1689 DIRENT_ENUM_CONTEXT DirContext; 1690 DIRENT Dirent; 1691 1692 } COMPOUND_DIRENT; 1693 typedef COMPOUND_DIRENT *PCOMPOUND_DIRENT; 1694 1695 1696 // 1697 // The following structure is used to enumerate the files in a directory. 1698 // It contains three DirContext/Dirent pairs and then self pointers to 1699 // know which of these is begin used how. 1700 // 1701 1702 typedef struct _FILE_ENUM_CONTEXT { 1703 1704 // 1705 // Pointers to the current compound dirents below. 1706 // 1707 // PriorDirent - Initial dirent for the last file encountered. 1708 // InitialDirent - Initial dirent for the current file. 1709 // CurrentDirent - Second or later dirent for the current file. 1710 // 1711 1712 PCOMPOUND_DIRENT PriorDirent; 1713 PCOMPOUND_DIRENT InitialDirent; 1714 PCOMPOUND_DIRENT CurrentDirent; 1715 1716 // 1717 // Flags indicating the state of the search. 1718 // 1719 1720 ULONG Flags; 1721 1722 // 1723 // This is an accumulation of the file sizes of the different extents 1724 // of a single file. 1725 // 1726 1727 LONGLONG FileSize; 1728 1729 // 1730 // Short name for this file. 1731 // 1732 1733 CD_NAME ShortName; 1734 WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ]; 1735 1736 // 1737 // Array of compound dirents. 1738 // 1739 1740 COMPOUND_DIRENT Dirents[3]; 1741 1742 } FILE_ENUM_CONTEXT; 1743 typedef FILE_ENUM_CONTEXT *PFILE_ENUM_CONTEXT; 1744 1745 #define FILE_CONTEXT_MULTIPLE_DIRENTS (0x00000001) 1746 1747 1748 // 1749 // RIFF header. Prepended to the data of a file containing XA sectors. 1750 // This is a hard-coded structure except that we bias the 'ChunkSize' and 1751 // 'RawSectors' fields with the file size. We also copy the attributes flag 1752 // from the system use area in the dirent. We always initialize this 1753 // structure by copying the XAFileHeader. 1754 // 1755 1756 typedef struct _RIFF_HEADER { 1757 1758 ULONG ChunkId; 1759 LONG ChunkSize; 1760 ULONG SignatureCDXA; 1761 ULONG SignatureFMT; 1762 ULONG XAChunkSize; 1763 ULONG OwnerId; 1764 USHORT Attributes; 1765 USHORT SignatureXA; 1766 UCHAR FileNumber; 1767 UCHAR Reserved[7]; 1768 ULONG SignatureData; 1769 ULONG RawSectors; 1770 1771 } RIFF_HEADER; 1772 typedef RIFF_HEADER *PRIFF_HEADER; 1773 1774 // 1775 // Audio play header for CDDA tracks. 1776 // 1777 1778 typedef struct _AUDIO_PLAY_HEADER { 1779 1780 ULONG Chunk; 1781 ULONG ChunkSize; 1782 ULONG SignatureCDDA; 1783 ULONG SignatureFMT; 1784 ULONG FMTChunkSize; 1785 USHORT FormatTag; 1786 USHORT TrackNumber; 1787 ULONG DiskID; 1788 ULONG StartingSector; 1789 ULONG SectorCount; 1790 UCHAR TrackAddress[4]; 1791 UCHAR TrackLength[4]; 1792 1793 } AUDIO_PLAY_HEADER; 1794 typedef AUDIO_PLAY_HEADER *PAUDIO_PLAY_HEADER; 1795 1796 1797 // 1798 // Some macros for supporting the use of a Generic Table 1799 // containing all the FCB/DCBs and indexed by their FileId. 1800 // 1801 // For directories: 1802 // 1803 // The HighPart contains the path table offset of this directory in the 1804 // path table. 1805 // 1806 // The LowPart contains zero except for the upper bit which is 1807 // set to indicate that this is a directory. 1808 // 1809 // For files: 1810 // 1811 // The HighPart contains the path table offset of the parent directory 1812 // in the path table. 1813 // 1814 // The LowPart contains the byte offset of the dirent in the parent 1815 // directory file. 1816 // 1817 // A directory is always entered into the Fcb Table as if it's 1818 // dirent offset was zero. This enables any child to look in the FcbTable 1819 // for it's parent by searching with the same HighPart but with zero 1820 // as the value for LowPart. 1821 // 1822 // The Id field is a LARGE_INTEGER where the High and Low parts can be 1823 // accessed separately. 1824 // 1825 // The following macros are used to access the Fid fields. 1826 // 1827 // CdQueryFidDirentOffset - Accesses the Dirent offset field 1828 // CdQueryFidPathTableNumber - Accesses the PathTable offset field 1829 // CdSetFidDirentOffset - Sets the Dirent offset field 1830 // CdSetFidPathTableNumber - Sets the PathTable ordinal field 1831 // CdFidIsDirectory - Queries if directory bit is set 1832 // CdFidSetDirectory - Sets directory bit 1833 // 1834 1835 #define FID_DIR_MASK 0x80000000 // high order bit means directory. 1836 1837 #define CdQueryFidDirentOffset(I) ((I).LowPart & ~FID_DIR_MASK) 1838 #define CdQueryFidPathTableOffset(I) ((I).HighPart) 1839 #define CdSetFidDirentOffset(I,D) ((I).LowPart = D) 1840 #define CdSetFidPathTableOffset(I,P) ((I).HighPart = P) 1841 #define CdFidIsDirectory(I) FlagOn( (I).LowPart, FID_DIR_MASK ) 1842 #define CdFidSetDirectory(I) SetFlag( (I).LowPart, FID_DIR_MASK ) 1843 1844 #define CdSetFidFromParentAndDirent(I,F,D) { \ 1845 CdSetFidPathTableOffset( (I), CdQueryFidPathTableOffset( (F)->FileId )); \ 1846 CdSetFidDirentOffset( (I), (D)->DirentOffset ); \ 1847 if (FlagOn( (D)->DirentFlags, CD_ATTRIBUTE_DIRECTORY )) { \ 1848 CdFidSetDirectory((I)); \ 1849 } \ 1850 } 1851 1852 #ifdef CDFS_TELEMETRY_DATA 1853 // ============================================================================ 1854 // ============================================================================ 1855 // 1856 // Telemetry 1857 // 1858 // ============================================================================ 1859 // ============================================================================ 1860 1861 typedef struct _CDFS_TELEMETRY_DATA_CONTEXT { 1862 1863 // 1864 // Number of times there was not enough stack space to generate telemetry 1865 // 1866 1867 volatile LONG MissedTelemetryPoints; 1868 1869 // 1870 // System Time of the last periodic telemtry event. System Time 1871 // is according to KeQuerySystemTime() 1872 // 1873 1874 LARGE_INTEGER LastPeriodicTelemetrySystemTime; 1875 1876 // 1877 // TickCount of the last periodic telemtry event. TickCount is 1878 // according to KeQueryTickCount() 1879 // 1880 1881 LARGE_INTEGER LastPeriodicTelemetryTickCount; 1882 1883 // 1884 // Hint for Worker thread whether to generate 1885 // periodic telemetry or not 1886 // 1887 1888 BOOLEAN GeneratePeriodicTelemetry; 1889 1890 // 1891 // Guid for ID parity with other file systems telemetry. 1892 // 1893 1894 GUID VolumeGuid; 1895 1896 1897 #if DBG 1898 1899 // 1900 // For DBG builds we want a machanism to change the frequency of 1901 // periodic events 1902 // 1903 1904 LONGLONG PeriodicInterval; 1905 1906 #endif 1907 1908 // 1909 // File system statistics at time of last period telemetry event 1910 // 1911 1912 FILESYSTEM_STATISTICS CommonStats; 1913 1914 } CDFS_TELEMETRY_DATA_CONTEXT, *PCDFS_TELEMETRY_DATA_CONTEXT; 1915 1916 #endif // CDFS_TELEMETRY_DATA 1917 1918 #endif // _CDSTRUC_ 1919 1920