reactos/drivers/filesystems/udfs/Include/udf_common.h

660 lines
24 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.
////////////////////////////////////////////////////////////////////
#ifndef __UDF_COMMON_STRUCT__H__
#define __UDF_COMMON_STRUCT__H__
typedef enum _UDFFSD_MEDIA_TYPE {
MediaUnknown = 0,
MediaHdd,
MediaCdr,
MediaCdrw,
MediaCdrom,
MediaZip,
MediaFloppy,
MediaDvdr,
MediaDvdrw
} UDFFSD_MEDIA_TYPE;
#define MAX_UDFFSD_MEDIA_TYPE ((ULONG)MediaFloppy)
typedef struct _UDF_KEY_LIST {
int32 d[4];
} UDF_KEY_LIST, *PUDF_KEY_LIST;
struct UDF_MEDIA_CLASS_NAMES
{
UDFFSD_MEDIA_TYPE MediaClass;
PCWSTR ClassName;
};
extern struct UDF_MEDIA_CLASS_NAMES UDFMediaClassName[];
#define MAX_ANCHOR_LOCATIONS 11
#define MAX_SPARING_TABLE_LOCATIONS 32
typedef struct _UDFVolumeControlBlock {
#ifdef _UDF_STRUCTURES_H_
//---------------
// Kernel-only data:
//---------------
//---------------
// Fcb data
//---------------
union {
struct {
UDFIdentifier NodeIdentifier;
// compatibility field
PtrUDFNTRequiredFCB NTRequiredFCB;
// UDF related data (compatibility field)
PVOID Reserved0;
// this FCB belongs to some mounted logical volume
// (compatibility field - pointer to itself)
struct _UDFVolumeControlBlock* Vcb;
// a global list of all FCB structures associated with the VCB
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.
// For volume open operations, we do not create a FCB (we use the VCB
// directly instead). Therefore, all CCB structures for the volume
// open operation are linked directly off the VCB
LIST_ENTRY VolumeOpenListHead; // CCB
// A count of the number of open files/directories
// As long as the count is != 0, the volume cannot
// be dismounted or locked.
uint32 VolumeOpenCount;
uint32 Reserved2;
uint32 Reserved3;
PVOID Reserved4;
ERESOURCE CcbListResource;
struct _UDFFileControlBlock* ParentFcb;
// Pointer to IrpContextLite in delayed queue.
struct _UDFIrpContextLite* IrpContextLite;
uint32 CcbCount;
};
UDFFCB VcbAsFcb;
};
//---------------
// Vcb-only data
//---------------
uint32 VCBOpenCount;
uint32 VCBOpenCountRO;
uint32 VCBHandleCount;
// a resource to protect the fields contained within the VCB
ERESOURCE FcbListResource;
ERESOURCE FlushResource;
// each VCB is accessible off a global linked list
LIST_ENTRY NextVCB;
// each VCB points to a VPB structure created by the NT I/O Manager
PVPB Vpb;
// we will maintain a global list of IRP's that are pending
// because of a directory notify request.
LIST_ENTRY NextNotifyIRP;
// the above list is protected only by the mutex declared below
PNOTIFY_SYNC NotifyIRPMutex;
// for each mounted volume, we create a device object. Here then
// is a back pointer to that device object
PDEVICE_OBJECT VCBDeviceObject;
BOOLEAN ShutdownRegistered;
// We also retain a pointer to the physical device object on which we
// have mounted ourselves. The I/O Manager passes us a pointer to this
// device object when requesting a mount operation.
PDEVICE_OBJECT TargetDeviceObject;
UNICODE_STRING TargetDevName;
PCWSTR DefaultRegName;
// the volume structure contains a pointer to the root directory FCB
PtrUDFFCB RootDirFCB;
// the complete name of the user visible drive letter we serve
PUCHAR PtrVolumePath;
// Pointer to a stream file object created for the volume information
// to be more easily read from secondary storage (with the support of
// the NT Cache Manager).
/* PFILE_OBJECT PtrStreamFileObject;
// Required to use the Cache Manager.
*/
struct _FILE_SYSTEM_STATISTICS* Statistics;
// Volume lock file object - used in Lock/Unlock routines
ULONG VolumeLockPID;
PFILE_OBJECT VolumeLockFileObject;
DEVICE_TYPE FsDeviceType;
// The following field tells how many requests for this volume have
// either been enqueued to ExWorker threads or are currently being
// serviced by ExWorker threads. If the number goes above
// a certain threshold, put the request on the overflow queue to be
// executed later.
ULONG PostedRequestCount;
ULONG ThreadsPerCpu;
// The following field indicates the number of IRP's waiting
// to be serviced in the overflow queue.
ULONG OverflowQueueCount;
// The following field contains the queue header of the overflow queue.
// The Overflow queue is a list of IRP's linked via the IRP's ListEntry
// field.
LIST_ENTRY OverflowQueue;
// The following spinlock protects access to all the above fields.
KSPIN_LOCK OverflowQueueSpinLock;
ULONG StopOverflowQueue;
ULONG SystemCacheGran;
//---------------
//
//---------------
// Eject Request waiter
struct _UDFEjectWaitContext* EjectWaiter;
KEVENT WaiterStopped;
ULONG SoftEjectReq;
ULONG BM_FlushTime;
ULONG BM_FlushPriod;
ULONG Tree_FlushTime;
ULONG Tree_FlushPriod;
ULONG SkipCountLimit;
ULONG SkipEjectCountLimit;
/* // XP CD Burner related data
UNICODE_STRING CDBurnerVolume;
BOOLEAN CDBurnerVolumeValid;
*/
// Background writes counter
LONG BGWriters;
// File Id cache
struct _UDFFileIDCacheItem* FileIdCache;
ULONG FileIdCount;
//
ULONG MediaLockCount;
BOOLEAN IsVolumeJustMounted;
#else
//---------------
// Win32-only data:
//---------------
#ifdef _BROWSE_UDF_
PUDF_FILE_INFO RootFileInfo;
#endif
#ifdef UDF_FORMAT_MEDIA
struct _UDFFmtState* fms;
#endif //UDF_FORMAT_MEDIA
PDEVICE_OBJECT TargetDeviceObject;
ULONG FsDeviceType;
ULONG PhDeviceType;
#endif //_UDF_STRUCTURES_H_
// FS size cache
LONGLONG TotalAllocUnits;
LONGLONG FreeAllocUnits;
LONGLONG EstimatedFreeUnits;
// a resource to protect the fields contained within the VCB
ERESOURCE VCBResource;
ERESOURCE BitMapResource1;
ERESOURCE FileIdResource;
ERESOURCE DlocResource;
ERESOURCE DlocResource2;
ERESOURCE PreallocResource;
ERESOURCE IoResource;
//---------------
// Physical media parameters
//---------------
ULONG BlockSize;
ULONG BlockSizeBits;
ULONG WriteBlockSize;
ULONG LBlockSize;
ULONG LBlockSizeBits;
ULONG LB2B_Bits;
// Number of last session
ULONG LastSession;
ULONG FirstTrackNum;
ULONG FirstTrackNumLastSes;
ULONG LastTrackNum;
// First & Last LBA of the last session
ULONG FirstLBA;
ULONG FirstLBALastSes;
ULONG LastLBA;
// Last writable LBA
ULONG LastPossibleLBA;
// First writable LBA
ULONG NWA;
// sector type map
struct _UDFTrackMap* TrackMap;
ULONG LastModifiedTrack;
ULONG LastReadTrack;
ULONG CdrwBufferSize;
ULONG CdrwBufferSizeCounter;
uint32 SavedFeatures;
// OPC info
// PCHAR OPC_buffer;
UCHAR OPCNum;
BOOLEAN OPCDone;
UCHAR MediaType;
UCHAR MediaClassEx;
UCHAR DiscStat;
UCHAR PhErasable;
UCHAR PhDiskType;
UCHAR PhMediaCapFlags;
UCHAR MRWStatus;
UCHAR UseEvent;
BOOLEAN BlankCD;
UCHAR Reserved;
ULONG PhSerialNumber;
// Speed control
SET_CD_SPEED_EX_USER_IN SpeedBuf;
ULONG MaxWriteSpeed;
ULONG MaxReadSpeed;
ULONG CurSpeed;
BOOLEAN CDR_Mode;
BOOLEAN DVD_Mode;
BOOLEAN WriteParamsReq;
#define SYNC_CACHE_RECOVERY_NONE 0
#define SYNC_CACHE_RECOVERY_ATTEMPT 1
#define SYNC_CACHE_RECOVERY_RETRY 2
UCHAR SyncCacheState;
// W-cache
W_CACHE FastCache;
ULONG WCacheMaxFrames;
ULONG WCacheMaxBlocks;
ULONG WCacheBlocksPerFrameSh;
ULONG WCacheFramesToKeepFree;
PCHAR ZBuffer;
PCHAR fZBuffer;
ULONG fZBufferSize;
PSEND_OPC_INFO_HEADER_USER_IN OPCh;
PGET_WRITE_MODE_USER_OUT WParams;
PGET_LAST_ERROR_USER_OUT Error;
ULONG IoErrorCounter;
// Media change count (equal to the same field in CDFS VCB)
ULONG MediaChangeCount;
#define INCREMENTAL_SEEK_NONE 0
#define INCREMENTAL_SEEK_WORKAROUND 1
#define INCREMENTAL_SEEK_DONE 2
UCHAR IncrementalSeekState;
BOOLEAN VerifyOnWrite;
BOOLEAN DoNotCompareBeforeWrite;
BOOLEAN CacheChainedIo;
ULONG MountPhErrorCount;
// a set of flags that might mean something useful
uint32 VCBFlags;
BOOLEAN FP_disc;
//---------------
// UDF related data
//---------------
#ifdef _BROWSE_UDF_
// Anchors LBA
ULONG Anchor[MAX_ANCHOR_LOCATIONS];
ULONG BadSeqLoc[MAX_ANCHOR_LOCATIONS*2];
OSSTATUS BadSeqStatus[MAX_ANCHOR_LOCATIONS*2];
ULONG BadSeqLocIndex;
// Volume label
UNICODE_STRING VolIdent;
// Volume creation time
int64 VolCreationTime;
// Root & SystemStream lb_addr
lb_addr RootLbAddr;
lb_addr SysStreamLbAddr;
// Number of partition
ULONG PartitionMaps;
// Pointer to partition structures
PUDFPartMap Partitions;
LogicalVolIntegrityDesc *LVid;
uint32 IntegrityType;
uint32 origIntegrityType;
extent_ad LVid_loc;
ULONG SerialNumber;
// on-disk structure version control
uint16 CurrentUDFRev;
uint16 minUDFReadRev;
uint16 minUDFWriteRev;
uint16 maxUDFWriteRev;
// file/dir counters for Mac OS
uint32 numFiles;
uint32 numDirs;
// VAT
uint32 InitVatCount;
uint32 VatCount;
uint32* Vat;
uint32 VatPartNdx;
PUDF_FILE_INFO VatFileInfo;
// sparing table
ULONG SparingCountFree;
ULONG SparingCount;
ULONG SparingBlockSize;
struct _SparingEntry* SparingTable;
uint32 SparingTableLoc[MAX_SPARING_TABLE_LOCATIONS];
uint32 SparingTableCount;
uint32 SparingTableLength;
uint32 SparingTableModified;
// free space bitmap
ULONG FSBM_ByteCount;
// the following 2 fields are equal to NTIFS's RTL_BITMAP structure
ULONG FSBM_BitCount;
PCHAR FSBM_Bitmap; // 0 - free, 1 - used
#ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS
PULONG FSBM_Bitmap_owners; // 0 - free
// -1 - used by unknown
// other - owner's FE location
#ifdef UDF_TRACK_FS_STRUCTURES
PEXTENT_MAP FsStructMap;
PULONG FE_link_counts; // 0 - free
#endif //UDF_TRACK_FS_STRUCTURES
#endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS
PCHAR FSBM_OldBitmap; // 0 - free, 1 - used
ULONG BitmapModified;
PCHAR ZSBM_Bitmap; // 0 - data, 1 - zero-filleld
#endif //_BROWSE_UDF_
PCHAR BSBM_Bitmap; // 0 - normal, 1 - bad-block
#ifdef _BROWSE_UDF_
// pointers to Volume Descriptor Sequences
ULONG VDS1;
ULONG VDS1_Len;
ULONG VDS2;
ULONG VDS2_Len;
ULONG Modified;
// System Stream Dir
PUDF_FILE_INFO SysSDirFileInfo;
// Non-alloc space
PUDF_FILE_INFO NonAllocFileInfo;
// Unique ID Mapping
PUDF_FILE_INFO UniqueIDMapFileInfo;
// Saved location of Primary Vol Descr (used for setting Label)
UDF_VDS_RECORD PVolDescAddr;
UDF_VDS_RECORD PVolDescAddr2;
// NSR flags
uint32 NSRDesc;
// File Id cache
ULONGLONG NextUniqueId;
// FE location cache
PUDF_DATALOC_INDEX DlocList;
ULONG DlocCount;
// FS compatibility
USHORT DefaultAllocMode; // Default alloc mode (from registry)
BOOLEAN UseExtendedFE;
BOOLEAN LowFreeSpace;
UDFFSD_MEDIA_TYPE MediaTypeEx;
ULONG DefaultUID;
ULONG DefaultGID;
ULONG DefaultAttr; // Default file attributes (NT-style)
UCHAR PartitialDamagedVolumeAction;
BOOLEAN NoFreeRelocationSpaceVolumeAction;
BOOLEAN WriteSecurity;
BOOLEAN FlushMedia;
BOOLEAN ForgetVolume;
UCHAR Reserved5[3];
//
ULONG FECharge;
ULONG FEChargeSDir;
ULONG PackDirThreshold;
ULONG SparseThreshold; // in blocks
PUDF_ALLOCATION_CACHE_ITEM FEChargeCache;
ULONG FEChargeCacheMaxSize;
PUDF_ALLOCATION_CACHE_ITEM PreallocCache;
ULONG PreallocCacheMaxSize;
UDF_VERIFY_CTX VerifyCtx;
PUCHAR Cfg;
ULONG CfgLength;
ULONG CfgVersion;
#endif //_BROWSE_UDF_
uint32 CompatFlags;
uint32 UserFSFlags;
UCHAR ShowBlankCd;
} VCB, *PVCB;
// some valid flags for the VCB
#define UDF_VCB_FLAGS_VOLUME_MOUNTED (0x00000001)
#define UDF_VCB_FLAGS_VOLUME_LOCKED (0x00000002)
#define UDF_VCB_FLAGS_BEING_DISMOUNTED (0x00000004)
#define UDF_VCB_FLAGS_SHUTDOWN (0x00000008)
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY (0x00000010)
#define UDF_VCB_FLAGS_VCB_INITIALIZED (0x00000020)
#define UDF_VCB_FLAGS_OUR_DEVICE_DRIVER (0x00000040)
#define UDF_VCB_FLAGS_NO_SYNC_CACHE (0x00000080)
#define UDF_VCB_FLAGS_REMOVABLE_MEDIA (0x00000100)
#define UDF_VCB_FLAGS_MEDIA_LOCKED (0x00000200)
#define UDF_VCB_SKIP_EJECT_CHECK (0x00000400)
//#define UDF_VCB_FS_BITMAP_MODIFIED (0x00000800) // moved to separate flag
#define UDF_VCB_LAST_WRITE (0x00001000)
#define UDF_VCB_FLAGS_TRACKMAP (0x00002000)
#define UDF_VCB_ASSUME_ALL_USED (0x00004000)
#define UDF_VCB_FLAGS_RAW_DISK (0x00040000)
#define UDF_VCB_FLAGS_USE_STD (0x00080000)
#define UDF_VCB_FLAGS_STOP_WAITER_EVENT (0x00100000)
#define UDF_VCB_FLAGS_NO_DELAYED_CLOSE (0x00200000)
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY (0x00400000)
#define UDF_VCB_FLAGS_FLUSH_BREAK_REQ (0x01000000)
#define UDF_VCB_FLAGS_EJECT_REQ (0x02000000)
#define UDF_VCB_FLAGS_FORCE_SYNC_CACHE (0x04000000)
#define UDF_VCB_FLAGS_USE_CAV (0x08000000)
#define UDF_VCB_FLAGS_UNSAFE_IOCTL (0x10000000)
#define UDF_VCB_FLAGS_DEAD (0x20000000) // device unexpectedly disappeared
// flags for FS Interface Compatibility
#define UDF_VCB_IC_UPDATE_ACCESS_TIME (0x00000001)
#define UDF_VCB_IC_UPDATE_MODIFY_TIME (0x00000002)
#define UDF_VCB_IC_UPDATE_ATTR_TIME (0x00000004)
#define UDF_VCB_IC_UPDATE_ARCH_BIT (0x00000008)
#define UDF_VCB_IC_UPDATE_DIR_WRITE (0x00000010)
#define UDF_VCB_IC_UPDATE_DIR_READ (0x00000020)
#define UDF_VCB_IC_WRITE_IN_RO_DIR (0x00000040)
#define UDF_VCB_IC_UPDATE_UCHG_DIR_ACCESS_TIME (0x00000080)
#define UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS (0x00000100)
#define UDF_VCB_IC_HW_RO (0x00000200)
#define UDF_VCB_IC_OS_NATIVE_DOS_NAME (0x00000400)
#define UDF_VCB_IC_FORCE_WRITE_THROUGH (0x00000800)
#define UDF_VCB_IC_FORCE_HW_RO (0x00001000)
#define UDF_VCB_IC_IGNORE_SEQUENTIAL_IO (0x00002000)
#define UDF_VCB_IC_NO_SYNCCACHE_AFTER_WRITE (0x00004000)
#define UDF_VCB_IC_BAD_RW_SEEK (0x00008000)
#define UDF_VCB_IC_FP_ADDR_PROBLEM (0x00010000)
#define UDF_VCB_IC_MRW_ADDR_PROBLEM (0x00020000)
#define UDF_VCB_IC_BAD_DVD_LAST_LBA (0x00040000)
#define UDF_VCB_IC_SYNCCACHE_BEFORE_READ (0x00080000)
#define UDF_VCB_IC_INSTANT_COMPAT_ALLOC_DESCS (0x00100000)
#define UDF_VCB_IC_SOFT_RO (0x00200000)
#define UDF_VCB_IC_DIRTY_RO (0x04000000)
#define UDF_VCB_IC_W2K_COMPAT_VLABEL (0x08000000)
#define UDF_VCB_IC_CACHE_BAD_VDS (0x10000000)
#define UDF_VCB_IC_WAIT_CD_SPINUP (0x20000000)
#define UDF_VCB_IC_SHOW_BLANK_CD (0x40000000)
#define UDF_VCB_IC_ADAPTEC_NONALLOC_COMPAT (0x80000000)
// Some defines
#define UDFIsDvdMedia(Vcb) (Vcb->DVD_Mode)
#define UDFIsWriteParamsReq(Vcb) (Vcb->WriteParamsReq && !Vcb->DVD_Mode)
/**************************************************************************
we will store all of our global variables in one structure.
Global variables are not specific to any mounted volume BUT
by definition are required for successful operation of the
FSD implementation.
**************************************************************************/
typedef struct _UDFData {
#ifdef _UDF_STRUCTURES_H_
UDFIdentifier NodeIdentifier;
// the fields in this list are protected by the following resource
ERESOURCE GlobalDataResource;
// each driver has a driver object created for it by the NT I/O Mgr.
// we are no exception to this rule.
PDRIVER_OBJECT DriverObject;
// we will create a device object for our FSD as well ...
// Although not really required, it helps if a helper application
// writen by us wishes to send us control information via
// IOCTL requests ...
PDEVICE_OBJECT UDFDeviceObject;
PDEVICE_OBJECT UDFDeviceObject_CD;
PDEVICE_OBJECT UDFDeviceObject_HDD;
PDEVICE_OBJECT UDFDeviceObject_TAPE;
PDEVICE_OBJECT UDFDeviceObject_OTHER;
PDEVICE_OBJECT UDFFilterDeviceObject;
// we will keep a list of all logical volumes for our UDF FSD
LIST_ENTRY VCBQueue;
// the NT Cache Manager, the I/O Manager and we will conspire
// to bypass IRP usage using the function pointers contained
// in the following structure
FAST_IO_DISPATCH UDFFastIoDispatch;
// The NT Cache Manager uses the following call backs to ensure
// correct locking hierarchy is maintained
CACHE_MANAGER_CALLBACKS CacheMgrCallBacks;
// structures allocated from a zone need some fields here. Note
// that under version 4.0, it might be better to use lookaside
// lists
KSPIN_LOCK ZoneAllocationSpinLock;
ZONE_HEADER ObjectNameZoneHeader;
ZONE_HEADER CCBZoneHeader;
ZONE_HEADER FCBZoneHeader;
ZONE_HEADER IrpContextZoneHeader;
// ZONE_HEADER FileInfoZoneHeader;
VOID *ObjectNameZone;
VOID *CCBZone;
VOID *FCBZone;
VOID *IrpContextZone;
// VOID *FileInfoZone;
// currently, there is a single default zone size value used for
// all zones. This should ideally be changed by you to be 1 per
// type of zone (e.g. a default size for the FCB zone might be
// different from the default size for the ByteLock zone).
// Of course, you will need to use different values (min/max)
// for lookaside lists (if you decide to use them instead)
uint32 DefaultZoneSizeInNumStructs;
// Handle returned by the MUP is stored here.
HANDLE MupHandle;
// IsSync Resource
// ERESOURCE IsSyncResource;
// Is operation synchronous flag
// BOOLEAN IsSync;
// delayed close support
ERESOURCE DelayedCloseResource;
ULONG MaxDelayedCloseCount;
ULONG DelayedCloseCount;
ULONG MinDelayedCloseCount;
ULONG MaxDirDelayedCloseCount;
ULONG DirDelayedCloseCount;
ULONG MinDirDelayedCloseCount;
LIST_ENTRY DelayedCloseQueue;
LIST_ENTRY DirDelayedCloseQueue;
WORK_QUEUE_ITEM CloseItem;
WORK_QUEUE_ITEM LicenseKeyItem;
BOOLEAN LicenseKeyItemStarted;
BOOLEAN FspCloseActive;
BOOLEAN ReduceDelayedClose;
BOOLEAN ReduceDirDelayedClose;
ULONG CPU_Count;
LARGE_INTEGER UDFLargeZero;
// mount event (for udf gui app)
PKEVENT MountEvent;
#endif //_UDF_STRUCTURES_H_
//HKEY hUdfRootKey;
UNICODE_STRING SavedRegPath;
UNICODE_STRING UnicodeStrRoot;
UNICODE_STRING UnicodeStrSDir;
UNICODE_STRING AclName;
// WCHAR UnicodeStrRootBuffer[2];
ULONG WCacheMaxFrames;
ULONG WCacheMaxBlocks;
ULONG WCacheBlocksPerFrameSh;
ULONG WCacheFramesToKeepFree;
// some state information is maintained in the flags field
uint32 UDFFlags;
PVOID AutoFormatCount;
} UDFData, *PtrUDFData;
// valid flag values for the global data structure
#define UDF_DATA_FLAGS_RESOURCE_INITIALIZED (0x00000001)
#define UDF_DATA_FLAGS_ZONES_INITIALIZED (0x00000002)
#define UDF_DATA_FLAGS_BEING_UNLOADED (0x00000004)
/**/
extern VOID UDFSetModified(
IN PVCB Vcb
);
extern VOID UDFPreClrModified(
IN PVCB Vcb
);
extern VOID UDFClrModified(
IN PVCB Vcb
);
#define FILE_ID_CACHE_GRANULARITY 16
#define DLOC_LIST_GRANULARITY 16
typedef LONGLONG FILE_ID;
typedef FILE_ID *PFILE_ID;
#endif //__UDF_COMMON_STRUCT__H__