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