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