test: udfstruc.h Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# udfstruc.h

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1989  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     UdfStruc.h
    00008
    00009 Abstract:
    00010
    00011     This module defines the data structures that make up the major internal
    00012     parts of the Udfs file system.
    00013
    00014     In-Memory structures:
    00015
    00016         The global data structures with the UdfDataRecord.  It contains a pointer
    00017         to a File System Device object and a queue of Vcb's.  There is a Vcb for
    00018         every currently or previously mounted volumes.  We may be in the process
    00019         of tearing down the Vcb's which have been dismounted.  The Vcb's are
    00020         allocated as an extension to a volume device object.
    00021
    00022             +---------+
    00023             | UdfData |     +--------+
    00024             |         | --> |FilSysDo|
    00025             |         |     |        |
    00026             |         | <+  +--------+
    00027             +---------+  |
    00028                          |
    00029                          |  +--------+     +--------+
    00030                          |  |VolDo   |     |VolDo   |
    00031                          |  |        |     |        |
    00032                          |  +--------+     +--------+
    00033                          +> |Vcb     | <-> |Vcb     | <-> ...
    00034                             |        |     |        |
    00035                             +--------+     +--------+
    00036
    00037
    00038         Each Vcb contains a table of all the Fcbs for the volume indexed by
    00039         their FileId.  Each Vcb contains a pointer to the root directory of
    00040         the volume.  Each directory Fcb contains a queue of child Lcb's for
    00041         its children.  Each Lcb is queued onto both its parent and child Fcb.
    00042         There can also be detached subtrees due to open operations by Id where
    00043         the Fcb's are not connected to the root.
    00044
    00045         The following diagram shows the root structure.
    00046
    00047             +--------+     +--------+
    00048             |  Vcb   |---->| Fcb    |-------------------------------------------------------------------+
    00049             |        |     |  Table |----------------------------------------------------------------+  |
    00050             |        |--+  |        |-------------------------------------------------------------+  |  |
    00051             +--------+  |  +--------+                                                             |  |  |
    00052                         |    |  |  |                                                              |  |  |
    00053                         |    |  |  +---------------------------------------------+                |  |  |
    00054                         |    V  +-----------------------+                        |                |  |  |
    00055                         |  +--------+                   |                        |                |  |  |
    00056                         |  |RootFcb |                   V                        V                |  |  |
    00057                         +->|        |    +-----+    +--------+               +--------+           |  |  |
    00058                            |        |<-->| Lcb |<-->|Child   |    +-----+    |Child   |           |  |  |
    00059                            +--------+    +-----+    | Fcb    |<-->| Lcb |<-->| Fcb    |<--> ...   |  |  |
    00060                                                     |        |    +-----+    |        |           |  |  |
    00061                                                     +--------+               +--------+           |  |  |
    00062                                                                                                   |  |  |
    00063                           (Freestanding sub-tree)                                                 |  |  |
    00064                           +--------+                                                              |  |  |
    00065                           |OpenById|<-------------------------------------------------------------+  |  |
    00066                           | Dir    |    +--------+                                                   |  |
    00067                           |        |--->|OpenById|<--------------------------------------------------+  |
    00068                           +--------+    | Child  |    +--------+                                        |
    00069                                         |  Dir   |--->|OpenById|<---------------------------------------+
    00070                                         +--------+    | Child  |
    00071                                                       |  File  |
    00072                                                       +--------+
    00073
    00074         Attached to each Directory Fcb is an prefix table containing the
    00075         Lcbs pointing to children of this directory for which there is an Fcb.
    00076
    00077             +--------+      +--------+
    00078             |  Dir   |      | Prefix |
    00079             |   Fcb  |----->|  Table |--------------------+
    00080             |        |      |        |-------+            |
    00081             +--------+      +--------+       |            |
    00082                 ^              |             |            |
    00083                 |              |             |            |
    00084                 |              V             V            V
    00085                 |           +--------+    +--------+    +--------+
    00086                 |           |  Lcb   |    |  Lcb   |    |  Lcb   |
    00087                 +---------->|        |<-->|        |<-->|        |
    00088                             +--------+    +--------+    +--------+
    00089
    00090         Each file object open on a UDF volume contains two context pointers.  The
    00091         first will point back to the Fcb for the file object.  The second, if present,
    00092         points to a Ccb (ContextControlBlock) which contains the per-handle information.
    00093         This includes the state of any directory enumeration and the Lcb used to open
    00094         this file object.
    00095
    00096           +--------+       +--------+    +--------+
    00097           |  Fcb   |<------| File   |    |  Ccb   |
    00098           |        |       |  Object|--->|        |
    00099           |        |       |        |    |        |
    00100           +--------+       +--------+    +--------+
    00101             ^    ^
    00102             |    |         +--------+    +--------+
    00103             |    |         | File   |    |  Ccb   |
    00104             |    +---------|  Object|--->|        |
    00105             |              |        |    |        |
    00106             |              +--------+    +--------+
    00107             |
    00108             |              +--------+
    00109             |              |Stream  |
    00110             +--------------| File   |
    00111                            |  Object|
    00112                            +--------+
    00113
    00114
    00115     Synchronization:
    00116
    00117         1. A resource in the UdfData synchronizes access to the Vcb queue.  This
    00118             is used during mount/verify/dismount operations.
    00119
    00120         2. A resource in the Vcb is used to synchronize access to Vcb for
    00121             open/close operations.  Typically acquired shared, it
    00122             is acquired exclusively to lock out these operations.
    00123
    00124         3. A second resource in the Vcb is used to synchronize all file operations.
    00125             Typically acquired shared, it is acquired exclusively to lock
    00126             out all file operations.  Acquiring both Vcb resources will lock
    00127             the entire volume.
    00128
    00129         4. A resource in the nonpaged Fcb will synchronize open/close operations
    00130             on an Fcb.
    00131
    00132         5. A fast mutex in the Vcb will protect access to the Fcb table and
    00133             the open counts in the Vcb.  It is also used to modify the reference
    00134             counts in all Fcbs/Lcbs.  This mutex cannot be acquired
    00135             exclusely and is an end resource.
    00136
    00137         6. A fast mutex in the Fcb will synchronize access to all Fcb fields
    00138             which aren't synchronized in some other way.  A thread may acquire
    00139             mutexes for multiple Fcb's as long as it works it way toward the
    00140             root of the tree.  This mutex can also be acquired recursively.
    00141
    00142         7. Normal locking order is UdfData/Vcb/Fcb starting at any point in this
    00143             chain.  The Vcb is required prior to acquiring resources for multiple
    00144             files.  Shared ownership of the Vcb is sufficient in this case.
    00145
    00146         8. Normal locking order when acquiring multiple Fcb's is from some
    00147             starting Fcb and walking towards the root of tree.  Create typically
    00148             walks down the tree.  In this case we will attempt to acquire the
    00149             next node optimistically and if that fails we will reference
    00150             the current node in the tree, release it and acquire the next node.
    00151             At that point it will be safe to reacquire the parent node.
    00152
    00153         9. Locking order for the Fcb (via the fast mutex) will be from leaf of
    00154             tree back towards the root.  No other resource may be acquired
    00155             after locking the Vcb (other than in-page reads).
    00156
    00157        10. Cleanup operations only lock the Vcb and Fcb long enough to change the
    00158             critical counts and share access fields.  No reason to synchronize
    00159             otherwise.  None of the structures can go away from beneath us
    00160             in this case.
    00161
    00162 Author:
    00163
    00164     Dan Lovinger    [DanLo]   31-May-1996
    00165
    00166 Revision History:
    00167
    00168 --*/
    00169
    00170 #ifndef _UDFSTRUC_
    00171 #define _UDFSTRUC_
    00172
    00173 typedef PVOID PBCB;
    00174
    00175
    00176 //
    00177 //  The following structure is used to encapsulate the converted timestamps for
    00178 //  straightforward referencing.
    00179 //
    00180
    00181 typedef struct _TIMESTAMP_BUNDLE {
    00182
    00183     LARGE_INTEGER   CreationTime;
    00184     LARGE_INTEGER   AccessTime;
    00185     LARGE_INTEGER   ModificationTime;
    00186
    00187 } TIMESTAMP_BUNDLE, *PTIMESTAMP_BUNDLE;
    00188
    00189
    00190 //
    00191 //  The UDF_DATA record is the top record in the UDF file system in-memory
    00192 //  data structure.  This structure must be allocated from non-paged pool.
    00193 //
    00194
    00195 #define NUMBER_OF_FS_OBJECTS    2
    00196
    00197 typedef struct _UDF_DATA {
    00198
    00199     //
    00200     //  The type and size of this record (must be UDFS_NTC_DATA_HEADER)
    00201     //
    00202
    00203     NODE_TYPE_CODE NodeTypeCode;
    00204     NODE_BYTE_SIZE NodeByteSize;
    00205
    00206     //
    00207     //  A pointer to the Driver object we were initialized with
    00208     //
    00209
    00210     PDRIVER_OBJECT DriverObject;
    00211
    00212     //
    00213     //  Vcb queue.
    00214     //
    00215
    00216     LIST_ENTRY VcbQueue;
    00217
    00218     //
    00219     //  The following fields are used to allocate IRP context structures
    00220     //  using a lookaside list, and other fixed sized structures from a
    00221     //  small cache.  We use the CdData mutex to protext these structures.
    00222     //
    00223
    00224     ULONG IrpContextDepth;
    00225     ULONG IrpContextMaxDepth;
    00226     SINGLE_LIST_ENTRY IrpContextList;
    00227
    00228     //
    00229     //  Filesystem device objects for UDFS.
    00230     //
    00231
    00232     PDEVICE_OBJECT FileSystemDeviceObjects[NUMBER_OF_FS_OBJECTS];
    00233
    00234     //
    00235     //  Following are used to manage the async and delayed close queue.
    00236     //
    00237     //  FspCloseActive - Indicates whether there is a thread processing the
    00238     //      two close queues.
    00239     //  ReduceDelayedClose - Indicates that we have hit the upper threshold
    00240     //      for the delayed close queue and need to reduce it to lower threshold.
    00241     //
    00242     //  AsyncCloseQueue - Queue of IrpContext waiting for async close operation.
    00243     //  AsyncCloseCount - Number of entries on the async close queue.
    00244     //
    00245     //  DelayedCloseQueue - Queue of IrpContextLite waiting for delayed close
    00246     //      operation.
    00247     //  MaxDelayedCloseCount - Trigger delay close work at this threshold.
    00248     //  MinDelayedCloseCount - Turn off delay close work at this threshold.
    00249     //  DelayedCloseCount - Number of entries on the delayted close queue.
    00250     //
    00251     //  CloseItem - Workqueue item used to start FspClose thread.
    00252     //
    00253
    00254     LIST_ENTRY AsyncCloseQueue;
    00255     ULONG AsyncCloseCount;
    00256     BOOLEAN FspCloseActive;
    00257     BOOLEAN ReduceDelayedClose;
    00258     USHORT PadUshort;
    00259
    00260     //
    00261     //  The following fields describe the deferred close file objects.
    00262     //
    00263
    00264     LIST_ENTRY DelayedCloseQueue;
    00265     ULONG DelayedCloseCount;
    00266     ULONG MaxDelayedCloseCount;
    00267     ULONG MinDelayedCloseCount;
    00268
    00269     //
    00270     //  Fast mutex used to lock the fields of this structure.
    00271     //
    00272
    00273     PVOID UdfDataLockThread;
    00274     FAST_MUTEX UdfDataMutex;
    00275
    00276     //
    00277     //  A resource variable to control access to the global UDFS data record
    00278     //
    00279
    00280     ERESOURCE DataResource;
    00281
    00282     //
    00283     //  Cache manager call back structure, which must be passed on each call
    00284     //  to CcInitializeCacheMap.
    00285     //
    00286
    00287     CACHE_MANAGER_CALLBACKS CacheManagerCallbacks;
    00288     CACHE_MANAGER_CALLBACKS CacheManagerVolumeCallbacks;
    00289
    00290     //
    00291     //  This is the ExWorkerItem that does both kinds of deferred closes.
    00292     //
    00293
    00294     WORK_QUEUE_ITEM CloseItem;
    00295
    00296 } UDF_DATA, *PUDF_DATA;
    00297
    00298
    00299 //
    00300 //  A PARTITION will record the VSN/LSN -> PSN retrieval information for a
    00301 //  partition reference.  Since we do not support multi-volume 13346/UDF,
    00302 //  we will omit noting the volume sequence number that would tell us which
    00303 //  piece of media contained the partition.
    00304 //
    00305 //  There are currently three types of partitions used during operation: physical,
    00306 //  sparable and virtual.  However, since sparing merely adds another last layer
    00307 //  of quick indirection, we consider them as a minor extension of a physical
    00308 //  partition.
    00309 //
    00310
    00311 typedef enum _PARTITION_TYPE {
    00312     Uninitialized,
    00313     Physical,
    00314     Virtual
    00315 } PARTITION_TYPE, *PPARTITION_TYPE;
    00316
    00317 //
    00318 //  A Physical partition corresponds to a single extent of the volume.
    00319 //
    00320
    00321 typedef struct _PARTITION_PHYSICAL {
    00322
    00323     //
    00324     //  Starting Psn and length in sectors
    00325     //
    00326
    00327     ULONG Start;
    00328     ULONG Length;
    00329
    00330     //
    00331     //  The partition number is specified by the LVD, and refers to
    00332     //  a specific partition descriptor on the media.  We use this
    00333     //  in the second pass of partition discovery.
    00334     //
    00335
    00336     ULONG PartitionNumber;
    00337     PNSR_PART PartitionDescriptor;
    00338
    00339     //
    00340     //  Spared partition map, saved temporarily between
    00341     //  logical volume descriptor analysis and partition
    00342     //  descriptor discover/pcb completion.
    00343     //
    00344
    00345     PPARTMAP_SPARABLE SparingMap;
    00346
    00347 } PARTITION_PHYSICAL, *PPARTITION_PHYSICAL;
    00348
    00349 //
    00350 //  A Virtual partition is a remapping from VSN to LSN on a given Physical
    00351 //  partition.  The remapping is done through the VAT FCB.
    00352 //
    00353
    00354 typedef struct _PARTITION_VIRTUAL{
    00355
    00356     //
    00357     //  The maximum Vbn in the virtual partition.
    00358     //
    00359
    00360     ULONG Length;
    00361
    00362     //
    00363     //  A virtual partition refers to its "host" physical partition by partition
    00364     //  number, which we translate to a partition reference during the second pass
    00365     //  of partition discovery.
    00366     //
    00367     //  Example: if the virtual partition is reference 1, hosted on partition 156
    00368     //  (which is reference 0 for this logical volume), then NSRLBA 100/1 would
    00369     //  refer to the block on partition ref 0 as mapped in the VAT at entry 100.
    00370     //
    00371
    00372     USHORT RelatedReference;
    00373
    00374 } PARTITION_VIRTUAL, *PPARTITION_VIRTUAL;
    00375
    00376 //
    00377 //  There is exactly one PARTITION per partition.  It is responsible for mapping
    00378 //  from some form of logical sector to a physical sector.
    00379 //
    00380
    00381 typedef struct _PARTITION {
    00382
    00383     //
    00384     //  This is the type of partition.
    00385     //
    00386
    00387     PARTITION_TYPE Type;
    00388
    00389     union {
    00390
    00391         PARTITION_PHYSICAL Physical;
    00392         PARTITION_VIRTUAL Virtual;
    00393     };
    00394
    00395 } PARTITION, *PPARTITION;
    00396
    00397 //
    00398 //  The Pcb (Partition control block) record corresponds to the partitions
    00399 //  which collectively form the mounted volume.  Exactly one of these is
    00400 //  linked off of the Vcb.
    00401 //
    00402
    00403 typedef struct _PCB {
    00404
    00405     //
    00406     //  The type and size of this record (must be UDFS_NTC_PCB)
    00407     //
    00408
    00409     NODE_TYPE_CODE NodeTypeCode;
    00410     NODE_BYTE_SIZE NodeByteSize;
    00411
    00412     //
    00413     //  This is the number of partitions in the map
    00414     //
    00415
    00416     USHORT Partitions;
    00417
    00418     //
    00419     //  A bitmask of flags.
    00420     //
    00421
    00422     USHORT Flags;
    00423
    00424     //
    00425     //  Sparing Mcb, if this volume has sparing.
    00426     //
    00427
    00428     PLARGE_MCB SparingMcb;
    00429
    00430     //
    00431     //  This is the mapping table.  A PCB will be dynamically sized
    00432     //  according to the number of partitions forming the volume.
    00433     //
    00434
    00435     PARTITION Partition[0];
    00436
    00437 } PCB, *PPCB;
    00438
    00439 //
    00440 //  Indicate what kinds of partitions are contained for quick checks.
    00441 //
    00442
    00443 #define PCB_FLAG_PHYSICAL_PARTITION     0x0001
    00444 #define PCB_FLAG_VIRTUAL_PARTITION      0x0002
    00445 #define PCB_FLAG_SPARABLE_PARTITION     0x0004
    00446
    00447
    00448 //
    00449 //  The Vmcb structure is a double mapped structure for mapping
    00450 //  between VBNs and LBNs using the MCB structures.  The whole structure
    00451 //  is also protected by a private mutex.  This record must be allocated
    00452 //  from non-paged pool.
    00453 //
    00454
    00455 //
    00456 //  We use an #if to snip out historical code in the Vmcb package that
    00457 //  dealt with write issues, leaving it for the future.
    00458 //
    00459
    00460 #define VMCB_WRITE_SUPPORT 0
    00461
    00462 typedef struct _VMCB {
    00463
    00464     KMUTEX Mutex;
    00465
    00466     MCB VbnIndexed;     // maps VBNs to LBNs
    00467     MCB LbnIndexed;     // maps LBNs to VBNs
    00468
    00469     ULONG MaximumLbn;
    00470
    00471     ULONG SectorSize;
    00472
    00473 #if VMCB_WRITE_SUPPORT
    00474
    00475     RTL_GENERIC_TABLE DirtyTable;
    00476
    00477 #endif // VMCB_WRITE_SUPPORT
    00478
    00479 } VMCB, *PVMCB;
    00480
    00481 //
    00482 //  The Vcb (Volume control block) record corresponds to every
    00483 //  volume mounted by the file system.  They are ordered in a queue off
    00484 //  of UdfData.VcbQueue.
    00485 //
    00486 //  The Vcb will be in several conditions during its lifespan.
    00487 //
    00488 //      NotMounted - Disk is not currently mounted (i.e. removed
    00489 //          from system) but cleanup and close operations are
    00490 //          supported.
    00491 //
    00492 //      MountInProgress - State of the Vcb from the time it is
    00493 //          created until it is successfully mounted or the mount
    00494 //          fails.
    00495 //
    00496 //      Mounted - Volume is currently in the mounted state.
    00497 //
    00498 //      Invalid - User has invalidated the volume.  Only legal operations
    00499 //          are cleanup and close.
    00500 //
    00501 //      DismountInProgress - We have begun the process of tearing down the
    00502 //          Vcb.  It can be deleted when all the references to it
    00503 //          have gone away.
    00504 //
    00505
    00506 typedef enum _VCB_CONDITION {
    00507
    00508     VcbNotMounted = 0,
    00509     VcbMountInProgress,
    00510     VcbMounted,
    00511     VcbInvalid,
    00512     VcbDismountInProgress
    00513
    00514 } VCB_CONDITION;
    00515
    00516 typedef struct _VCB {
    00517
    00518     //
    00519     //  The type and size of this record (must be UDFS_NTC_VCB)
    00520     //
    00521
    00522     NODE_TYPE_CODE NodeTypeCode;
    00523     NODE_BYTE_SIZE NodeByteSize;
    00524
    00525     //
    00526     //  Vpb for this volume.
    00527     //
    00528
    00529     PVPB Vpb;
    00530
    00531     //
    00532     //  Pcb for this volume.
    00533     //
    00534
    00535     PPCB Pcb;
    00536
    00537     //
    00538     //  Device object for the driver below us.
    00539     //
    00540
    00541     PDEVICE_OBJECT TargetDeviceObject;
    00542
    00543     //
    00544     //  Link into queue of Vcb's in the UdfData structure.  We will create a union with
    00545     //  a LONGLONG to force the Vcb to be quad-aligned.
    00546     //
    00547
    00548     union {
    00549
    00550         LIST_ENTRY VcbLinks;
    00551         LONGLONG Alignment;
    00552     };
    00553
    00554     //
    00555     //  State flags and condition for the Vcb.
    00556     //
    00557
    00558     ULONG VcbState;
    00559     VCB_CONDITION VcbCondition;
    00560
    00561     //
    00562     //  File object used to lock the volume.
    00563     //
    00564
    00565     PFILE_OBJECT VolumeLockFileObject;
    00566
    00567     //
    00568     //  Media change count from device driver for bulletproof detection
    00569     //  of media movement
    00570     //
    00571
    00572     ULONG MediaChangeCount;
    00573
    00574     //
    00575     //  Logical block size for this volume.
    00576     //
    00577
    00578     ULONG SectorSize;
    00579
    00580     //
    00581     //  Associated shift size
    00582     //
    00583
    00584     ULONG SectorShift;
    00585
    00586     //
    00587     //  LSN of the bounds that CD-UDF defines.
    00588     //
    00589     //  S - start of the session that contains the AVD @ +256
    00590     //  N - end of the disc, another chance to find AVD @ -256,
    00591     //      and discovery of the VAT ICB.
    00592     //
    00593     //  N may be unset until late in the mount sequence for a volume, since
    00594     //  the device may not respond to CD-style TOC requests, and only then
    00595     //  be a guess based on the partitons we find. S will be zero except in
    00596     //  the case of CD-UDF.  In a mounted system, S will correspond to where
    00597     //  we started finding the volume descriptors that let us proceed.
    00598     //
    00599
    00600     ULONG BoundS;
    00601     ULONG BoundN;
    00602
    00603     //
    00604     //  Various counts for this Vcb.
    00605     //
    00606     //      VcbCleanup - Open handles left on this system.
    00607     //      VcbReference - Number of reasons this Vcb is still present.
    00608     //      VcbUserReference - Number of user file objects still present.
    00609     //
    00610
    00611     ULONG VcbCleanup;
    00612     ULONG VcbReference;
    00613     ULONG VcbUserReference;
    00614
    00615     //
    00616     //  These are the number of times a mounted Vcb will be referenced on behalf
    00617     //  of the system.  See commentary in udfdata.h.
    00618     //
    00619
    00620     ULONG VcbResidualReference;
    00621     ULONG VcbResidualUserReference;
    00622
    00623     //
    00624     //  Fcb for the Volume Dasd file, root directory and the Vmcb-mapped Metadata stream.
    00625     //  The VAT Fcb is only created on CD UDF media, for the Virtual Allocation Table.
    00626     //
    00627
    00628     struct _FCB *VolumeDasdFcb;
    00629     struct _FCB *RootIndexFcb;
    00630     struct _FCB *MetadataFcb;
    00631     struct _FCB *VatFcb;
    00632
    00633     //
    00634     //  Vmcb for the metadata stream
    00635     //
    00636
    00637     VMCB Vmcb;
    00638
    00639     //
    00640     //  Vcb resource.  This is used to synchronize open/cleanup/close operations.
    00641     //
    00642
    00643     ERESOURCE VcbResource;
    00644
    00645     //
    00646     //  File resource.  This is used to synchronize all file operations except
    00647     //  open/cleanup/close.
    00648     //
    00649
    00650     ERESOURCE FileResource;
    00651
    00652     //
    00653     //  Vcb fast mutex.  This is used to synchronize the fields in the Vcb
    00654     //  when modified when the Vcb is not held exclusively.  Included here
    00655     //  are the count fields and Fcb table.
    00656     //
    00657     //  We also use this to synchronize changes to the Fcb reference field.
    00658     //
    00659
    00660     FAST_MUTEX VcbMutex;
    00661     PVOID VcbLockThread;
    00662
    00663     //
    00664     //  The following is used to synchronize the dir notify package.
    00665     //
    00666
    00667     PNOTIFY_SYNC NotifySync;
    00668
    00669     //
    00670     //  The following is the head of a list of notify Irps.
    00671     //
    00672
    00673     LIST_ENTRY DirNotifyList;
    00674
    00675     //
    00676     //  Fcb table.  Synchronized with the Vcb fast mutex.
    00677     //
    00678
    00679     RTL_GENERIC_TABLE FcbTable;
    00680
    00681 } VCB, *PVCB;
    00682
    00683 #define VCB_STATE_LOCKED                            (0x00000001)
    00684 #define VCB_STATE_REMOVABLE_MEDIA                   (0x00000002)
    00685 #define VCB_STATE_NOTIFY_REMOUNT                    (0x00000004)
    00686 #define VCB_STATE_METHOD_2_FIXUP                    (0x00000008)
    00687
    00688
    00689 //
    00690 //  The Volume Device Object is an I/O system device object with a
    00691 //  workqueue and an VCB record appended to the end.  There are multiple
    00692 //  of these records, one for every mounted volume, and are created during
    00693 //  a volume mount operation.  The work queue is for handling an overload
    00694 //  of work requests to the volume.
    00695 //
    00696
    00697 typedef struct _VOLUME_DEVICE_OBJECT {
    00698
    00699     DEVICE_OBJECT DeviceObject;
    00700
    00701     //
    00702     //  The following field tells how many requests for this volume have
    00703     //  either been enqueued to ExWorker threads or are currently being
    00704     //  serviced by ExWorker threads.  If the number goes above
    00705     //  a certain threshold, put the request on the overflow queue to be
    00706     //  executed later.
    00707     //
    00708
    00709     ULONG PostedRequestCount;
    00710
    00711     //
    00712     //  The following field indicates the number of IRP's waiting
    00713     //  to be serviced in the overflow queue.
    00714     //
    00715
    00716     ULONG OverflowQueueCount;
    00717
    00718     //
    00719     //  The following field contains the queue header of the overflow queue.
    00720     //  The Overflow queue is a list of IRP's linked via the IRP's ListEntry
    00721     //  field.
    00722     //
    00723
    00724     LIST_ENTRY OverflowQueue;
    00725
    00726     //
    00727     //  The following spinlock protects access to all the above fields.
    00728     //
    00729
    00730     KSPIN_LOCK OverflowQueueSpinLock;
    00731
    00732     //
    00733     //  This is the file system specific volume control block.
    00734     //
    00735
    00736     VCB Vcb;
    00737
    00738 } VOLUME_DEVICE_OBJECT, *PVOLUME_DEVICE_OBJECT;
    00739
    00740
    00741 //
    00742 //  Udfs file id is a large integer. This corresponds to the FileInternalInformation
    00743 //  query type and is used for internal FCB indexing.
    00744 //
    00745
    00746 typedef LARGE_INTEGER                   FILE_ID, *PFILE_ID;
    00747
    00748
    00749 //
    00750 //  Lcb (Link Control Block), which corresponds to a link from a directory (or in
    00751 //  the future, other container objects) to a file (UDF File Identifier).  There is
    00752 //  one of these for each name tuple in a prefix table.
    00753 //
    00754
    00755 typedef struct _LCB {
    00756
    00757     //
    00758     //  Type and size of this record (must be UDFS_NTC_LCB)
    00759     //
    00760
    00761     NODE_TYPE_CODE NodeTypeCode;
    00762     NODE_BYTE_SIZE NodeByteSize;
    00763
    00764     //
    00765     //  Pointer to the Parent Fcb for this entry and queue for Parent to
    00766     //  find all referencing Lcbs.  Corresponds to Fcb->ChildLcbQueue.
    00767     //
    00768
    00769     LIST_ENTRY ParentFcbLinks;
    00770     struct _FCB *ParentFcb;
    00771
    00772     //
    00773     //  Pointer to Child (referenced) Fcb for this entry and queue for Child
    00774     //  to find all referencing Lcbs.  Corresponds to Fcb->ParentLcbQueue.
    00775     //
    00776
    00777     LIST_ENTRY ChildFcbLinks;
    00778     struct _FCB *ChildFcb;
    00779
    00780     //
    00781     //  Number of extra realtime references made to this Lcb.
    00782     //
    00783
    00784     ULONG Reference;
    00785
    00786     //
    00787     //  Flags indicating the state of this Lcb.
    00788     //
    00789
    00790     ULONG Flags;
    00791
    00792     //
    00793     //  File attributes to be merged with the child Fcb.  UDF seperates interesting
    00794     //  information into the FID and FE so, properly, the name link (corresponding to
    00795     //  a FID) must record some extra information.
    00796     //
    00797
    00798     ULONG FileAttributes;
    00799
    00800     //
    00801     //  Splay links in the prefix tree.
    00802     //
    00803
    00804     RTL_SPLAY_LINKS Links;
    00805
    00806     //
    00807     //  The name of this link.
    00808     //
    00809
    00810     UNICODE_STRING FileName;
    00811
    00812 } LCB, *PLCB;
    00813
    00814 #define LCB_FLAG_IGNORE_CASE        0x00000001
    00815 #define LCB_FLAG_SHORT_NAME         0x00000002
    00816 #define LCB_FLAG_POOL_ALLOCATED     0x00000004
    00817
    00818 //
    00819 //  We build a lookaside of Lcb capable of holding a reasonably sized name.
    00820 //
    00821
    00822 #define SIZEOF_LOOKASIDE_LCB        ( sizeof( LCB ) + ( sizeof( WCHAR ) * 16 ))
    00823
    00824
    00825 //
    00826 //  The following two structures are the separate union structures for
    00827 //  data and index Fcb's.
    00828 //
    00829
    00830 typedef enum _FCB_CONDITION {
    00831     FcbGood = 1,
    00832     FcbBad,
    00833     FcbNeedsToBeVerified
    00834 } FCB_CONDITION;
    00835
    00836 typedef struct _FCB_NONPAGED {
    00837
    00838     //
    00839     //  Type and size of this record must be UDFS_NTC_FCB_NONPAGED
    00840     //
    00841
    00842     NODE_TYPE_CODE NodeTypeCode;
    00843     NODE_BYTE_SIZE NodeByteSize;
    00844
    00845     //
    00846     //  The following field contains a record of special pointers used by
    00847     //  MM and Cache to manipluate section objects.  Note that the values
    00848     //  are set outside of the file system.  However the file system on an
    00849     //  open/create will set the file object's SectionObject field to
    00850     //  point to this field
    00851     //
    00852
    00853     SECTION_OBJECT_POINTERS SegmentObject;
    00854
    00855     //
    00856     //  This is the resource structure for this Fcb.
    00857     //
    00858
    00859     ERESOURCE FcbResource;
    00860
    00861     //
    00862     //  This is the FastMutex for this Fcb.
    00863     //
    00864
    00865     FAST_MUTEX FcbMutex;
    00866
    00867 } FCB_NONPAGED;
    00868 typedef FCB_NONPAGED *PFCB_NONPAGED;
    00869
    00870 typedef struct _FCB_DATA {
    00871
    00872     //
    00873     //  The following field is used by the oplock module
    00874     //  to maintain current oplock information.
    00875     //
    00876
    00877     OPLOCK Oplock;
    00878
    00879     //
    00880     //  The following field is used by the filelock module
    00881     //  to maintain current byte range locking information.
    00882     //  A file lock is allocated as needed.
    00883     //
    00884
    00885     PFILE_LOCK FileLock;
    00886
    00887 } FCB_DATA, *PFCB_DATA;
    00888
    00889 typedef struct _FCB_INDEX {
    00890
    00891     //
    00892     //  Internal stream file for the directory.
    00893     //
    00894
    00895     PFILE_OBJECT FileObject;
    00896
    00897     //
    00898     //  Root of splay trees for exact and ignore case prefix trees.
    00899     //
    00900
    00901     PRTL_SPLAY_LINKS ExactCaseRoot;
    00902     PRTL_SPLAY_LINKS IgnoreCaseRoot;
    00903
    00904 } FCB_INDEX, *PFCB_INDEX;
    00905
    00906 //
    00907 //  The Fcb/Dcb record corresponds to every open file and directory, and to
    00908 //  every directory on an opened path.
    00909 //
    00910
    00911 typedef struct _FCB {
    00912
    00913     //
    00914     //  The following field is used for fast I/O.  It contains the node
    00915     //  type code and size, indicates if fast I/O is possible, contains
    00916     //  allocation, file, and valid data size, a resource, and call back
    00917     //  pointers for FastIoRead and FastMdlRead.
    00918     //
    00919     //
    00920     //  Node type codes for the Fcb must be one of the following.
    00921     //
    00922     //      UDFS_NTC_FCB_INDEX
    00923     //      UDFS_NTC_FCB_DATA
    00924     //
    00925
    00926     //
    00927     //  Common Fsrtl Header.  The named header is for the fieldoff.c output.  We
    00928     //  use the unnamed header internally.
    00929     //
    00930
    00931     union {
    00932
    00933         FSRTL_COMMON_FCB_HEADER Header;
    00934         FSRTL_COMMON_FCB_HEADER;
    00935     };
    00936
    00937     //
    00938     //  Vcb for this Fcb.
    00939     //
    00940
    00941     PVCB Vcb;
    00942
    00943     //
    00944     //  Queues of Lcbs that are on this Fcb: Parent - edges that lead in
    00945     //                                       Child  - edges that lead out
    00946     //
    00947     //  We anticipate supporting the streaming extension to UDF 2.0, so we
    00948     //  leave the ChildLcbQueue here which in the case of a stream-rich file
    00949     //  will contain a solitary Lcb leading to the stream directory.
    00950     //
    00951
    00952     LIST_ENTRY ParentLcbQueue;
    00953     LIST_ENTRY ChildLcbQueue;
    00954
    00955     //
    00956     //  Length of Root ICB Extent for this object.  Coupled with the information
    00957     //  in the FileId, this will allow discovery of the active File Entry for this
    00958     //  Fcb at any time.
    00959     //
    00960
    00961     ULONG RootExtentLength;
    00962
    00963     //
    00964     //  FileId for this file.
    00965     //
    00966
    00967     FILE_ID FileId;
    00968
    00969     //
    00970     //  Counts on this Fcb.  Cleanup count represents the number of open handles
    00971     //  on this Fcb.  Reference count represents the number of reasons this Fcb
    00972     //  is still present.  It includes file objects, children Fcb and anyone
    00973     //  who wants to prevent this Fcb from going away.  Cleanup count is synchronized
    00974     //  with the FcbResource.  The reference count is synchronized with the
    00975     //  FcbMutex.
    00976     //
    00977
    00978     ULONG FcbCleanup;
    00979     ULONG FcbReference;
    00980     ULONG FcbUserReference;
    00981
    00982     //
    00983     //  State flags for this Fcb.
    00984     //
    00985
    00986     ULONG FcbState;
    00987
    00988     //
    00989     //  NT style attributes for the Fcb.
    00990     //
    00991
    00992     ULONG FileAttributes;
    00993
    00994     //
    00995     //  This is the thread and count for the thread which has locked this
    00996     //  Fcb.
    00997     //
    00998
    00999     PVOID FcbLockThread;
    01000     ULONG FcbLockCount;
    01001
    01002     //
    01003     //  Information for Lsn->Psn mapping.  If the file data is embedded, we have a
    01004     //  lookup into the metadata stream for the single logical block and an offset
    01005     //  of the data within that block.  If the file data is is external, we have a
    01006     //  regular Mapping Control Block.
    01007     //
    01008     //  Metadata structures are mapped through the volume-level Metadata Fcb which
    01009     //  uses the volume's VMCB.
    01010     //
    01011
    01012     union {
    01013
    01014         LARGE_MCB Mcb;
    01015
    01016         struct EMBEDDED_MAPPING {
    01017
    01018             ULONG EmbeddedVsn;
    01019             ULONG EmbeddedOffset;
    01020         };
    01021     };
    01022
    01023     //
    01024     //  This is the nonpaged data for the Fcb
    01025     //
    01026
    01027     PFCB_NONPAGED FcbNonpaged;
    01028
    01029     //
    01030     //  Share access structure.
    01031     //
    01032
    01033     SHARE_ACCESS ShareAccess;
    01034
    01035     //
    01036     //  We cache a few fields from the FE so that various operations do not have to
    01037     //  hit the disk (query, etc.).
    01038     //
    01039
    01040     //
    01041     //  Time stamps for this file.
    01042     //
    01043
    01044     TIMESTAMP_BUNDLE Timestamps;
    01045
    01046     //
    01047     //  Link count on this file.
    01048     //
    01049
    01050     USHORT LinkCount;
    01051
    01052     union {
    01053
    01054         ULONG FcbType;
    01055         FCB_INDEX;
    01056         FCB_DATA;
    01057     };
    01058
    01059 } FCB, *PFCB;
    01060
    01061 #define FCB_STATE_INITIALIZED                   (0x00000001)
    01062 #define FCB_STATE_IN_FCB_TABLE                  (0x00000002)
    01063 #define FCB_STATE_VMCB_MAPPING                  (0x00000004)
    01064 #define FCB_STATE_EMBEDDED_DATA                 (0x00000008)
    01065 #define FCB_STATE_MCB_INITIALIZED               (0x00000010)
    01066
    01067 #define SIZEOF_FCB_DATA              \
    01068     (FIELD_OFFSET( FCB, FcbType ) + sizeof( FCB_DATA ))
    01069
    01070 #define SIZEOF_FCB_INDEX             \
    01071     (FIELD_OFFSET( FCB, FcbType ) + sizeof( FCB_INDEX ))
    01072
    01073
    01074 //
    01075 //  The Ccb record is allocated for every user file object
    01076 //
    01077
    01078 typedef struct _CCB {
    01079
    01080     //
    01081     //  Type and size of this record (must be UDFS_NTC_CCB)
    01082     //
    01083
    01084     NODE_TYPE_CODE NodeTypeCode;
    01085     NODE_BYTE_SIZE NodeByteSize;
    01086
    01087     //
    01088     //  Flags.  Indicates flags to apply for the current open.
    01089     //
    01090
    01091     ULONG Flags;
    01092
    01093     //
    01094     //  Fcb for the file being opened.
    01095     //
    01096
    01097     PFCB Fcb;
    01098
    01099     //
    01100     //  Lcb for the file being opened.
    01101     //
    01102
    01103     PLCB Lcb;
    01104
    01105     //
    01106     //  We store state information in the Ccb for a directory
    01107     //  enumeration on this handle.
    01108     //
    01109
    01110     //
    01111     //  Offset in the virtual directory stream to base the next enumeration.
    01112     //
    01113     //  A small number (in fact, possibly one) of file indices are reserved for
    01114     //  synthesized directory entries (like '.'). Past that point, CurrentFileIndex -
    01115     //  UDF_MAX_SYNTHESIZED_FILEINDEX is a byte offset in the stream.
    01116     //
    01117
    01118     LONGLONG CurrentFileIndex;
    01119     UNICODE_STRING SearchExpression;
    01120
    01121     //
    01122     //  Highest ULONG-representable FileIndex so far found in the directory stream.
    01123     //  This corresponds to the highest FileIndex returnable in a query structure.
    01124     //
    01125
    01126     ULONG HighestReturnableFileIndex;
    01127
    01128 } CCB, *PCCB;
    01129
    01130 #define CCB_FLAG_OPEN_BY_ID                     (0x00000001)
    01131 #define CCB_FLAG_OPEN_RELATIVE_BY_ID            (0x00000002)
    01132 #define CCB_FLAG_IGNORE_CASE                    (0x00000004)
    01133
    01134 //
    01135 //  Following flags refer to index enumeration.
    01136 //
    01137
    01138 #define CCB_FLAG_ENUM_NAME_EXP_HAS_WILD         (0x00010000)
    01139 #define CCB_FLAG_ENUM_MATCH_ALL                 (0x00020000)
    01140 #define CCB_FLAG_ENUM_RETURN_NEXT               (0x00040000)
    01141 #define CCB_FLAG_ENUM_INITIALIZED               (0x00080000)
    01142 #define CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY    (0x00100000)
    01143
    01144
    01145 //
    01146 //  The Irp Context record is allocated for every orginating Irp.  It is
    01147 //  created by the Fsd dispatch routines, and deallocated by the UdfComplete
    01148 //  request routine
    01149 //
    01150
    01151 typedef struct _IRP_CONTEXT {
    01152
    01153     //
    01154     //  Type and size of this record (must be UDFS_NTC_IRP_CONTEXT)
    01155     //
    01156
    01157     NODE_TYPE_CODE NodeTypeCode;
    01158     NODE_BYTE_SIZE NodeByteSize;
    01159
    01160     //
    01161     //  Originating Irp for the request.
    01162     //
    01163
    01164     PIRP Irp;
    01165
    01166     //
    01167     //  Vcb for this operation.  When this is NULL it means we were called
    01168     //  with our filesystem device object instead of a volume device object.
    01169     //  (Mount will fill this in once the Vcb is created)
    01170     //
    01171
    01172     PVCB Vcb;
    01173
    01174     //
    01175     //  Exception encountered during the request.  Any error raised explicitly by
    01176     //  the file system will be stored here.  Any other error raised by the system
    01177     //  is stored here after normalizing it.
    01178     //
    01179
    01180     NTSTATUS ExceptionStatus;
    01181
    01182     //
    01183     //  Flags for this request.
    01184     //
    01185
    01186     ULONG Flags;
    01187
    01188     //
    01189     //  Real device object.  This represents the physical device closest to the media.
    01190     //
    01191
    01192     PDEVICE_OBJECT RealDevice;
    01193
    01194     //
    01195     //  Io context for a read request.
    01196     //  Address of Fcb for teardown oplock in create case.
    01197     //
    01198
    01199     union {
    01200
    01201         struct _UDF_IO_CONTEXT *IoContext;
    01202         PFCB *TeardownFcb;
    01203     };
    01204
    01205     //
    01206     //  Top level irp context for this thread.
    01207     //
    01208
    01209     struct _IRP_CONTEXT *TopLevel;
    01210
    01211     //
    01212     //  Major and minor function codes.
    01213     //
    01214
    01215     UCHAR MajorFunction;
    01216     UCHAR MinorFunction;
    01217
    01218     //
    01219     //  Pointer to the top-level context if this IrpContext is responsible
    01220     //  for cleaning it up.
    01221     //
    01222
    01223     struct _THREAD_CONTEXT *ThreadContext;
    01224
    01225     //
    01226     //  This structure is used for posting to the Ex worker threads.
    01227     //
    01228
    01229     WORK_QUEUE_ITEM WorkQueueItem;
    01230
    01231 } IRP_CONTEXT, *PIRP_CONTEXT;
    01232
    01233 #define IRP_CONTEXT_FLAG_ON_STACK               (0x00000001)
    01234 #define IRP_CONTEXT_FLAG_MORE_PROCESSING        (0x00000002)
    01235 #define IRP_CONTEXT_FLAG_WAIT                   (0x00000004)
    01236 #define IRP_CONTEXT_FLAG_FORCE_POST             (0x00000008)
    01237 #define IRP_CONTEXT_FLAG_TOP_LEVEL              (0x00000010)
    01238 #define IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS         (0x00000020)
    01239 #define IRP_CONTEXT_FLAG_IN_FSP                 (0x00000040)
    01240 #define IRP_CONTEXT_FLAG_IN_TEARDOWN            (0x00000080)
    01241 #define IRP_CONTEXT_FLAG_ALLOC_IO               (0x00000100)
    01242 #define IRP_CONTEXT_FLAG_DISABLE_POPUPS         (0x00000200)
    01243
    01244 //
    01245 //  Flags used for create.
    01246 //
    01247
    01248 #define IRP_CONTEXT_FLAG_FULL_NAME              (0x10000000)
    01249 #define IRP_CONTEXT_FLAG_TRAIL_BACKSLASH        (0x20000000)
    01250
    01251 //
    01252 //  The following flags need to be cleared when a request is posted.
    01253 //
    01254
    01255 #define IRP_CONTEXT_FLAGS_CLEAR_ON_POST (   \
    01256     IRP_CONTEXT_FLAG_MORE_PROCESSING    |   \
    01257     IRP_CONTEXT_FLAG_WAIT               |   \
    01258     IRP_CONTEXT_FLAG_FORCE_POST         |   \
    01259     IRP_CONTEXT_FLAG_TOP_LEVEL          |   \
    01260     IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS     |   \
    01261     IRP_CONTEXT_FLAG_IN_FSP             |   \
    01262     IRP_CONTEXT_FLAG_IN_TEARDOWN        |   \
    01263     IRP_CONTEXT_FLAG_DISABLE_POPUPS         \
    01264 )
    01265
    01266 //
    01267 //  The following flags need to be cleared when a request is retried.
    01268 //
    01269
    01270 #define IRP_CONTEXT_FLAGS_CLEAR_ON_RETRY (  \
    01271     IRP_CONTEXT_FLAG_MORE_PROCESSING    |   \
    01272     IRP_CONTEXT_FLAG_IN_TEARDOWN        |   \
    01273     IRP_CONTEXT_FLAG_DISABLE_POPUPS         \
    01274 )
    01275
    01276 //
    01277 //  The following flags are set each time through the Fsp loop.
    01278 //
    01279
    01280 #define IRP_CONTEXT_FSP_FLAGS (             \
    01281     IRP_CONTEXT_FLAG_WAIT               |   \
    01282     IRP_CONTEXT_FLAG_TOP_LEVEL          |   \
    01283     IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS     |   \
    01284     IRP_CONTEXT_FLAG_IN_FSP                 \
    01285 )
    01286
    01287
    01288 //
    01289 //  Following structure is used to queue a request to the delayed close queue.
    01290 //  This structure should be the minimum block allocation size.
    01291 //
    01292
    01293 typedef struct _IRP_CONTEXT_LITE {
    01294
    01295     //
    01296     //  Type and size of this record (must be UDFS_NTC_IRP_CONTEXT_LITE)
    01297     //
    01298
    01299     NODE_TYPE_CODE NodeTypeCode;
    01300     NODE_BYTE_SIZE NodeByteSize;
    01301
    01302     //
    01303     //  Fcb for the file object being closed.
    01304     //
    01305
    01306     PFCB Fcb;
    01307
    01308     //
    01309     //  List entry to attach to delayed close queue.
    01310     //
    01311
    01312     LIST_ENTRY DelayedCloseLinks;
    01313
    01314     //
    01315     //  User reference count for the file object being closed.
    01316     //
    01317
    01318     ULONG UserReference;
    01319
    01320     //
    01321     //  Real device object.  This represents the physical device closest to the media.
    01322     //
    01323
    01324     PDEVICE_OBJECT RealDevice;
    01325
    01326 } IRP_CONTEXT_LITE, *PIRP_CONTEXT_LITE;
    01327
    01328
    01329 //
    01330 //  Context structure for asynchronous I/O calls.  Most of these fields
    01331 //  are actually only required for the ReadMultiple routines, but
    01332 //  the caller must allocate one as a local variable anyway before knowing
    01333 //  whether there are multiple requests are not.  Therefore, a single
    01334 //  structure is used for simplicity.
    01335 //
    01336
    01337 typedef struct _UDF_IO_CONTEXT {
    01338
    01339     //
    01340     //  These two fields are used for multiple run Io
    01341     //
    01342
    01343     LONG IrpCount;
    01344     PIRP MasterIrp;
    01345     NTSTATUS Status;
    01346     BOOLEAN AllocatedContext;
    01347
    01348     union {
    01349
    01350         //
    01351         //  This element handles the asynchronous non-cached Io
    01352         //
    01353
    01354         struct {
    01355
    01356             PERESOURCE Resource;
    01357             ERESOURCE_THREAD ResourceThreadId;
    01358             ULONG RequestedByteCount;
    01359         };
    01360
    01361         //
    01362         //  and this element handles the synchronous non-cached Io.
    01363         //
    01364
    01365         KEVENT SyncEvent;
    01366     };
    01367
    01368 } UDF_IO_CONTEXT, *PUDF_IO_CONTEXT;
    01369
    01370
    01371 //
    01372 //  Following structure is used to track the top level request.  Each Udfs
    01373 //  Fsd and Fsp entry point will examine the top level irp location in the
    01374 //  thread local storage to determine if this request is top level and/or
    01375 //  top level Udfs.  The top level Udfs request will remember the previous
    01376 //  value and update that location with a stack location.  This location
    01377 //  can be accessed by recursive Udfs entry points.
    01378 //
    01379
    01380 typedef struct _THREAD_CONTEXT {
    01381
    01382     //
    01383     //  UDFS signature.  Used to confirm structure on stack is valid.
    01384     //
    01385
    01386     ULONG Udfs;
    01387
    01388     //
    01389     //  Previous value in top-level thread location.  We restore this
    01390     //  when done.
    01391     //
    01392
    01393     PIRP SavedTopLevelIrp;
    01394
    01395     //
    01396     //  Top level Udfs IrpContext.  Initial Udfs entry point on stack
    01397     //  will store the IrpContext for the request in this stack location.
    01398     //
    01399
    01400     PIRP_CONTEXT TopLevelIrpContext;
    01401
    01402 } THREAD_CONTEXT, *PTHREAD_CONTEXT;
    01403
    01404
    01405 //
    01406 //  Following structure is used to build up static data for parse tables
    01407 //
    01408
    01409 typedef struct _PARSE_KEYVALUE {
    01410     PCHAR Key;
    01411     ULONG Value;
    01412 } PARSE_KEYVALUE, *PPARSE_KEYVALUE;
    01413
    01414
    01415 //
    01416 //  Some macros for supporting the use of a Generic Table
    01417 //  containing all the FCB and indexed by their FileId.
    01418 //
    01419 //  The ISO 13346 lb_addr of the ICB hierarchy of the object
    01420 //
    01421 //      { ULONG BlockNo; USHORT PartitionId }
    01422 //
    01423 //  is encoded in the LowPart (BlockNo) and low 16 bits of the
    01424 //  HighPart (PartitionId). The top 16 bits are reserved and are
    01425 //  currently used to indicate the type of the object being referenced
    01426 //  (file or directory).
    01427 //
    01428 //  NOTE: this FileId prevents us from being able crack the name of
    01429 //  object since an ICB hierarchy's contained direct File Entrys do
    01430 //  not (and cannot) contain backpointers to the containing directory.
    01431 //  In order to be able to crack paths, we need to be able to do a
    01432 //  directory/dirent offset, which cannot fit in 64bits of FileId.
    01433 //  A FileId must be 64bits since we export this in the FileInternalInforation
    01434 //  query.
    01435 //
    01436 //  Also, even through we are restricted to a single partition in this
    01437 //  implementation, getting those "spare" 16bits isn't good enough to let us
    01438 //  point directly into a directory's File Identifier. Files and by extension
    01439 //  directories can exceed 2^32 bytes/entries.  Once we have pointed at the
    01440 //  parent dir, we are out of bits.
    01441 //
    01442 //  The Id field is a LARGE_INTEGER where the High and Low parts can be
    01443 //  accessed separately.
    01444 //
    01445 //  The following macros are used to access the Fid fields.
    01446 //
    01447 //      CdQueryFidDirentOffset      - Accesses the Dirent offset field
    01448 //      CdQueryFidPathTableNumber   - Accesses the PathTable offset field
    01449 //      CdSetFidDirentOffset        - Sets the Dirent offset field
    01450 //      CdSetFidPathTableNumber     - Sets the PathTable ordinal field
    01451 //      CdFidIsDirectory            - Queries if directory bit is set
    01452 //      CdFidSetDirectory           - Sets directory bit
    01453 //
    01454
    01455 #define FID_DIR_MASK  0x80000000        // high order bit means directory.
    01456
    01457 #define UdfSetFidFromLbAddr(I, LBA)     { (I).LowPart = (LBA).Lbn; \
    01458                                           (I).HighPart = (ULONG) (LBA).Partition; }
    01459
    01460 #define UdfGetFidLbn(I)                 ((I).LowPart)
    01461 #define UdfGetFidPartition(I)           ((USHORT) (((I).HighPart & ~FID_DIR_MASK) & MAXUSHORT))
    01462 #define UdfGetFidReservedZero(I)        ((I).HighPart & ~(FID_DIR_MASK|MAXUSHORT))
    01463
    01464 #define UdfSetFidFile(I)                ClearFlag( (I).HighPart, FID_DIR_MASK )
    01465 #define UdfSetFidDirectory(I)           SetFlag( (I).HighPart, FID_DIR_MASK )
    01466
    01467 #define UdfIsFidFile(I)                 BooleanFlagOff( (I).HighPart, FID_DIR_MASK )
    01468 #define UdfIsFidDirectory(I)            BooleanFlagOn( (I).HighPart, FID_DIR_MASK )
    01469
    01470
    01471 //
    01472 //  Context structures for browsing through structures
    01473 //
    01474
    01475 //
    01476 //  A mapped view is a useful bundle to hold information about a physical
    01477 //  view of the disk.
    01478 //
    01479
    01480 typedef struct _MAPPED_PVIEW {
    01481
    01482     //
    01483     //  A mapped extent and CC control block
    01484     //
    01485
    01486     PVOID View;
    01487     PBCB Bcb;
    01488
    01489     //
    01490     //  Extent location
    01491     //
    01492
    01493     USHORT Partition;
    01494     ULONG Lbn;
    01495     ULONG Length;
    01496
    01497 } MAPPED_PVIEW, *PMAPPED_PVIEW;
    01498
    01499
    01500 //
    01501 //  Enumeration contexts for various operations.
    01502 //
    01503
    01504 //
    01505 //  The following is used for crawling ICB hierarchies searching
    01506 //  for some notion of an active entry.
    01507 //
    01508
    01509 typedef struct _ICB_SEARCH_CONTEXT {
    01510
    01511     //
    01512     //  Vcb the search is occuring on.
    01513     //
    01514
    01515     PVCB Vcb;
    01516
    01517     //
    01518     //  Type of Icb being searched for.
    01519     //
    01520
    01521     USHORT IcbType;
    01522
    01523     //
    01524     //  The Active is most prevailing ICB so far found.
    01525     //
    01526
    01527     MAPPED_PVIEW Active;
    01528
    01529     //
    01530     //  The current logical block extent being read from the disk.
    01531     //
    01532
    01533     MAPPED_PVIEW Current;
    01534
    01535 } ICB_SEARCH_CONTEXT, *PICB_SEARCH_CONTEXT;
    01536
    01537 //
    01538 //  The following is used for crawling Extended Attributes extending off of
    01539 //  a direct ICB
    01540 //
    01541
    01542 typedef enum _EA_SEARCH_TYPE {
    01543
    01544     EaEnumBad = 0,
    01545     EaEnumISO,
    01546     EaEnumImplementation,
    01547     EaEnumApplication
    01548
    01549 } EA_SEARCH_TYPE, *PEA_SEARCH_TYPE;
    01550
    01551 typedef struct _EA_SEARCH_CONTEXT {
    01552
    01553     //
    01554     //  Reference to an elaborated ICB_SEARCH_CONTEXT which gives us a handle
    01555     //  onto a direct ICB to crawl.
    01556     //
    01557
    01558     PICB_SEARCH_CONTEXT IcbContext;
    01559
    01560     //
    01561     //  The current Ea being looked at.
    01562     //
    01563
    01564     PVOID Ea;
    01565
    01566     //
    01567     //  Bytes remaining in the EA view
    01568     //
    01569
    01570     ULONG Remaining;
    01571
    01572     //
    01573     //  EA being searched for.  We only support looking for ISO at this time.
    01574     //
    01575
    01576     ULONG EAType;
    01577     USHORT EASubType;
    01578
    01579 } EA_SEARCH_CONTEXT, *PEA_SEARCH_CONTEXT;
    01580
    01581 //
    01582 //  The following is used to crawl the list of allocation extent descriptors attached
    01583 //  to an ICB.
    01584 //
    01585
    01586 typedef struct _ALLOC_ENUM_CONTEXT {
    01587
    01588     //
    01589     //  Reference to an elaborated ICB_ENUM_CONTEXT which gives us a handle
    01590     //  onto a direct ICB to crawl.
    01591     //
    01592
    01593     PICB_SEARCH_CONTEXT IcbContext;
    01594
    01595     //
    01596     //  The current allocation descriptor being looked at.
    01597     //
    01598
    01599     PVOID Alloc;
    01600
    01601     //
    01602     //  Type of allocation descriptors in this enumeration
    01603     //
    01604
    01605     ULONG AllocType;
    01606
    01607     //
    01608     //  Bytes remaining in this view.
    01609     //
    01610
    01611     ULONG Remaining;
    01612
    01613 } ALLOC_ENUM_CONTEXT, *PALLOC_ENUM_CONTEXT;
    01614
    01615 //
    01616 //  The following is used to crawl a logical directory.
    01617 //
    01618
    01619 typedef struct _DIR_ENUM_CONTEXT {
    01620
    01621     //
    01622     //  The current view in the enumeration.
    01623     //
    01624
    01625     PVOID View;
    01626     PBCB Bcb;
    01627
    01628     //
    01629     //  Offset of the view from the beginning of the directory.
    01630     //
    01631
    01632     LARGE_INTEGER BaseOffset;
    01633
    01634     //
    01635     //  Length of the view which is valid and the current
    01636     //  offset in it.
    01637     //
    01638
    01639     ULONG ViewLength;
    01640     ULONG ViewOffset;
    01641
    01642     //
    01643     //  Pointer to the current FID.
    01644     //
    01645
    01646     PNSR_FID Fid;
    01647
    01648     //
    01649     //  Offset to the next fid from the beginning of the view.
    01650     //
    01651
    01652     ULONG NextFidOffset;
    01653
    01654     //
    01655     //  Flags indicating the state of the enumeration.
    01656     //
    01657
    01658     ULONG Flags;
    01659
    01660     //
    01661     //  Converted names from the FID. Case name is "case appropriate" for
    01662     //  the operation.
    01663     //
    01664
    01665     UNICODE_STRING ObjectName;
    01666     UNICODE_STRING CaseObjectName;
    01667
    01668     //
    01669     //  Real object name in pure form (not rendered to NT legal form)
    01670     //
    01671
    01672     UNICODE_STRING PureObjectName;
    01673
    01674     //
    01675     //  Short name for the object.
    01676     //
    01677
    01678     UNICODE_STRING ShortObjectName;
    01679
    01680     //
    01681     //  Currently allocated space for the name.  The previous strings are
    01682     //  carved out of this single buffer.
    01683     //
    01684
    01685     PVOID NameBuffer;
    01686
    01687     //
    01688     //  Size of currently allocated name buffer for the lfn names.
    01689     //
    01690
    01691     USHORT AllocLength;
    01692
    01693 } DIR_ENUM_CONTEXT, *PDIR_ENUM_CONTEXT;
    01694
    01695 //
    01696 //  Flags for noting where in the enumeration we are.
    01697 //
    01698
    01699 #define DIR_CONTEXT_FLAG_SEEN_NONCONSTANT       0x0001
    01700 #define DIR_CONTEXT_FLAG_SEEN_PARENT            0x0002
    01701
    01702 //
    01703 //  Flag indicating current Fid was buffered into pool.
    01704 //
    01705
    01706 #define DIR_CONTEXT_FLAG_FID_BUFFERED           0x0004
    01707
    01708 #endif // _CDSTRUC_