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