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