//////////////////////////////////////////////////////////////////// // 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__