📄 cdstruc.h
字号:
/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
CdStruc.h
Abstract:
This module defines the data structures that make up the major internal
part of the Cdfs file system.
In-Memory structures:
The global data structures with the CdDataRecord. It contains a pointer
to a File System Device object and a queue of Vcb's. There is a Vcb for
every currently or previously mounted volumes. We may be in the process
of tearing down the Vcb's which have been dismounted. The Vcb's are
allocated as an extension to a volume device object.
+--------+
| CdData | +--------+
| | --> |FilSysDo|
| | | |
| | <+ +--------+
+--------+ |
|
| +--------+ +--------+
| |VolDo | |VolDo |
| | | | |
| +--------+ +--------+
+> |Vcb | <-> |Vcb | <-> ...
| | | |
+--------+ +--------+
Each Vcb contains a table of all the Fcbs for the volume indexed by
their FileId. Each Vcb contains a pointer to the root directory of
the volume. Each directory Fcb contains a queue of child Fcb's for
its children. There can also be detached subtrees due to open operations
by Id where the Fcb's are not connected to the root.
The following diagram shows the root structure.
+--------+ +--------+
| Vcb |---->| Fcb |-----------------------------------------------+
| | | Table |--------------------------------------------+ | |
| |--+ | |-----------------------------------------+ | | |
+--------+ | +--------+ | | |
| | | | | | |
| | | +--------------------+ | | |
| V +---------+ | | | |
| +--------+ | | | | |
| |RootFcb | V V | | |
+->| | +--------+ +--------+ | | |
| |-->|Child | |Child | | | |
+--------+ | Fcb |<-->| Fcb |<--> ... | | |
| | | | | | |
+--------+ +--------+ | | |
| | |
(Freestanding sub-tree) | | |
+--------+ | | |
|OpenById|<-----------------------------------------+ | |
| Dir | +--------+ | |
| |--->|OpenById|<------------------------------+ |
+--------+ | Child | +--------+ |
| Dir |--->|OpenById|<-------------------+
+--------+ | Child |
| File |
+--------+
Attached to each Directory Fcb is a prefix table containing the names
of children of this directory for which there is an Fcb. Not all Fcb's
will necessarily have an entry in this table.
+--------+ +--------+
| Dir | | Prefix |
| Fcb |----->| Table |--------------------+
| | | |-------+ |
+--------+ +--------+ | |
| | | |
| | | |
| V V V
| +--------+ +--------+ +--------+ +--------+
| | Fcb | | Fcb | | Fcb | | Fcb |
+---------->| |<-->| |<-->| |<-->| |
| | | | | | | |
+--------+ +--------+ +--------+ +--------+
Each file object open on a CDROM volume contains two context pointers. The
first will point back to the Fcb for the file object. The second, if present,
points to a Ccb (ContextControlBlock) which contains the per-handle information.
This includes the state of any directory enumeration.
+--------+ +--------+ +--------+
| Fcb |<------| File | | Ccb |
| | | Object|--->| |
| | | | | |
+--------+ +--------+ +--------+
^ ^
| | +--------+ +--------+
| | | File | | Ccb |
| +---------| Object|--->| |
| | | | |
| +--------+ +--------+
|
| +--------+
| |Stream |
+--------------| File |
| Object|
+--------+
Synchronization:
1. A resource in the CdData synchronizes access to the Vcb queue. This
is used during mount/verify/dismount operations.
2. A resource in the Vcb is used to synchronize access to Vcb for
open/close operations. Typically acquired shared, it
is acquired exclusively to lock out these operations.
3. A second resource in the Vcb is used to synchronize all file operations.
Typically acquired shared, it is acquired exclusively to lock
out all file operations. Acquiring both Vcb resources will lock
the entire volume.
4. A resource in the nonpaged Fcb will synchronize open/close operations
on an Fcb.
5. A fast mutex in the Vcb will protect access to the Fcb table and
the open counts in the Vcb. It is also used to modify the reference
counts in all Fcbs. This mutex cannot be acquired
exclusely and is an end resource.
6. A fast mutex in the Fcb will synchronize access to all Fcb fields
which aren't synchronized in some other way. A thread may acquire
mutexes for multiple Fcb's as long as it works it way toward the
root of the tree. This mutex can also be acquired recursively.
7. Normal locking order is CdData/Vcb/Fcb starting at any point in this
chain. The Vcb is required prior to acquiring resources for multiple
files. Shared ownership of the Vcb is sufficient in this case.
8. Normal locking order when acquiring multiple Fcb's is from some
starting Fcb and walking towards the root of tree. Create typically
walks down the tree. In this case we will attempt to acquire the
next node optimistically and if that fails we will reference
the current node in the tree, release it and acquire the next node.
At that point it will be safe to reacquire the parent node.
9. Locking order for the Fcb (via the fast mutex) will be from leaf of
tree back towards the root. No other resource may be acquired
after locking the Vcb (other than in-page reads).
10. Cleanup operations only lock the Vcb and Fcb long enough to change the
critical counts and share access fields. No reason to synchronize
otherwise. None of the structures can go away from beneath us
in this case.
--*/
#ifndef _CDSTRUC_
#define _CDSTRUC_
typedef PVOID PBCB; //**** Bcb's are now part of the cache module
#define BYTE_COUNT_EMBEDDED_NAME (32)
//
// The CD_MCB is used to store the mapping of logical file offset to
// logical disk offset. NOTE - This package only deals with the
// logical 2048 sectors. Translating to 'raw' sectors happens in
// software. We will embed a single MCB_ENTRY in the Fcb since this
// will be the typical case.
//
typedef struct _CD_MCB {
//
// Size and current count of the Mcb entries.
//
ULONG MaximumEntryCount;
ULONG CurrentEntryCount;
//
// Pointer to the start of the Mcb entries.
//
struct _CD_MCB_ENTRY *McbArray;
} CD_MCB;
typedef CD_MCB *PCD_MCB;
typedef struct _CD_MCB_ENTRY {
//
// Starting offset and number of bytes described by this entry.
// The Byte count is rounded to a logical block boundary if this is
// the last block.
//
LONGLONG DiskOffset;
LONGLONG ByteCount;
//
// Starting offset in the file of mapping described by this dirent.
//
LONGLONG FileOffset;
//
// Data length and block length. Data length is the length of each
// data block. Total length is the length of each data block and
// the skip size.
//
LONGLONG DataBlockByteCount;
LONGLONG TotalBlockByteCount;
} CD_MCB_ENTRY;
typedef CD_MCB_ENTRY *PCD_MCB_ENTRY;
//
// Cd name structure. The following structure is used to represent the
// full Cdrom name. This name can be stored in either Unicode or ANSI
// format.
//
typedef struct _CD_NAME {
//
// String containing name without the version number.
// The maximum length field for filename indicates the
// size of the buffer allocated for the two parts of the name.
//
UNICODE_STRING FileName;
//
// String containging the version number.
//
UNICODE_STRING VersionString;
} CD_NAME;
typedef CD_NAME *PCD_NAME;
//
// Following is the splay link structure for the prefix lookup.
// The names can be in either Unicode string or Ansi string format.
//
typedef struct _NAME_LINK {
RTL_SPLAY_LINKS Links;
UNICODE_STRING FileName;
} NAME_LINK;
typedef NAME_LINK *PNAME_LINK;
//
// Prefix entry. There is one of these for each name in the prefix table.
// An Fcb will have one of these embedded for the long name and an optional
// pointer to the short name entry.
//
typedef struct _PREFIX_ENTRY {
//
// Pointer to the Fcb for this entry.
//
struct _FCB *Fcb;
//
// Flags field. Used to indicate if the name is in the prefix table.
//
ULONG PrefixFlags;
//
// Exact case name match.
//
NAME_LINK ExactCaseName;
//
// Case-insensitive name link.
//
NAME_LINK IgnoreCaseName;
WCHAR FileNameBuffer[ BYTE_COUNT_EMBEDDED_NAME ];
} PREFIX_ENTRY;
typedef PREFIX_ENTRY *PPREFIX_ENTRY;
#define PREFIX_FLAG_EXACT_CASE_IN_TREE (0x00000001)
#define PREFIX_FLAG_IGNORE_CASE_IN_TREE (0x00000002)
//
// The CD_DATA record is the top record in the CDROM file system in-memory
// data structure. This structure must be allocated from non-paged pool.
//
typedef struct _CD_DATA {
//
// The type and size of this record (must be CDFS_NTC_DATA_HEADER)
//
NODE_TYPE_CODE NodeTypeCode;
NODE_BYTE_SIZE NodeByteSize;
//
// A pointer to the Driver object we were initialized with
//
PDRIVER_OBJECT DriverObject;
//
// Vcb queue.
//
LIST_ENTRY VcbQueue;
//
// The following fields are used to allocate IRP context structures
// using a lookaside list, and other fixed sized structures from a
// small cache. We use the CdData mutex to protext these structures.
//
ULONG IrpContextDepth;
ULONG IrpContextMaxDepth;
SINGLE_LIST_ENTRY IrpContextList;
//
// Filesystem device object for CDFS.
//
PDEVICE_OBJECT FileSystemDeviceObject;
//
// Following are used to manage the async and delayed close queue.
//
// FspCloseActive - Indicates whether there is a thread processing the
// two close queues.
// ReduceDelayedClose - Indicates that we have hit the upper threshold
// for the delayed close queue and need to reduce it to lower threshold.
//
// AsyncCloseQueue - Queue of IrpContext waiting for async close operation.
// AsyncCloseCount - Number of entries on the async close queue.
//
// DelayedCloseQueue - Queue of IrpContextLite waiting for delayed close
// operation.
// MaxDelayedCloseCount - Trigger delay close work at this threshold.
// MinDelayedCloseCount - Turn off delay close work at this threshold.
// DelayedCloseCount - Number of entries on the delayted close queue.
//
// CloseItem - Workqueue item used to start FspClose thread.
//
LIST_ENTRY AsyncCloseQueue;
ULONG AsyncCloseCount;
BOOLEAN FspCloseActive;
BOOLEAN ReduceDelayedClose;
USHORT PadUshort;
//
// The following fields describe the deferred close file objects.
//
LIST_ENTRY DelayedCloseQueue;
ULONG DelayedCloseCount;
ULONG MaxDelayedCloseCount;
ULONG MinDelayedCloseCount;
//
// Fast mutex used to lock the fields of this structure.
//
PVOID CdDataLockThread;
FAST_MUTEX CdDataMutex;
//
// A resource variable to control access to the global CDFS data record
//
ERESOURCE DataResource;
//
// Cache manager call back structure, which must be passed on each call
// to CcInitializeCacheMap.
//
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks;
CACHE_MANAGER_CALLBACKS CacheManagerVolumeCallbacks;
//
// This is the ExWorkerItem that does both kinds of deferred closes.
//
PIO_WORKITEM CloseItem;
} CD_DATA;
typedef CD_DATA *PCD_DATA;
//
// Since DVD drives allow > 100 "sessions", we need to use a larger TOC
// than the legacy CD definition. The maximum is theoretically 0xaa-16 (max
// number of open tracks in a session), but it's quite possible that some
// drive does not enforce this, so we'll go with 169 (track 0xaa is always the
// leadout).
//
#define MAXIMUM_NUMBER_TRACKS_LARGE 0xAA
typedef struct _CDROM_TOC_LARGE {
//
// Header
//
UCHAR Length[2]; // add two bytes for this field
UCHAR FirstTrack;
UCHAR LastTrack;
//
// Track data
//
TRACK_DATA TrackData[ MAXIMUM_NUMBER_TRACKS_LARGE];
} CDROM_TOC_LARGE, *PCDROM_TOC_LARGE;
typedef struct _CD_SECTOR_CACHE_CHUNK {
ULONG BaseLbn;
PUCHAR Buffer;
} CD_SECTOR_CACHE_CHUNK, *PCD_SECTOR_CACHE_CHUNK;
#define CD_SEC_CACHE_CHUNKS 4
#define CD_SEC_CHUNK_BLOCKS 0x18
//
// The Vcb (Volume control block) record corresponds to every
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -