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