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

556 lines
18 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.
////////////////////////////////////////////////////////////////////
/*
Module Name: udf_rel.h
Abstract:
Contains udf related structures.
Environment:
Both kernel and user mode
*/
#ifndef _UDF_REL_H_
#define _UDF_REL_H_
#include "Include/platform.h"
#include "ecma_167.h"
#ifdef UDF_LIMIT_DIR_SIZE
typedef uint8 uint_di;
#else //UDF_LIMIT_DIR_SIZE
typedef uint32 uint_di;
#endif //UDF_LIMIT_DIR_SIZE
typedef struct _UDFTrackMap {
uint32 FirstLba;
uint32 LastLba;
uint32 NWA;
uint32 PacketSize;
uint32 Session;
uint8 TrackParam;
uint8 DataParam;
uint8 NWA_V;
uint8 Flags;
#define TrackMap_AllowCopyBit_variated 0x01
#define TrackMap_CopyBit_variated 0x02
#define TrackMap_Try_variation 0x04
#define TrackMap_Use_variation 0x08
#define TrackMap_FixFPAddressing 0x10
#define TrackMap_FixMRWAddressing 0x20
// are used only if FixFPAddressing is enabled
uint32 TrackFPOffset;
uint32 PacketFPOffset;
} UDFTrackMap, *PUDFTrackMap;
typedef struct _UDFSparingData
{
uint32 SparingLocation;
uint16 SparingPLength;
} UDFSparingData, *PUDFSparingData;
#define PACK_MAPPING_THRESHOLD (sizeof(EXTENT_MAP)*8)
typedef struct _EXTENT_INFO {
uint32 Offset;
PEXTENT_MAP Mapping;
int64 Length; // user data
BOOLEAN Modified; // mapping
UCHAR Flags;
/*
UCHAR Reserved[2];
PVOID Cache;
*/
} EXTENT_INFO, *PEXTENT_INFO;
#define EXTENT_FLAG_ALLOC_STD 0x00
#define EXTENT_FLAG_ALLOC_SEQUENTIAL 0x01
#define EXTENT_FLAG_ALLOC_MASK 0x03
#define EXTENT_FLAG_PREALLOCATED 0x80
#define EXTENT_FLAG_CUT_PREALLOCATED 0x40
#define EXTENT_FLAG_VERIFY 0x20
#define EXTENT_FLAG_2K_COMPAT 0x10
typedef struct _UDFPartMap
{
uint32 UspaceBitmap; // Lba
uint32 FspaceBitmap; // Lba
uint32 AccessType;
uint32 PartitionRoot;
uint32 PartitionLen;
uint16 PartitionType;
uint16 PartitionNum;
uint16 VolumeSeqNum;
} UDFPartMap, *PUDFPartMap;
#define VDS_POS_PRIMARY_VOL_DESC 0
#define VDS_POS_UNALLOC_SPACE_DESC 1
#define VDS_POS_LOGICAL_VOL_DESC 2
#define VDS_POS_PARTITION_DESC 3
#define VDS_POS_IMP_USE_VOL_DESC 4
#define VDS_POS_VOL_DESC_PTR 5
#define VDS_POS_TERMINATING_DESC 6
#define VDS_POS_RECURSION_COUNTER 7
#define VDS_POS_LENGTH 8
typedef struct _UDF_VDS_RECORD {
uint32 block;
uint32 volDescSeqNum;
} UDF_VDS_RECORD, *PUDF_VDS_RECORD;
#define VRS_NSR02_FOUND 0x0001
#define VRS_NSR03_FOUND 0x0002
#define VRS_ISO9660_FOUND 0x0004
#define EXTENT_MAP_GRAN (8*sizeof(LONG_AD))
#define DIR_INDEX_MAP_GRAN (8*sizeof(DIR_INDEX))
#define SHORT_AD_GRAN (8*sizeof(SHORT_AD))
#define RELOC_MAP_GRAN (8*sizeof(EXT_RELOCATION_ENTRY))
#define ALLOC_DESC_MAX_RECURSE 256
struct _UDF_FILE_INFO;
struct _DIR_INDEX_ITEM;
#define UDF_DIR_INDEX_MT PagedPool
#define UDF_FILENAME_MT PagedPool
typedef struct _HASH_ENTRY {
uint32 hDos; // hash for Dos-name
uint32 hLfn; // hash for Upcased Lfn
uint32 hPosix; // hash for Posix Lfn
} HASH_ENTRY, *PHASH_ENTRY;
typedef struct _DIR_INDEX_HDR {
uint_di FirstFree;
uint_di LastUsed;
uint_di FrameCount;
uint_di LastFrameCount; // in items
uint_di DelCount;
EXTENT_INFO FECharge; // file entry charge
EXTENT_INFO FEChargeSDir; // file entry charge for streams
ULONG DIFlags;
// struct _DIR_INDEX_ITEM* FrameList[0];
} DIR_INDEX_HDR, *PDIR_INDEX_HDR;
// Initial location of directory data extent in IN_ICB
#define UDF_DI_FLAG_INIT_IN_ICB (0x01)
/**
This is an entry of file list. Each directory has such a list
for fast search & modification. This structure was introduced
because on-disk equivalents have variable sizes & record
formats.
*/
typedef struct _DIR_INDEX_ITEM {
// FSD-specific data
/**
Specifies the position of corresponding FileIdent inside the
directory (on-disk).
*/
uint32 Offset; // File Ident offset in extent
/**
Specifies on-disk size of FileIdent. 0 value of this field
means that given entry has no on-disk representation (ex. -
pointer to the directory itself). In this case #Offset
value must be also 0.
*/
uint32 Length; // Its length
/**
Points to file name in UnicodeString format. NULL value of
this field is treated as list terminator.
*/
UNICODE_STRING FName; // Filename
/**
Specifies on-disk location of FileEntry associated with the
given file. This value should be used for unopened files.
*/
lb_addr FileEntryLoc; // pointer to FileEntry
/**
Cached value from FileIdent (see #FILE_IDENT_DESC)
*/
uint8 FileCharacteristics;
/**
Set of flags. This is intended for internal use.
Valid flags:
- #UDF_FI_FLAG_FI_MODIFIED\n
Presence of this bit means that given FileIdent was modified
& should be flushed.
- #UDF_FI_FLAG_SYS_ATTR\n
Presence of this bit means that given entry of file list
contains valid file attributes & times in NT-specific format.
- #UDF_FI_FLAG_FI_INTERNAL\n
Presence of this bit means that given entry represents the
file used for internal FS purposes & must be invisible.
- #UDF_FI_FLAG_LINKED\n
Presence of this bit means that related FileEntry has more
than one FileIdent. It happends when we use HardLinks.
*/
uint8 FI_Flags; // FileIdent-related flags
/**
Points to FileInfo structure for opened files. This field
must be NULL if the file is not opened.
*/
struct _UDF_FILE_INFO* FileInfo; // associated FileInfo (if opened)
// search hashes
HASH_ENTRY hashes;
// attributes (System-specific format)
uint32 SysAttr;
int64 CreationTime;
int64 LastWriteTime;
int64 LastAccessTime;
int64 ChangeTime;
int64 FileSize;
int64 AllocationSize;
} DIR_INDEX_ITEM, *PDIR_INDEX_ITEM;
/// FileIdent was modified & should be flushed.
#define UDF_FI_FLAG_FI_MODIFIED (0x01)
/// Given entry of file list contains valid file attributes & times in NT-specific format.
#define UDF_FI_FLAG_SYS_ATTR (0x02)// cached flags in system-specific format
/// Given entry represents the file used for internal FS purposes & must be invisible
#define UDF_FI_FLAG_FI_INTERNAL (0x04)
/// Related FileEntry has more than one FileIdent. It happends when we use HardLinks.
#define UDF_FI_FLAG_LINKED (0x08)
#define UDF_FI_FLAG_DOS (0x10)// Lfn-style name is equal to DOS-style (case insensetive)
#define UDF_FI_FLAG_KEEP_NAME (0x20)
#define UDF_DATALOC_INFO_MT PagedPool
/**
This structure describes actual data location. It is an
analogue (and a pair in this implementation) of NTRequiredFcb
structure.
UDF FSD keeps list of all Dloc structures & their on-disk
representations. Before allocating new Dloc for newly opened
file the FSD checks if the Dloc with the same Lba is already
in memory. If it is so the initiator receive pointer to
existing structure instead of allocating new. This allows to
handle HardLiks properly. When all references to given Dloc
has gone it is released. In case of file deletion the
association between Dloc & Lba is discarded, but Dloc is not
released untill UDFCleanUpFile__() is called. This prevents
interference between deleted files & newly created ones in
case of equal Lba of deleted & created FileEntries.
*/
typedef struct _UDF_DATALOC_INFO {
/**
NT-specific field. As soon as NT supports HardLink concept it
has own structure describing the file's actual data.
*/
struct _UDFNTRequiredFCB* CommonFcb; // pointer to corresponding NtReqFcb
/**
Describes on-disk location of user data. If the file is
recorded using IN_ICB method this structure points to the
same LBA as #FELoc, but with non-zero offset inside logical
block
*/
EXTENT_INFO DataLoc; // user data
/**
Describes on-disk location of allocation descriptors. They
are part of metadata associated with given file If this
structure is not initialized UDF assumes that no allocation
descriptors recorded for this file. Usually this structure
points to the same LBA as #FELoc, but with non-zero offset
inside logical block. The only exception is for files
recorded using IN_ICB method (see above). In such a case this
structure must be zero-filled
*/
EXTENT_INFO AllocLoc; // allocation descriptors (if any)
/**
Describes on-disk location the FileEntry. This is on-disk
metadata block describing file location.
*/
EXTENT_INFO FELoc; // file entry location
/**
Pointer to cached FileEntry. This field mush be valid untill
all file instances are cleaned up (see UDFCleanUpFile__() and
#LinkRefCount).
*/
tag* FileEntry; // file entry data
uint32 FileEntryLen;
/**
Set of flags. This is intended for internal use.
Valid flags:
- #UDF_FE_FLAG_FE_MODIFIED\n
Presence of this bit means that given FileEntry was modified &
should be flushed
- #UDF_FE_FLAG_HAS_SDIR\n
Presence of this bit means that given FileEntry has an associated
Stream Dir.
- #UDF_FE_FLAG_IS_SDIR\n
Presence of this bit means that given FileEntry represents a Stream Dir.
*/
uint32 FE_Flags; // FileEntry flags
/**
Counter of currently opened directory tree instances (files)
pointing to given data. It is introduced because UDF supports
HardLink concept. UDF_DATALOC_INFO structure should not be
released untill this field reaches zero.
*/
uint32 LinkRefCount;
/**
Points to the list of files referenced by the given file.
This field is used for directories only. Otherwise its value
should be NULL.
*/
PDIR_INDEX_HDR DirIndex; // for Directory objects only
struct _UDF_FILE_INFO* LinkedFileInfo;
/**
Points to the FileInfo describing the StreamDirectory
associated with the given file. If the file has no associated
StreamDirectory this field must bu NULL.
*/
struct _UDF_FILE_INFO* SDirInfo;
} UDF_DATALOC_INFO, *PUDF_DATALOC_INFO;
/// Was modified & should be flushed
#define UDF_FE_FLAG_FE_MODIFIED (0x01)
/// File contains Stream Dir
#define UDF_FE_FLAG_HAS_SDIR (0x02)
/// File is a StreamDir
#define UDF_FE_FLAG_IS_SDIR (0x04)
/// Dir was modified & should be packed
#define UDF_FE_FLAG_DIR_MODIFIED (0x08)
/// File contains pointer to Deleted Stream Dir
#define UDF_FE_FLAG_HAS_DEL_SDIR (0x10)
/// File is Deleted Stream Dir
#define UDF_FE_FLAG_IS_DEL_SDIR (0x20)
/// Dloc is being initialized, don't touch it now
#define UDF_FE_FLAG_UNDER_INIT (0x40)
#define UDF_FILE_INFO_MT PagedPool
/**
This structure describes file location in the directory
tree.. It is an analogue (and a pair in this implementation)
of Fcb structure.
*/
typedef struct _UDF_FILE_INFO {
#ifdef VALIDATE_STRUCTURES
/**
Used for debug purposes. Each valid FileInfo structure has
IntegrityTag set to zero. If the routine receives FileInfo
with invalid IntegrityTag value the break occures.
*/
uint32 IntegrityTag;
#endif
/**
Points to the NT structure describing file instance in the
directory tree. Each file opened by NT has Fcb structure &
associated FileInfo. If the file is opened by UDF FSD for
internal use this field may be NULL. Each Fcb has a back
pointer to FileInfo, so both structures are accessable.
*/
struct _UDFFileControlBlock* Fcb; // pointer to corresponding Fcb (null if absent)
/**
Points to the structure describing actual data location &
file attributes. See #UDF_DATALOC_INFO for more information.
*/
PUDF_DATALOC_INFO Dloc; // actual data location descriptor
/**
Pointer to cached FileIdent. This field mush be valid untill
the file is cleaned up (see UDFCleanUpFile__()).
*/
PFILE_IDENT_DESC FileIdent; // file ident data
/**
Length of the buffer allocated for FileIdent.
*/
uint32 FileIdentLen;
/**
Points to FileInfo structure of the Parent Directory. If the
file has no parent directory this field must be NULL.
*/
struct _UDF_FILE_INFO* ParentFile; // parent (directory) if any
/**
Number of entry in the DirIndex of the parent directory. It
is used for fast access & modification of the parent.
FileInfo with index equal to 0 usually describes the
directory itself (file name is '.' & the parent is given
directory itself). FileInfo with index equal to 1 usually
describes the parent (file name is '..'). Otherwise FileInfo
describes a plain file or directory. If the file has no
parent this field must be 0.
*/
uint_di Index; // index in parent directory
/**
Counter of open operations. Each routine opening the file
increments this counter, each routine closing the file -
decrements. The FileInfo structure can't be released untill
this counter reachs zero.
*/
uint32 RefCount; // number of references
/**
Counter of open operations performed for subsequent files.
Each routine opening the file increments this counter in
parent FileInfo structure, each routine closing the file -
decrements. The FileInfo structure can't be released untill
this counter reachs zero.
*/
uint32 OpenCount; // number of opened files in Dir
struct _UDF_FILE_INFO* NextLinkedFile; //
struct _UDF_FILE_INFO* PrevLinkedFile; //
struct _FE_LIST_ENTRY* ListPtr;
} UDF_FILE_INFO, *PUDF_FILE_INFO;
typedef struct _FE_LIST_ENTRY {
PUDF_FILE_INFO FileInfo;
ULONG EntryRefCount;
} FE_LIST_ENTRY, *PFE_LIST_ENTRY;
#define DOS_NAME_LEN 8
#define DOS_EXT_LEN 3
#define ILLEGAL_CHAR_MARK 0x005F
#define UNICODE_CRC_MARK 0x0023
#define UNICODE_PERIOD 0x002E
#define UNICODE_SPACE 0x0020
#define LBA_OUT_OF_EXTENT ((ULONG)(-1))
#define LBA_NOT_ALLOCATED ((ULONG)(-2))
typedef struct _EXT_RELOCATION_ENTRY {
uint32 extLength;
uint32 extLocation;
uint32 extRedir;
} EXT_RELOCATION_ENTRY, *PEXT_RELOCATION_ENTRY;
typedef struct _UDF_DATALOC_INDEX {
uint32 Lba;
PUDF_DATALOC_INFO Dloc;
} UDF_DATALOC_INDEX, *PUDF_DATALOC_INDEX;
typedef struct _UDF_DIR_SCAN_CONTEXT {
PUDF_FILE_INFO DirInfo;
PDIR_INDEX_HDR hDirNdx;
PDIR_INDEX_ITEM DirNdx;
uint32 frame;
uint_di j;
uint32 d;
uint_di i;
} UDF_DIR_SCAN_CONTEXT, *PUDF_DIR_SCAN_CONTEXT;
typedef EXT_RELOCATION_ENTRY EXT_RELOC_MAP;
typedef PEXT_RELOCATION_ENTRY PEXT_RELOC_MAP;
typedef struct _UDF_ALLOCATION_CACHE_ITEM {
lba_t ParentLocation;
uint32 Items;
EXTENT_INFO Ext;
} UDF_ALLOCATION_CACHE_ITEM, *PUDF_ALLOCATION_CACHE_ITEM;
/*
#define MEM_DIR_HDR_TAG (ULONG)"DirHdr"
#define MEM_DIR_NDX_TAG (ULONG)"DirNdx"
#define MEM_DLOC_NDX_TAG (ULONG)"DlocNdx"
#define MEM_DLOC_INF_TAG (ULONG)"DlocInf"
#define MEM_FNAME_TAG (ULONG)"FName"
#define MEM_FNAME16_TAG (ULONG)"FName16"
#define MEM_FNAMECPY_TAG (ULONG)"FNameC"
#define MEM_FE_TAG (ULONG)"FE"
#define MEM_XFE_TAG (ULONG)"xFE"
#define MEM_FID_TAG (ULONG)"FID"
#define MEM_FINF_TAG (ULONG)"FInf"
#define MEM_VATFINF_TAG (ULONG)"FInfVat"
#define MEM_SDFINF_TAG (ULONG)"SDirFInf"
#define MEM_EXTMAP_TAG (ULONG)"ExtMap"
#define MEM_ALLOCDESC_TAG (ULONG)"AllocDesc"
#define MEM_SHAD_TAG (ULONG)"SHAD"
#define MEM_LNGAD_TAG (ULONG)"LNGAD"
*/
#define MEM_DIR_HDR_TAG 'DirH'
#define MEM_DIR_NDX_TAG 'DirN'
#define MEM_DLOC_NDX_TAG 'Dloc'
#define MEM_DLOC_INF_TAG 'Dloc'
#define MEM_FNAME_TAG 'FNam'
#define MEM_FNAME16_TAG 'FNam'
#define MEM_FNAMECPY_TAG 'FNam'
#define MEM_FE_TAG 'FE'
#define MEM_XFE_TAG 'xFE"'
#define MEM_FID_TAG 'FID'
#define MEM_FINF_TAG 'FInf'
#define MEM_VATFINF_TAG 'FInf'
#define MEM_SDFINF_TAG 'SDir'
#define MEM_EXTMAP_TAG 'ExtM'
#define MEM_ALLOCDESC_TAG 'Allo'
#define MEM_SHAD_TAG 'SHAD'
#define MEM_LNGAD_TAG 'LNGA'
#define MEM_ALLOC_CACHE_TAG 'hcCA'
#define UDF_DEFAULT_LAST_LBA_CD 276159
#define UDF_DEFAULT_LAST_LBA_DVD 0x23053f
#define UDF_DEFAULT_FE_CHARGE 128
#define UDF_DEFAULT_FE_CHARGE_SDIR 1
#define UDF_WRITE_MAX_RETRY 4
#define UDF_READ_MAX_RETRY 4
#define UDF_READY_MAX_RETRY 5
#define ICB_FLAG_AD_DEFAULT_ALLOC_MODE (UCHAR)(0xff)
#define UDF_INVALID_LINK_COUNT 0xffff
#define UDF_MAX_LINK_COUNT 0x7fff
#define UDF_MAX_EXTENT_LENGTH (UDF_EXTENT_LENGTH_MASK & ~(2048-1))
#define UDF_MAX_READ_REVISION 0x0260
#define UDF_MAX_WRITE_REVISION 0x0201
#define UDF_MAX_LVID_CHAIN_LENGTH 1024
#define UDF_LVID_TTL 1024
#define UDF_NO_EXTENT_MAP ((PEXTENT_MAP)(ULONG_PTR)~0ULL)
#define UDF_FLUSH_FLAGS_LITE (0x80000000)
#if defined UDF_DBG || defined _CONSOLE
//#define UDF_CHECK_DISK_ALLOCATION
//#define UDF_TRACK_ONDISK_ALLOCATION
//#define UDF_TRACK_ONDISK_ALLOCATION_OWNERS
//#define UDF_TRACK_ONDISK_ALLOCATION_OWNERS_INTERNAL
//#define UDF_TRACK_EXTENT_TO_MAPPING
//#define UDF_TRACK_ALLOC_FREE_EXTENT
//#define UDF_CHECK_EXTENT_SIZE_ALIGNMENT
// dependences:
#ifdef UDF_TRACK_ALLOC_FREE_EXTENT
#define UDF_TRACK_EXTENT_TO_MAPPING
#endif //UDF_TRACK_ALLOC_FREE_EXTENT
#endif //UDF_DBG
typedef struct _UDF_VERIFY_CTX {
uint8* StoredBitMap;
ULONG ItemCount;
LIST_ENTRY vrfList;
ERESOURCE VerifyLock;
KEVENT vrfEvent;
uint32 WaiterCount;
uint32 QueuedCount;
BOOLEAN VInited;
} UDF_VERIFY_CTX, *PUDF_VERIFY_CTX;
#endif /* _UDF_REL_H_ */