reactos/drivers/filesystems/udfs/struct.h
2021-06-11 15:33:08 +03:00

492 lines
22 KiB
C

////////////////////////////////////////////////////////////////////
// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
// All rights reserved
// This file was released under the GPLv2 on June 2015.
////////////////////////////////////////////////////////////////////
/*************************************************************************
*
* File: struct.h
*
* Module: UDF File System Driver (Kernel mode execution only)
*
* Description:
* This file contains structure definitions for the UDF file system
* driver. Note that all structures are prefixed with the letters
* "UDF". The structures are all aligned using normal alignment
* used by the compiler (typically quad-word aligned).
*
*************************************************************************/
#ifndef _UDF_STRUCTURES_H_
#define _UDF_STRUCTURES_H_
/**************************************************************************
some useful definitions
**************************************************************************/
#include "Include/platform.h"
/**************************************************************************
some empty typedefs defined here so we can reference them easily
**************************************************************************/
struct _UDFIdentifier;
struct _UDFObjectName;
struct _UDFContextControlBlock;
struct _UDFNTRequiredFCB;
struct _UDFDiskDependentFCB;
struct _UDFFileControlBlock;
struct _UDFVolumeControlBlock;
struct _UDFIrpContext;
struct _UDFIrpContextLite;
struct _UDF_FILE_INFO;
struct _UDFData;
struct _UDFEjectWaitContext;
struct _UDFFileIDCacheItem;
struct _SparingEntry;
struct _UDFTrackMap;
/**************************************************************************
include udf related structures *here* (because we need definition of Fcb)
**************************************************************************/
#include "udf_info/udf_rel.h"
/**************************************************************************
each structure has a unique "node type" or signature associated with it
**************************************************************************/
#define UDF_NODE_TYPE_NT_REQ_FCB ((CSHORT)(0xfcb0))
#define UDF_NODE_TYPE_OBJECT_NAME (0xfdecba01)
#define UDF_NODE_TYPE_CCB (0xfdecba02)
#define UDF_NODE_TYPE_FCB (0xfdecba03)
#define UDF_NODE_TYPE_VCB (0xfdecba04)
#define UDF_NODE_TYPE_IRP_CONTEXT (0xfdecba05)
#define UDF_NODE_TYPE_GLOBAL_DATA (0xfdecba06)
#define UDF_NODE_TYPE_FILTER_DEVOBJ (0xfdecba07)
#define UDF_NODE_TYPE_UDFFS_DEVOBJ (0xfdecba08)
#define UDF_NODE_TYPE_IRP_CONTEXT_LITE (0xfdecba09)
#define UDF_NODE_TYPE_UDFFS_DRVOBJ (0xfdecba0a)
/**************************************************************************
every structure has a node type, and a node size associated with it.
The node type serves as a signature field. The size is used for
consistency checking ...
**************************************************************************/
typedef struct _UDFIdentifier {
uint32 NodeType; // a 32 bit identifier for the structure
uint32 NodeSize; // computed as sizeof(structure)
} UDFIdentifier, *PtrUDFIdentifier;
/**************************************************************************
Every open on-disk object must have a name associated with it
This name has two components:
(a) the path-name (prefix) that leads to this on-disk object
(b) the name of the object itself
Note that with multiply linked objects, a single object might be
associated with more than one name structure.
This UDF FSD does not correctly support multiply linked objects.
This structure must be quad-word aligned because it is zone allocated.
**************************************************************************/
typedef struct _UDFObjectName {
UDFIdentifier NodeIdentifier;
uint32 ObjectNameFlags;
// an absolute pathname of the object is stored below
UNICODE_STRING ObjectName;
} UDFObjectName, *PtrUDFObjectName;
#define UDF_OBJ_NAME_NOT_FROM_ZONE (0x80000000)
/**************************************************************************
Each file open instance is represented by a context control block.
For each successful create/open request; a file object and a CCB will
be created.
For open operations performed internally by the FSD, there may not
exist file objects; but a CCB will definitely be created.
This structure must be quad-word aligned because it is zone allocated.
**************************************************************************/
typedef struct _UDFContextControlBlock {
UDFIdentifier NodeIdentifier;
// ptr to the associated FCB
struct _UDFFileControlBlock *Fcb;
// all CCB structures for a FCB are linked together
LIST_ENTRY NextCCB;
// each CCB is associated with a file object
PFILE_OBJECT FileObject;
// flags (see below) associated with this CCB
uint32 CCBFlags;
// current index in directory is required sometimes
ULONG CurrentIndex;
// if this CCB represents a directory object open, we may
// need to maintain a search pattern
PUNICODE_STRING DirectorySearchPattern;
HASH_ENTRY hashes;
ULONG TreeLength;
// Acces rights previously granted to caller's thread
ACCESS_MASK PreviouslyGrantedAccess;
} UDFCCB, *PtrUDFCCB;
/**************************************************************************
the following CCBFlags values are relevant. These flag
values are bit fields; therefore we can test whether
a bit position is set (1) or not set (0).
**************************************************************************/
// some on-disk file/directories are opened by UDF itself
// as opposed to being opened on behalf of a user process
#define UDF_CCB_OPENED_BY_UDF (0x00000001)
// the file object specified synchronous access at create/open time.
// this implies that UDF must maintain the current byte offset
#define UDF_CCB_OPENED_FOR_SYNC_ACCESS (0x00000002)
// file object specified sequential access for this file
#define UDF_CCB_OPENED_FOR_SEQ_ACCESS (0x00000004)
// the CCB has had an IRP_MJ_CLEANUP issued on it. we must
// no longer allow the file object / CCB to be used in I/O requests.
#define UDF_CCB_CLEANED (0x00000008)
// if we were invoked via the fast i/o path to perform file i/o;
// we should set the CCB access/modification time at cleanup
#define UDF_CCB_ACCESSED (0x00000010)
#define UDF_CCB_MODIFIED (0x00000020)
// if an application process set the file date time, we must
// honor that request and *not* overwrite the values at cleanup
#define UDF_CCB_ACCESS_TIME_SET (0x00000040)
#define UDF_CCB_MODIFY_TIME_SET (0x00000080)
#define UDF_CCB_CREATE_TIME_SET (0x00000100)
#define UDF_CCB_WRITE_TIME_SET (0x00000200)
#define UDF_CCB_ATTRIBUTES_SET (0x00020000)
#define UDF_CCB_CASE_SENSETIVE (0x00000400)
#ifndef UDF_READ_ONLY_BUILD
#define UDF_CCB_DELETE_ON_CLOSE (0x00000800)
#endif //UDF_READ_ONLY_BUILD
// this CCB was allocated for a "volume open" operation
#define UDF_CCB_VOLUME_OPEN (0x00001000)
#define UDF_CCB_MATCH_ALL (0x00002000)
#define UDF_CCB_WILDCARD_PRESENT (0x00004000)
#define UDF_CCB_CAN_BE_8_DOT_3 (0x00008000)
#define UDF_CCB_READ_ONLY (0x00010000)
//#define UDF_CCB_ATTRIBUTES_SET (0x00020000) // see above
#define UDF_CCB_FLUSHED (0x20000000)
#define UDF_CCB_VALID (0x40000000)
#define UDF_CCB_NOT_FROM_ZONE (0x80000000)
/**************************************************************************
each open file/directory/volume is represented by a file control block.
Each FCB can logically be divided into two:
(a) a structure that must have a field of type FSRTL_COMMON_FCB_HEADER
as the first field in the structure.
This portion should also contain other structures/resources required
by the NT Cache Manager
We will call this structure the "NT Required" FCB. Note that this
portion of the FCB must be allocated from non-paged pool.
(b) the remainder of the FCB is dependent upon the particular FSD
requirements.
This portion of the FCB could possibly be allocated from paged
memory, though in the UDF FSD, it will always be allocated
from non-paged pool.
FCB structures are protected by the MainResource as well as the
PagingIoResource. Of course, if the FSD implementation requires
it, we can associate other syncronization structures with the
FCB.
These structures must be quad-word aligned because they are zone-allocated.
**************************************************************************/
typedef struct _UDFNTRequiredFCB {
FSRTL_COMMON_FCB_HEADER CommonFCBHeader;
SECTION_OBJECT_POINTERS SectionObject;
FILE_LOCK FileLock;
ERESOURCE MainResource;
ERESOURCE PagingIoResource;
// we will maintain some time information here to make our life easier
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
// NT requires that a file system maintain and honor the various
// SHARE_ACCESS modes ...
SHARE_ACCESS FCBShareAccess;
// This counter is used to prevent unexpected structure releases
ULONG CommonRefCount;
PSECURITY_DESCRIPTOR SecurityDesc;
ULONG NtReqFCBFlags;
// to identify the lazy writer thread(s) we will grab and store
// the thread id here when a request to acquire resource(s)
// arrives ..
uint32 LazyWriterThreadID;
UCHAR AcqSectionCount;
UCHAR AcqFlushCount;
#ifdef DBG
PFILE_OBJECT FileObject;
#endif //DBG
PETHREAD CloseThread;
} UDFNTRequiredFCB, *PtrUDFNTRequiredFCB;
#define UDF_NTREQ_FCB_SD_MODIFIED (0x00000001)
#define UDF_NTREQ_FCB_INLIST (0x00000002)
#define UDF_NTREQ_FCB_DELETED (0x00000004)
#define UDF_NTREQ_FCB_MODIFIED (0x00000008)
#define UDF_NTREQ_FCB_VALID (0x40000000)
/**************************************************************************/
#define UDF_FCB_MT NonPagedPool
/***************************************************/
/***************** W A R N I N G *****************/
/***************************************************/
/***************************************************/
/* DO NOT FORGET TO UPDATE VCB's HEADER ! */
/***************************************************/
typedef struct _UDFFileControlBlock {
UDFIdentifier NodeIdentifier;
// we will not embed the "NT Required FCB" here, 'cause we dislike
// troubles with Hard(&Symbolic) Links
PtrUDFNTRequiredFCB NTRequiredFCB;
// UDF related data
PUDF_FILE_INFO FileInfo;
// this FCB belongs to some mounted logical volume
struct _UDFVolumeControlBlock* Vcb;
// to be able to access all open file(s) for a volume, we will
// link all FCB structures for a logical volume together
LIST_ENTRY NextFCB;
// some state information for the FCB is maintained using the
// flags field
uint32 FCBFlags;
// all CCB's for this particular FCB are linked off the following
// list head.
LIST_ENTRY NextCCB;
// whenever a file stream has a create/open operation performed,
// the Reference count below is incremented AND the OpenHandle count
// below is also incremented.
// When an IRP_MJ_CLEANUP is received, the OpenHandle count below
// is decremented.
// When an IRP_MJ_CLOSE is received, the Reference count below is
// decremented.
// When the Reference count goes down to zero, the FCB can be de-allocated.
// Note that a zero Reference count implies a zero OpenHandle count.
// But when we have mapped data, we can receive no IRP_MJ_CLOSE
// In this case OpenHandleCount may reach zero, but ReferenceCount may
// be non-zero.
uint32 ReferenceCount;
uint32 OpenHandleCount;
uint32 CachedOpenHandleCount;
// for the UDF fsd, there exists a 1-1 correspondence between a
// full object pathname and a FCB
PtrUDFObjectName FCBName;
ERESOURCE CcbListResource;
struct _UDFFileControlBlock* ParentFcb;
// Pointer to IrpContextLite in delayed queue.
struct _UDFIrpContextLite* IrpContextLite;
uint32 CcbCount;
} UDFFCB, *PtrUDFFCB;
/**************************************************************************
the following FCBFlags values are relevant. These flag
values are bit fields; therefore we can test whether
a bit position is set (1) or not set (0).
**************************************************************************/
#define UDF_FCB_VALID (0x00000002)
#define UDF_FCB_PAGE_FILE (0x00000004)
#define UDF_FCB_DIRECTORY (0x00000008)
#define UDF_FCB_ROOT_DIRECTORY (0x00000010)
#define UDF_FCB_WRITE_THROUGH (0x00000020)
#define UDF_FCB_MAPPED (0x00000040)
#define UDF_FCB_FAST_IO_READ_IN_PROGESS (0x00000080)
#define UDF_FCB_FAST_IO_WRITE_IN_PROGESS (0x00000100)
#define UDF_FCB_DELETE_ON_CLOSE (0x00000200)
#define UDF_FCB_MODIFIED (0x00000400)
#define UDF_FCB_ACCESSED (0x00000800)
#define UDF_FCB_READ_ONLY (0x00001000)
#define UDF_FCB_DELAY_CLOSE (0x00002000)
#define UDF_FCB_DELETED (0x00004000)
#define UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE (0x00008000)
#define UDF_FCB_POSTED_RENAME (0x00010000)
#define UDF_FCB_DELETE_PARENT (0x10000000)
#define UDF_FCB_NOT_FROM_ZONE (0x80000000)
/**************************************************************************
A logical volume is represented with the following structure.
This structure is allocated as part of the device extension
for a device object that this FSD will create, to represent
the mounted logical volume.
**************************************************************************/
#define _BROWSE_UDF_
// Common UDF-related definitions
#include "Include/udf_common.h"
// One for root
#define UDF_RESIDUAL_REFERENCE (2)
// input flush flags
#define UDF_FLUSH_FLAGS_BREAKABLE (0x00000001)
// see also udf_rel.h
#define UDF_FLUSH_FLAGS_LITE (0x80000000)
// output flush flags
#define UDF_FLUSH_FLAGS_INTERRUPTED (0x00000001)
#define UDF_MAX_BG_WRITERS 16
typedef struct _FILTER_DEV_EXTENSION {
UDFIdentifier NodeIdentifier;
PFILE_OBJECT fileObject;
PDEVICE_OBJECT lowerFSDeviceObject;
} FILTER_DEV_EXTENSION, *PFILTER_DEV_EXTENSION;
typedef struct _UDFFS_DEV_EXTENSION {
UDFIdentifier NodeIdentifier;
} UDFFS_DEV_EXTENSION, *PUDFFS_DEV_EXTENSION;
/**************************************************************************
The IRP context encapsulates the current request. This structure is
used in the "common" dispatch routines invoked either directly in
the context of the original requestor, or indirectly in the context
of a system worker thread.
**************************************************************************/
typedef struct _UDFIrpContext {
UDFIdentifier NodeIdentifier;
uint32 IrpContextFlags;
// copied from the IRP
uint8 MajorFunction;
// copied from the IRP
uint8 MinorFunction;
// to queue this IRP for asynchronous processing
WORK_QUEUE_ITEM WorkQueueItem;
// the IRP for which this context structure was created
PIRP Irp;
// the target of the request (obtained from the IRP)
PDEVICE_OBJECT TargetDeviceObject;
// if an exception occurs, we will store the code here
NTSTATUS SavedExceptionCode;
// For queued close operation we save Fcb
_UDFFileControlBlock *Fcb;
ULONG TreeLength;
PMDL PtrMdl;
PCHAR TransitionBuffer;
// support for delayed close
} UDFIrpContext, *PtrUDFIrpContext;
#define UDF_IRP_CONTEXT_CAN_BLOCK (0x00000001)
#define UDF_IRP_CONTEXT_WRITE_THROUGH (0x00000002)
#define UDF_IRP_CONTEXT_EXCEPTION (0x00000004)
#define UDF_IRP_CONTEXT_DEFERRED_WRITE (0x00000008)
#define UDF_IRP_CONTEXT_ASYNC_PROCESSING (0x00000010)
#define UDF_IRP_CONTEXT_NOT_TOP_LEVEL (0x00000020)
#define UDF_IRP_CONTEXT_FLAG_DISABLE_POPUPS (0x00000040)
#define UDF_IRP_CONTEXT_FLUSH_REQUIRED (0x00000080)
#define UDF_IRP_CONTEXT_FLUSH2_REQUIRED (0x00000100)
#define UDF_IRP_CONTEXT_READ_ONLY (0x00010000)
#define UDF_IRP_CONTEXT_RES1_ACQ (0x01000000)
#define UDF_IRP_CONTEXT_RES2_ACQ (0x02000000)
#define UDF_IRP_CONTEXT_FORCED_POST (0x20000000)
#define UDF_IRP_CONTEXT_BUFFER_LOCKED (0x40000000)
#define UDF_IRP_CONTEXT_NOT_FROM_ZONE (0x80000000)
/**************************************************************************
Following structure is used to queue a request to the delayed close queue.
This structure should be the minimum block allocation size.
**************************************************************************/
typedef struct _UDFIrpContextLite {
UDFIdentifier NodeIdentifier;
// Fcb for the file object being closed.
_UDFFileControlBlock *Fcb;
// List entry to attach to delayed close queue.
LIST_ENTRY DelayedCloseLinks;
// User reference count for the file object being closed.
//ULONG UserReference;
// Real device object. This represents the physical device closest to the media.
PDEVICE_OBJECT RealDevice;
ULONG TreeLength;
uint32 IrpContextFlags;
} UDFIrpContextLite, *PtrUDFIrpContextLite;
// a default size of the number of pages of non-paged pool allocated
// for each of the zones ...
// Note that the values are absolutely arbitrary, the only information
// worth using from the values themselves is that they increase for
// larger systems (i.e. systems with more memory)
#define UDF_DEFAULT_ZONE_SIZE_SMALL_SYSTEM (0x4)
#define UDF_DEFAULT_ZONE_SIZE_MEDIUM_SYSTEM (0x8)
#define UDF_DEFAULT_ZONE_SIZE_LARGE_SYSTEM (0xc)
// another simplistic (brain dead ? :-) method used is to simply double
// the values for a "server" machine
// So, for all you guys who "modified" the registry ;-) to change the
// wkstation into a server, tough luck !
#define UDF_NTAS_MULTIPLE (0x2)
typedef struct _UDFEjectWaitContext {
PVCB Vcb;
BOOLEAN SoftEjectReq;
UCHAR Padding0[3];
KEVENT StopReq;
PKEVENT WaiterStopped;
WORK_QUEUE_ITEM EjectReqWorkQueueItem;
GET_EVENT_USER_OUT EjectReqBuffer;
UCHAR PaddingEvt[(0x40 - sizeof(GET_EVENT_USER_OUT)) & 0x0f];
GET_CAPABILITIES_USER_OUT DevCap;
UCHAR PaddingDevCap[(0x40 - sizeof(GET_CAPABILITIES_USER_OUT)) & 0x0f];
GET_LAST_ERROR_USER_OUT Error;
UCHAR PaddingError[(0x40 - sizeof(GET_LAST_ERROR_USER_OUT)) & 0x0f];
ULONG Zero;
} UDFEjectWaitContext, *PUDFEjectWaitContext;
typedef struct _UDFBGWriteContext {
PVCB Vcb;
PVOID Buffer; // Target buffer
ULONG Length;
ULONG Lba;
ULONG WrittenBytes;
BOOLEAN FreeBuffer;
WORK_QUEUE_ITEM WorkQueueItem;
} UDFBGWriteContext, *PUDFBGWriteContext;
// Define the file system statistics struct. Vcb->Statistics points to an
// array of these (one per processor) and they must be 64 byte aligned to
// prevent cache line tearing.
typedef struct _FILE_SYSTEM_STATISTICS {
// This contains the actual data.
FILESYSTEM_STATISTICS Common;
FAT_STATISTICS Fat;
// Pad this structure to a multiple of 64 bytes.
UCHAR Pad[64-(sizeof(FILESYSTEM_STATISTICS)+sizeof(FAT_STATISTICS))%64];
} FILE_SYSTEM_STATISTICS, *PFILE_SYSTEM_STATISTICS;
//
typedef struct _UDFFileIDCacheItem {
LONGLONG Id;
UNICODE_STRING FullName;
BOOLEAN CaseSens;
} UDFFileIDCacheItem, *PUDFFileIDCacheItem;
#define DIRTY_PAGE_LIMIT 32
#endif /* _UDF_STRUCTURES_H_ */ // has this file been included?