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

1339 lines
51 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_STRUCT_SUPPORT_H__
#define __UDF_STRUCT_SUPPORT_H__
#include "ecma_167.h"
#include "osta_misc.h"
#include "udf_rel.h"
#include "wcache.h"
// memory re-allocation (returns new buffer size)
uint32 UDFMemRealloc(IN int8* OldBuff, // old buffer
IN uint32 OldLength, // old buffer size
OUT int8** NewBuff, // address to store new pointer
IN uint32 NewLength); // required size
// convert offset in extent to Lba & calculate block parameters
// it also returns pointer to last valid entry & flags
uint32
UDFExtentOffsetToLba(IN PVCB Vcb,
IN PEXTENT_AD Extent, // Extent array
IN int64 Offset, // offset in extent
OUT uint32* SectorOffset,
OUT PSIZE_T AvailLength, // available data in this block
OUT uint32* Flags,
OUT uint32* Index);
// locate frag containing specified Lba in extent
ULONG
UDFLocateLbaInExtent(
IN PVCB Vcb,
IN PEXTENT_MAP Extent, // Extent array
IN lba_t lba
);
// see udf_rel.h
//#define LBA_OUT_OF_EXTENT ((LONG)(-1))
//#define LBA_NOT_ALLOCATED ((LONG)(-2))
// read data at any offset from extent
OSSTATUS UDFReadExtent(IN PVCB Vcb,
IN PEXTENT_INFO ExtInfo, // Extent array
IN int64 Offset, // offset in extent
IN SIZE_T Length,
IN BOOLEAN Direct,
OUT int8* Buffer,
OUT PSIZE_T ReadBytes);
// builds mapping for specified amount of data at any offset from specified extent.
OSSTATUS
UDFReadExtentLocation(IN PVCB Vcb,
IN PEXTENT_INFO ExtInfo, // Extent array
IN int64 Offset, // offset in extent to start SubExtent from
OUT PEXTENT_MAP* _SubExtInfo, // SubExtent mapping array
IN OUT uint32* _SubExtInfoSz, // IN: maximum number fragments to get
// OUT: actually obtained fragments
OUT int64* _NextOffset // offset, caller can start from to continue
);
// calculate total length of extent
int64 UDFGetExtentLength(IN PEXTENT_MAP Extent); // Extent array
// convert compressed Unicode to standard
void
__fastcall UDFDecompressUnicode(IN OUT PUNICODE_STRING UName,
IN uint8* CS0,
IN SIZE_T Length,
OUT uint16* valueCRC);
// calculate hashes for directory search
uint8 UDFBuildHashEntry(IN PVCB Vcb,
IN PUNICODE_STRING Name,
OUT PHASH_ENTRY hashes,
IN uint8 Mask);
#define HASH_POSIX 0x01
#define HASH_ULFN 0x02
#define HASH_DOS 0x04
#define HASH_ALL 0x07
#define HASH_KEEP_NAME 0x08 // keep DOS '.' and '..' intact
// get dirindex's frame
PDIR_INDEX_ITEM UDFDirIndexGetFrame(IN PDIR_INDEX_HDR hDirNdx,
IN uint32 Frame,
OUT uint32* FrameLen,
OUT uint_di* Index,
IN uint_di Rel);
// release DirIndex
void UDFDirIndexFree(PDIR_INDEX_HDR hDirNdx);
// grow DirIndex
OSSTATUS UDFDirIndexGrow(IN PDIR_INDEX_HDR* _hDirNdx,
IN uint_di d);
// truncate DirIndex
OSSTATUS UDFDirIndexTrunc(IN PDIR_INDEX_HDR* _hDirNdx,
IN uint_di d);
// init variables for scan (using knowledge about internal structure)
BOOLEAN UDFDirIndexInitScan(IN PUDF_FILE_INFO DirInfo, //
OUT PUDF_DIR_SCAN_CONTEXT Context,
IN uint_di Index);
//
PDIR_INDEX_ITEM UDFDirIndexScan(PUDF_DIR_SCAN_CONTEXT Context,
PUDF_FILE_INFO* _FileInfo);
// build directory index
OSSTATUS UDFIndexDirectory(IN PVCB Vcb,
IN OUT PUDF_FILE_INFO FileInfo);
// search for specified file in specified directory &
// returns corresponding offset in extent if found.
OSSTATUS UDFFindFile(IN PVCB Vcb,
IN BOOLEAN IgnoreCase,
IN BOOLEAN NotDeleted,
IN PUNICODE_STRING Name,
IN PUDF_FILE_INFO DirInfo,
IN OUT uint_di* Index);
__inline OSSTATUS UDFFindFile__(IN PVCB Vcb,
IN BOOLEAN IgnoreCase,
IN PUNICODE_STRING Name,
IN PUDF_FILE_INFO DirInfo)
{
if(!DirInfo->Dloc->DirIndex)
return STATUS_NOT_A_DIRECTORY;
uint_di i=0;
return UDFFindFile(Vcb, IgnoreCase, TRUE, Name, DirInfo, &i);
}
// calculate file mapping length (in bytes) including ZERO-terminator
uint32 UDFGetMappingLength(IN PEXTENT_MAP Extent);
// merge 2 sequencial file mappings
PEXTENT_MAP
__fastcall UDFMergeMappings(IN PEXTENT_MAP Extent,
IN PEXTENT_MAP Extent2);
// build file mapping according to ShortAllocDesc (SHORT_AD) array
PEXTENT_MAP UDFShortAllocDescToMapping(IN PVCB Vcb,
IN uint32 PartNum,
IN PLONG_AD AllocDesc,
IN uint32 AllocDescLength,
IN uint32 SubCallCount,
OUT PEXTENT_INFO AllocLoc);
// build file mapping according to LongAllocDesc (LONG_AD) array
PEXTENT_MAP UDFLongAllocDescToMapping(IN PVCB Vcb,
IN PLONG_AD AllocDesc,
IN uint32 AllocDescLength,
IN uint32 SubCallCount,
OUT PEXTENT_INFO AllocLoc);
// build file mapping according to ExtendedAllocDesc (EXT_AD) array
PEXTENT_MAP UDFExtAllocDescToMapping(IN PVCB Vcb,
IN PLONG_AD AllocDesc,
IN uint32 AllocDescLength,
IN uint32 SubCallCount,
OUT PEXTENT_INFO AllocLoc);
// build file mapping according to (Extended)FileEntry
PEXTENT_MAP UDFReadMappingFromXEntry(IN PVCB Vcb,
IN uint32 PartNum,
IN tag* XEntry,
IN OUT uint32* Offset,
OUT PEXTENT_INFO AllocLoc);
// read FileEntry described in FileIdentDesc
OSSTATUS UDFReadFileEntry(IN PVCB Vcb,
// IN PFILE_IDENT_DESC FileDesc,
IN long_ad* Icb,
IN OUT PFILE_ENTRY FileEntry, // here we can also get ExtendedFileEntry
IN OUT uint16* Ident);
// scan FileSet sequence & return last valid FileSet
OSSTATUS UDFFindLastFileSet(IN PVCB Vcb,
IN lb_addr *Addr, // Addr for the 1st FileSet
IN OUT PFILE_SET_DESC FileSetDesc);
// read all sparing tables & stores them in contiguos memory
OSSTATUS UDFLoadSparingTable(IN PVCB Vcb,
IN PSPARABLE_PARTITION_MAP PartMap);
// build mapping for extent
PEXTENT_MAP
__fastcall UDFExtentToMapping_(IN PEXTENT_AD Extent
#ifdef UDF_TRACK_EXTENT_TO_MAPPING
,IN ULONG src,
IN ULONG line
#endif //UDF_TRACK_EXTENT_TO_MAPPING
);
#ifdef UDF_TRACK_EXTENT_TO_MAPPING
#define UDFExtentToMapping(e) UDFExtentToMapping_(e, UDF_BUG_CHECK_ID, __LINE__)
#else //UDF_TRACK_EXTENT_TO_MAPPING
#define UDFExtentToMapping(e) UDFExtentToMapping_(e)
#endif //UDF_TRACK_EXTENT_TO_MAPPING
// This routine remaps sectors from bad packet
OSSTATUS
__fastcall UDFRemapPacket(IN PVCB Vcb,
IN uint32 Lba,
IN BOOLEAN RemapSpared);
// This routine releases sector mapping when entire packet is marked as free
OSSTATUS
__fastcall UDFUnmapRange(IN PVCB Vcb,
IN uint32 Lba,
IN uint32 BCount);
// return physical address for relocated sector
uint32
__fastcall UDFRelocateSector(IN PVCB Vcb,
IN uint32 Lba);
// check
BOOLEAN
__fastcall UDFAreSectorsRelocated(IN PVCB Vcb,
IN uint32 Lba,
IN uint32 BlockCount);
// build mapping for relocated extent
PEXTENT_MAP
__fastcall UDFRelocateSectors(IN PVCB Vcb,
IN uint32 Lba,
IN uint32 BlockCount);
// check for presence of given char among specified ones
BOOLEAN UDFUnicodeInString(IN uint8* string,
IN WCHAR ch); // Unicode char to search for.
// validate char
BOOLEAN
__fastcall UDFIsIllegalChar(IN WCHAR ch);
// translate udfName to dosName using OSTA compliant.
#define UDFDOSName__(Vcb, DosName, UdfName, FileInfo) \
UDFDOSName(Vcb, DosName, UdfName, (FileInfo) && ((FileInfo)->Index < 2));
void
__fastcall UDFDOSName(IN PVCB Vcb,
IN OUT PUNICODE_STRING DosName,
IN PUNICODE_STRING UdfName,
IN BOOLEAN KeepIntact);
void
__fastcall UDFDOSName201(IN OUT PUNICODE_STRING DosName,
IN PUNICODE_STRING UdfName,
IN BOOLEAN KeepIntact);
void
__fastcall UDFDOSName200(IN OUT PUNICODE_STRING DosName,
IN PUNICODE_STRING UdfName,
IN BOOLEAN KeepIntact,
IN BOOLEAN Mode150);
void
__fastcall UDFDOSName100(IN OUT PUNICODE_STRING DosName,
IN PUNICODE_STRING UdfName,
IN BOOLEAN KeepIntact);
// return length of bit-chain starting from Offs bit
#ifdef _X86_
SIZE_T
__stdcall
UDFGetBitmapLen(
#else // NO X86 optimization , use generic C/C++
SIZE_T UDFGetBitmapLen(
#endif // _X86_
uint32* Bitmap,
SIZE_T Offs,
SIZE_T Lim);
// scan disc free space bitmap for minimal suitable extent
SIZE_T UDFFindMinSuitableExtent(IN PVCB Vcb,
IN uint32 Length, // in blocks
IN uint32 SearchStart,
IN uint32 SearchLim,
OUT uint32* MaxExtLen,
IN uint8 AllocFlags);
#ifdef UDF_CHECK_DISK_ALLOCATION
// mark space described by Mapping as Used/Freed (optionaly)
void UDFCheckSpaceAllocation_(IN PVCB Vcb,
IN PEXTENT_MAP Map,
IN uint32 asXXX
#ifdef UDF_TRACK_ONDISK_ALLOCATION
,IN uint32 FE_lba,
IN uint32 BugCheckId,
IN uint32 Line
#endif //UDF_TRACK_ONDISK_ALLOCATION
);
#ifdef UDF_TRACK_ONDISK_ALLOCATION
#define UDFCheckSpaceAllocation(Vcb, FileInfo, Map, asXXX) \
UDFCheckSpaceAllocation_(Vcb, Map, asXXX, (uint32)FileInfo, UDF_BUG_CHECK_ID,__LINE__);
#else //UDF_TRACK_ONDISK_ALLOCATION
#define UDFCheckSpaceAllocation(Vcb, FileInfo, Map, asXXX) \
UDFCheckSpaceAllocation_(Vcb, Map, asXXX);
#endif //UDF_TRACK_ONDISK_ALLOCATION
#else // UDF_CHECK_DISK_ALLOCATION
#define UDFCheckSpaceAllocation(Vcb, FileInfo, Map, asXXX) {;}
#endif //UDF_CHECK_DISK_ALLOCATION
// mark space described by Mapping as Used/Freed (optionaly)
// this routine doesn't acquire any resource
void
UDFMarkSpaceAsXXXNoProtect_(
IN PVCB Vcb,
IN PEXTENT_MAP Map,
IN uint32 asXXX
#ifdef UDF_TRACK_ONDISK_ALLOCATION
,IN uint32 FE_lba,
IN uint32 BugCheckId,
IN uint32 Line
#endif //UDF_TRACK_ONDISK_ALLOCATION
);
#ifdef UDF_TRACK_ONDISK_ALLOCATION
#define UDFMarkSpaceAsXXXNoProtect(Vcb, FileInfo, Map, asXXX) \
UDFMarkSpaceAsXXXNoProtect_(Vcb, Map, asXXX, (uint32)FileInfo, UDF_BUG_CHECK_ID,__LINE__);
#else //UDF_TRACK_ONDISK_ALLOCATION
#define UDFMarkSpaceAsXXXNoProtect(Vcb, FileInfo, Map, asXXX) \
UDFMarkSpaceAsXXXNoProtect_(Vcb, Map, asXXX);
#endif //UDF_TRACK_ONDISK_ALLOCATION
// mark space described by Mapping as Used/Freed (optionaly)
void UDFMarkSpaceAsXXX_(IN PVCB Vcb,
IN PEXTENT_MAP Map,
IN uint32 asXXX
#ifdef UDF_TRACK_ONDISK_ALLOCATION
,IN uint32 FE_lba,
IN uint32 BugCheckId,
IN uint32 Line
#endif //UDF_TRACK_ONDISK_ALLOCATION
);
#ifdef UDF_TRACK_ONDISK_ALLOCATION
#define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX) \
UDFMarkSpaceAsXXX_(Vcb, Map, asXXX, (uint32)FileInfo, UDF_BUG_CHECK_ID,__LINE__);
#else //UDF_TRACK_ONDISK_ALLOCATION
#define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX) \
UDFMarkSpaceAsXXX_(Vcb, Map, asXXX);
#endif //UDF_TRACK_ONDISK_ALLOCATION
#define AS_FREE 0x00
#define AS_USED 0x01
#define AS_DISCARDED 0x02
#define AS_BAD 0x04
// build mapping for Length bytes in FreeSpace
OSSTATUS UDFAllocFreeExtent_(IN PVCB Vcb,
IN int64 Length,
IN uint32 SearchStart,
IN uint32 SearchLim,
OUT PEXTENT_INFO Extent,
IN uint8 AllocFlags
#ifdef UDF_TRACK_ALLOC_FREE_EXTENT
,IN uint32 src,
IN uint32 line
#endif //UDF_TRACK_ALLOC_FREE_EXTENT
);
#ifdef UDF_TRACK_ALLOC_FREE_EXTENT
#define UDFAllocFreeExtent(v, l, ss, sl, e, af) UDFAllocFreeExtent_(v, l, ss, sl, e, af, UDF_BUG_CHECK_ID, __LINE__)
#else //UDF_TRACK_ALLOC_FREE_EXTENT
#define UDFAllocFreeExtent(v, l, ss, sl, e, af) UDFAllocFreeExtent_(v, l, ss, sl, e, af)
#endif //UDF_TRACK_ALLOC_FREE_EXTENT
//
uint32 __fastcall
UDFGetPartFreeSpace(IN PVCB Vcb,
IN uint32 partNum);
#define UDF_PREALLOC_CLASS_FE 0x00
#define UDF_PREALLOC_CLASS_DIR 0x01
// try to find cached allocation
OSSTATUS
UDFGetCachedAllocation(
IN PVCB Vcb,
IN uint32 ParentLocation,
OUT PEXTENT_INFO Ext,
OUT uint32* Items, // optional
IN uint32 AllocClass
);
// put released pre-allocation to cache
OSSTATUS
UDFStoreCachedAllocation(
IN PVCB Vcb,
IN uint32 ParentLocation,
IN PEXTENT_INFO Ext,
IN uint32 Items,
IN uint32 AllocClass
);
// discard all cached allocations
OSSTATUS
UDFFlushAllCachedAllocations(
IN PVCB Vcb,
IN uint32 AllocClass
);
// allocate space for FE
OSSTATUS UDFAllocateFESpace(IN PVCB Vcb,
IN PUDF_FILE_INFO DirInfo,
IN uint32 PartNum,
IN PEXTENT_INFO FEExtInfo,
IN uint32 Len);
#ifndef UDF_READ_ONLY_BUILD
// free space FE's allocation
void UDFFreeFESpace(IN PVCB Vcb,
IN PUDF_FILE_INFO DirInfo,
IN PEXTENT_INFO FEExtInfo);
#endif //UDF_READ_ONLY_BUILD
#define FLUSH_FE_KEEP FALSE
#define FLUSH_FE_FOR_DEL TRUE
// flush FE charge
void UDFFlushFESpace(IN PVCB Vcb,
IN PUDF_DATALOC_INFO Dloc,
IN BOOLEAN Discard = FLUSH_FE_KEEP);
// discard file allocation
void UDFFreeFileAllocation(IN PVCB Vcb,
IN PUDF_FILE_INFO DirInfo,
IN PUDF_FILE_INFO FileInfo);
// convert physical address to logical in specified partition
uint32 UDFPhysLbaToPart(IN PVCB Vcb,
IN uint32 PartNum,
IN uint32 Addr);
/*#define UDFPhysLbaToPart(Vcb, PartNum, Addr) \
((Addr - Vcb->Partitions[PartNum].PartitionRoot) >> Vcb->LB2B_Bits)*/
// initialize Tag structure.
void UDFSetUpTag(IN PVCB Vcb,
IN tag* Tag,
IN uint16 DataLen,
IN uint32 TagLoc);
// build content for AllocDesc sequence for specified extent
OSSTATUS UDFBuildShortAllocDescs(IN PVCB Vcb,
IN uint32 PartNum,
OUT int8** Buff, // data for AllocLoc
IN uint32 InitSz,
IN OUT PUDF_FILE_INFO FileInfo);
// build data for AllocDesc sequence for specified
OSSTATUS UDFBuildLongAllocDescs(IN PVCB Vcb,
IN uint32 PartNum,
OUT int8** Buff, // data for AllocLoc
IN uint32 InitSz,
IN OUT PUDF_FILE_INFO FileInfo);
// builds FileEntry & associated AllocDescs for specified extent.
OSSTATUS UDFBuildFileEntry(IN PVCB Vcb,
IN PUDF_FILE_INFO DirInfo,
IN PUDF_FILE_INFO FileInfo,
IN uint32 PartNum,
IN uint16 AllocMode, // short/long/ext/in-icb
IN uint32 ExtAttrSz,
IN BOOLEAN Extended/*,
OUT PFILE_ENTRY* FEBuff,
OUT uint32* FELen,
OUT PEXTENT_INFO FEExtInfo*/);
// find partition containing given physical sector
uint32
__fastcall UDFGetPartNumByPhysLba(IN PVCB Vcb,
IN uint32 Lba);
// add given bitmap to existing one
#define UDF_FSPACE_BM 0x00
#define UDF_ZSPACE_BM 0x01
OSSTATUS UDFAddXSpaceBitmap(IN PVCB Vcb,
IN uint32 PartNum,
IN PSHORT_AD bm,
IN ULONG bm_type);
// subtract given Bitmap to existing one
OSSTATUS UDFDelXSpaceBitmap(IN PVCB Vcb,
IN uint32 PartNum,
IN PSHORT_AD bm);
// build FreeSpaceBitmap (internal) according to media parameters & input data
OSSTATUS UDFBuildFreeSpaceBitmap(IN PVCB Vcb,
IN uint32 PartNdx,
IN PPARTITION_HEADER_DESC phd,
IN uint32 Lba);
// fill ExtentInfo for specified FileEntry
OSSTATUS UDFLoadExtInfo(IN PVCB Vcb,
IN PFILE_ENTRY fe,
IN PLONG_AD fe_loc,
IN OUT PEXTENT_INFO FExtInfo,
IN OUT PEXTENT_INFO AExtInfo);
// convert standard Unicode to compressed
void
__fastcall UDFCompressUnicode(IN PUNICODE_STRING UName,
IN OUT uint8** _CS0,
IN OUT PSIZE_T Length);
// build FileIdent for specified FileEntry.
OSSTATUS UDFBuildFileIdent(IN PVCB Vcb,
IN PUNICODE_STRING fn,
IN PLONG_AD FileEntryIcb, // virtual address of FileEntry
IN uint32 ImpUseLen,
OUT PFILE_IDENT_DESC* _FileId,
OUT uint32* FileIdLen);
// rebuild mapping on write attempts to Alloc-Not-Rec area.
OSSTATUS UDFMarkAllocatedAsRecorded(IN PVCB Vcb,
IN int64 Offset,
IN uint32 Length,
IN PEXTENT_INFO ExtInfo); // Extent array
// rebuild mapping on write attempts to Not-Alloc-Not-Rec area
OSSTATUS UDFMarkNotAllocatedAsAllocated(IN PVCB Vcb,
IN int64 Offset,
IN uint32 Length,
IN PEXTENT_INFO ExtInfo); // Extent array
OSSTATUS UDFMarkAllocatedAsNotXXX(IN PVCB Vcb,
IN int64 Offset,
IN uint32 Length,
IN PEXTENT_INFO ExtInfo, // Extent array
IN BOOLEAN Deallocate);
#ifdef DBG
__inline OSSTATUS UDFMarkAllocatedAsNotAllocated(IN PVCB Vcb,
IN int64 Offset,
IN uint32 Length,
IN PEXTENT_INFO ExtInfo)
{
return UDFMarkAllocatedAsNotXXX(Vcb, Offset, Length, ExtInfo, TRUE);
}
#else
#define UDFMarkAllocatedAsNotAllocated(Vcb, Off, Len, Ext) \
UDFMarkAllocatedAsNotXXX(Vcb, Off, Len, Ext, TRUE)
#endif //DBG
#ifdef DBG
__inline OSSTATUS UDFMarkRecordedAsAllocated(IN PVCB Vcb,
IN int64 Offset,
IN uint32 Length,
IN PEXTENT_INFO ExtInfo)
{
return UDFMarkAllocatedAsNotXXX(Vcb, Offset, Length, ExtInfo, FALSE);
}
#else
#define UDFMarkRecordedAsAllocated(Vcb, Off, Len, Ext) \
UDFMarkAllocatedAsNotXXX(Vcb, Off, Len, Ext, FALSE)
#endif //DBG
// write data at any offset from specified extent.
OSSTATUS UDFWriteExtent(IN PVCB Vcb,
IN PEXTENT_INFO ExtInfo, // Extent array
IN int64 Offset, // offset in extent
IN SIZE_T Length,
IN BOOLEAN Direct, // setting this flag delays flushing of given
// data to indefinite term
IN int8* Buffer,
OUT PSIZE_T WrittenBytes);
// deallocate/zero data at any offset from specified extent.
OSSTATUS UDFZeroExtent(IN PVCB Vcb,
IN PEXTENT_INFO ExtInfo, // Extent array
IN int64 Offset, // offset in extent
IN SIZE_T Length,
IN BOOLEAN Deallocate, // deallocate frag or just mark as unrecorded
IN BOOLEAN Direct, // setting this flag delays flushing of given
// data to indefinite term
OUT PSIZE_T WrittenBytes);
#define UDFZeroExtent__(Vcb, Ext, Off, Len, Dir, WB) \
UDFZeroExtent(Vcb, Ext, Off, Len, FALSE, Dir, WB)
#define UDFSparseExtent__(Vcb, Ext, Off, Len, Dir, WB) \
UDFZeroExtent(Vcb, Ext, Off, Len, TRUE, Dir, WB)
uint32
__fastcall UDFPartStart(PVCB Vcb,
uint32 PartNum);
uint32
__fastcall UDFPartEnd(PVCB Vcb,
uint32 PartNum);
// resize extent & associated mapping
OSSTATUS UDFResizeExtent(IN PVCB Vcb,
IN uint32 PartNum,
IN int64 Length,
IN BOOLEAN AlwaysInIcb, // must be TRUE for AllocDescs
OUT PEXTENT_INFO ExtInfo);
// (re)build AllocDescs data & resize associated extent
OSSTATUS UDFBuildAllocDescs(IN PVCB Vcb,
IN uint32 PartNum,
IN OUT PUDF_FILE_INFO FileInfo,
OUT int8** AllocData);
// set informationLength field in (Ext)FileEntry
void UDFSetFileSize(IN PUDF_FILE_INFO FileInfo,
IN int64 Size);
// sync cached FileSize from DirNdx and actual FileSize from FE
void UDFSetFileSizeInDirNdx(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN int64* ASize);
// get informationLength field in (Ext)FileEntry
int64 UDFGetFileSize(IN PUDF_FILE_INFO FileInfo);
//
int64 UDFGetFileSizeFromDirNdx(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo);
// set lengthAllocDesc field in (Ext)FileEntry
void UDFSetAllocDescLen(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo);
// change fileLinkCount field in (Ext)FileEntry
void UDFChangeFileLinkCount(IN PUDF_FILE_INFO FileInfo,
IN BOOLEAN Increase);
#define UDFIncFileLinkCount(fi) UDFChangeFileLinkCount(fi, TRUE)
#define UDFDecFileLinkCount(fi) UDFChangeFileLinkCount(fi, FALSE)
// ee
void UDFSetEntityID_imp_(IN EntityID* eID,
IN uint8* Str,
IN uint32 Len);
// get fileLinkCount field from (Ext)FileEntry
uint16 UDFGetFileLinkCount(IN PUDF_FILE_INFO FileInfo);
#ifdef UDF_CHECK_UTIL
// set fileLinkCount field in (Ext)FileEntry
void
UDFSetFileLinkCount(
IN PUDF_FILE_INFO FileInfo,
uint16 LinkCount
);
#endif //UDF_CHECK_UTIL
#define UDFSetEntityID_imp(eID, Str) \
UDFSetEntityID_imp_(eID, (uint8*)(Str), sizeof(Str));
//
void UDFReadEntityID_Domain(PVCB Vcb,
EntityID* eID);
// get lengthExtendedAttr field in (Ext)FileEntry
uint32 UDFGetFileEALength(IN PUDF_FILE_INFO FileInfo);
// set UniqueID field in (Ext)FileEntry
void UDFSetFileUID(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo);
// get UniqueID field in (Ext)FileEntry
int64 UDFGetFileUID(IN PUDF_FILE_INFO FileInfo);
// change counters in LVID
void UDFChangeFileCounter(IN PVCB Vcb,
IN BOOLEAN FileCounter,
IN BOOLEAN Increase);
#define UDFIncFileCounter(Vcb) UDFChangeFileCounter(Vcb, TRUE, TRUE);
#define UDFDecFileCounter(Vcb) UDFChangeFileCounter(Vcb, TRUE, FALSE);
#define UDFIncDirCounter(Vcb) UDFChangeFileCounter(Vcb, FALSE, TRUE);
#define UDFDecDirCounter(Vcb) UDFChangeFileCounter(Vcb, FALSE, FALSE);
// write to file
OSSTATUS UDFWriteFile__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN int64 Offset,
IN SIZE_T Length,
IN BOOLEAN Direct,
IN int8* Buffer,
OUT PSIZE_T WrittenBytes);
// mark file as deleted & decrease file link counter.
OSSTATUS UDFUnlinkFile__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN BOOLEAN FreeSpace);
// delete all files in directory (FreeSpace = TRUE)
OSSTATUS UDFUnlinkAllFilesInDir(IN PVCB Vcb,
IN PUDF_FILE_INFO DirInfo);
// init UDF_FILE_INFO structure for specifiend file
OSSTATUS UDFOpenFile__(IN PVCB Vcb,
IN BOOLEAN IgnoreCase,
IN BOOLEAN NotDeleted,
IN PUNICODE_STRING fn,
IN PUDF_FILE_INFO DirInfo,
OUT PUDF_FILE_INFO* _FileInfo,
IN uint_di* IndexToOpen);
// init UDF_FILE_INFO structure for root directory
OSSTATUS UDFOpenRootFile__(IN PVCB Vcb,
IN lb_addr* RootLoc,
OUT PUDF_FILE_INFO FileInfo);
// free all memory blocks referenced by given FileInfo
uint32 UDFCleanUpFile__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo);
#define UDF_FREE_NOTHING 0x00
#define UDF_FREE_FILEINFO 0x01
#define UDF_FREE_DLOC 0x02
// create zero-sized file
OSSTATUS UDFCreateFile__(IN PVCB Vcb,
IN BOOLEAN IgnoreCase,
IN PUNICODE_STRING fn,
IN uint32 ExtAttrSz,
IN uint32 ImpUseLen,
IN BOOLEAN Extended,
IN BOOLEAN CreateNew,
IN OUT PUDF_FILE_INFO DirInfo,
OUT PUDF_FILE_INFO* _FileInfo);
// read data from file described with FileInfo
/*
This routine reads data from file described by FileInfo
*/
__inline
OSSTATUS UDFReadFile__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN int64 Offset, // offset in extent
IN SIZE_T Length,
IN BOOLEAN Direct,
OUT int8* Buffer,
OUT PSIZE_T ReadBytes)
{
ValidateFileInfo(FileInfo);
return UDFReadExtent(Vcb, &(FileInfo->Dloc->DataLoc), Offset, Length, Direct, Buffer, ReadBytes);
} // end UDFReadFile__()*/
/*
This routine reads data from file described by FileInfo
*/
__inline
OSSTATUS UDFReadFileLocation__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN int64 Offset, // offset in extent to start SubExtent from
OUT PEXTENT_MAP* SubExtInfo, // SubExtent mapping array
IN OUT uint32* SubExtInfoSz, // IN: maximum number fragments to get
// OUT: actually obtained fragments
OUT int64* NextOffset // offset, caller can start from to continue
)
{
ValidateFileInfo(FileInfo);
return UDFReadExtentLocation(Vcb, &(FileInfo->Dloc->DataLoc), Offset, SubExtInfo, SubExtInfoSz, NextOffset);
} // end UDFReadFile__()*/
/*
#define UDFReadFile__(Vcb, FileInfo, Offset, Length, Direct, Buffer, ReadBytes) \
(UDFReadExtent(Vcb, &((FileInfo)->Dloc->DataLoc), Offset, Length, Direct, Buffer, ReadBytes))
*/
// zero data in file described by FileInfo
__inline
OSSTATUS UDFZeroFile__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN int64 Offset, // offset in extent
IN uint32 Length,
IN BOOLEAN Direct,
OUT uint32* ReadBytes);
// make sparse area in file described by FileInfo
__inline
OSSTATUS UDFSparseFile__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN int64 Offset, // offset in extent
IN uint32 Length,
IN BOOLEAN Direct,
OUT uint32* ReadBytes);
// pad sector tail with zeros
OSSTATUS UDFPadLastSector(IN PVCB Vcb,
IN PEXTENT_INFO ExtInfo);
// update AllocDesc sequence, FileIdent & FileEntry
OSSTATUS UDFCloseFile__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo);
// load specified bitmap.
OSSTATUS UDFPrepareXSpaceBitmap(IN PVCB Vcb,
IN OUT PSHORT_AD XSpaceBitmap,
IN OUT PEXTENT_INFO XSBMExtInfo,
IN OUT int8** XSBM,
IN OUT uint32* XSl);
// update Freed & Unallocated space bitmaps
OSSTATUS UDFUpdateXSpaceBitmaps(IN PVCB Vcb,
IN uint32 PartNum,
IN PPARTITION_HEADER_DESC phd); // partition header pointing to Bitmaps
// update Partition Desc & associated data structures
OSSTATUS UDFUpdatePartDesc(PVCB Vcb,
int8* Buf);
// update Logical volume integrity descriptor
OSSTATUS UDFUpdateLogicalVolInt(PVCB Vcb,
BOOLEAN Close);
// blank Unalloc Space Desc
OSSTATUS UDFUpdateUSpaceDesc(IN PVCB Vcb,
int8* Buf);
// update Volume Descriptor Sequence
OSSTATUS UDFUpdateVDS(IN PVCB Vcb,
IN uint32 block,
IN uint32 lastblock,
IN uint32 flags);
// rebuild & flushes all system areas
OSSTATUS UDFUmount__(IN PVCB Vcb);
// move file from DirInfo1 to DirInfo2 & renames it to fn
OSSTATUS UDFRenameMoveFile__(IN PVCB Vcb,
IN BOOLEAN IgnoreCase,
IN OUT BOOLEAN* Replace, // replace if destination file exists
IN PUNICODE_STRING fn, // destination
// IN uint32 ExtAttrSz,
IN OUT PUDF_FILE_INFO DirInfo1,
IN OUT PUDF_FILE_INFO DirInfo2,
IN OUT PUDF_FILE_INFO FileInfo); // source (opened)
// change file size (on disc)
OSSTATUS UDFResizeFile__(IN PVCB Vcb,
IN OUT PUDF_FILE_INFO FileInfo,
IN int64 NewLength);
// transform zero-sized file to directory
OSSTATUS UDFRecordDirectory__(IN PVCB Vcb,
IN OUT PUDF_FILE_INFO DirInfo); // source (opened)
// remove all DELETED entries from Dir & resize it.
#ifndef UDF_READ_ONLY_BUILD
OSSTATUS UDFPackDirectory__(IN PVCB Vcb,
IN OUT PUDF_FILE_INFO FileInfo); // source (opened)
// rebuild tags for all entries from Dir.
OSSTATUS
UDFReTagDirectory(IN PVCB Vcb,
IN OUT PUDF_FILE_INFO FileInfo); // source (opened)
#endif //UDF_READ_ONLY_BUILD
// load VAT.
OSSTATUS UDFLoadVAT(IN PVCB Vcb,
IN uint32 PartNdx);
// get volume free space
int64
__fastcall UDFGetFreeSpace(IN PVCB Vcb);
// get volume total space
int64
__fastcall UDFGetTotalSpace(IN PVCB Vcb);
// get DirIndex for specified FileInfo
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo);
// check if the file has been found is deleted
/*BOOLEAN UDFIsDeleted(IN PDIR_INDEX_ITEM DirNdx);*/
#define UDFIsDeleted(DirNdx) \
(((DirNdx)->FileCharacteristics & FILE_DELETED) ? TRUE : FALSE)
// check Directory flag
/*BOOLEAN UDFIsADirectory(IN PUDF_FILE_INFO FileInfo);*/
#define UDFIsADirectory(FileInfo) \
(((FileInfo) && ((FileInfo)->Dloc) && ((FileInfo)->Dloc->DirIndex || ((FileInfo)->FileIdent && ((FileInfo)->FileIdent->fileCharacteristics & FILE_DIRECTORY)))) ? TRUE : FALSE)
// calculate actual allocation size
/*int64 UDFGetFileAllocationSize(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo);*/
#define UDFGetFileAllocationSize(Vcb, FileInfo) \
(((FileInfo)->Dloc->DataLoc.Mapping) ? UDFGetExtentLength((FileInfo)->Dloc->DataLoc.Mapping) : Vcb->LBlockSize)
// check if the directory is empty
BOOLEAN UDFIsDirEmpty(IN PDIR_INDEX_HDR hCurDirNdx);
// flush FE
OSSTATUS UDFFlushFE(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN uint32 PartNum);
// flush FI
OSSTATUS UDFFlushFI(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN uint32 PartNum);
// flush all metadata & update counters
OSSTATUS UDFFlushFile__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN ULONG FlushFlags = 0);
// check if the file is flushed
#define UDFIsFlushed(FI) \
( FI && \
!(FI->Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED) && \
!(FI->Dloc->DataLoc.Modified) && \
!(FI->Dloc->AllocLoc.Modified) &&\
!(FI->Dloc->FELoc.Modified) && \
!(UDFGetDirIndexByFileInfo(FI)[FI->Index].FI_Flags & UDF_FI_FLAG_FI_MODIFIED) )
// compare opened directories
BOOLEAN UDFCompareFileInfo(IN PUDF_FILE_INFO f1,
IN PUDF_FILE_INFO f2);
// pack mappings
void
__fastcall UDFPackMapping(IN PVCB Vcb,
IN PEXTENT_INFO ExtInfo); // Extent array
// check if all the data is in cache.
BOOLEAN UDFIsExtentCached(IN PVCB Vcb,
IN PEXTENT_INFO ExtInfo, // Extent array
IN int64 Offset, // offset in extent
IN uint32 Length,
IN BOOLEAN ForWrite);
/*BOOLEAN UDFIsFileCached__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN int64 Offset, // offset in extent
IN uint32 Length,
IN BOOLEAN ForWrite);*/
#define UDFIsFileCached__(Vcb, FileInfo, Offset, Length, ForWrite) \
(UDFIsExtentCached(Vcb, &((FileInfo)->Dloc->DataLoc), Offset, Length, ForWrite))
// check if specified sector belongs to a file
ULONG UDFIsBlockAllocated(IN void* _Vcb,
IN uint32 Lba);
// record VolIdent
OSSTATUS UDFUpdateVolIdent(IN PVCB Vcb,
IN UDF_VDS_RECORD Lba,
IN PUNICODE_STRING VolIdent);
// calculate checksum for unicode string (for DOS-names)
uint16
__fastcall UDFUnicodeCksum(PWCHAR s,
uint32 n);
//#define UDFUnicodeCksum(s,n) UDFCrc((uint8*)(s), (n)*sizeof(WCHAR))
//
uint16
__fastcall
UDFUnicodeCksum150(PWCHAR s,
uint32 n);
uint32
__fastcall crc32(IN uint8* s,
IN uint32 len);
// calculate a 16-bit CRC checksum using ITU-T V.41 polynomial
uint16
__fastcall UDFCrc(IN uint8* Data,
IN SIZE_T Size);
// read the first block of a tagged descriptor & check it
OSSTATUS UDFReadTagged(IN PVCB Vcb,
IN int8* Buf,
IN uint32 Block,
IN uint32 Location,
OUT uint16 *Ident);
// get physycal Lba for partition-relative addr
uint32
__fastcall UDFPartLbaToPhys(IN PVCB Vcb,
IN lb_addr* Addr);
// look for Anchor(s) at all possible locations
lba_t UDFFindAnchor(PVCB Vcb); // Volume control block
// look for Volume recognition sequence
uint32 UDFFindVRS(PVCB Vcb);
// process Primary volume descriptor
void UDFLoadPVolDesc(PVCB Vcb,
int8* Buf); // pointer to buffer containing PVD
//
#define UDFGetLVIDiUse(Vcb) \
( ((Vcb) && (Vcb)->LVid) ? \
( (LogicalVolIntegrityDescImpUse*) \
( ((int8*)(Vcb->LVid+1)) + \
Vcb->LVid->numOfPartitions*2*sizeof(uint32))) \
: NULL)
// load Logical volume integrity descriptor
OSSTATUS UDFLoadLogicalVolInt(PDEVICE_OBJECT DeviceObject,
PVCB Vcb,
extent_ad loc);
// load Logical volume descriptor
OSSTATUS UDFLoadLogicalVol(PDEVICE_OBJECT DeviceObject,
PVCB Vcb,
int8* Buf,
lb_addr *fileset);
// process Partition descriptor
OSSTATUS UDFLoadPartDesc(PVCB Vcb,
int8* Buf);
// scan VDS & fill special array
OSSTATUS UDFReadVDS(IN PVCB Vcb,
IN uint32 block,
IN uint32 lastblock,
IN PUDF_VDS_RECORD vds,
IN int8* Buf);
// process a main/reserve volume descriptor sequence.
OSSTATUS UDFProcessSequence(IN PDEVICE_OBJECT DeviceObject,
IN PVCB Vcb,
IN uint32 block,
IN uint32 lastblock,
OUT lb_addr *fileset);
// Verifies a main/reserve volume descriptor sequence.
OSSTATUS UDFVerifySequence(IN PDEVICE_OBJECT DeviceObject,
IN PVCB Vcb,
IN uint32 block,
IN uint32 lastblock,
OUT lb_addr *fileset);
// remember some useful info about FileSet & RootDir location
void UDFLoadFileset(IN PVCB Vcb,
IN PFILE_SET_DESC fset,
OUT lb_addr *root,
OUT lb_addr *sysstream);
// load partition info
OSSTATUS UDFLoadPartition(IN PDEVICE_OBJECT DeviceObject,
IN PVCB Vcb,
OUT lb_addr *fileset);
// check if this is an UDF-formatted disk
OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, // the target device object
IN PVCB Vcb); // Volume control block from this DevObj
// create hard link for the file
OSSTATUS UDFHardLinkFile__(IN PVCB Vcb,
IN BOOLEAN IgnoreCase,
IN OUT BOOLEAN* Replace, // replace if destination file exists
IN PUNICODE_STRING fn, // destination
IN OUT PUDF_FILE_INFO DirInfo1,
IN OUT PUDF_FILE_INFO DirInfo2,
IN OUT PUDF_FILE_INFO FileInfo); // source (opened)
//
LONG UDFFindDloc(IN PVCB Vcb,
IN uint32 Lba);
//
LONG UDFFindFreeDloc(IN PVCB Vcb,
IN uint32 Lba);
//
OSSTATUS UDFAcquireDloc(IN PVCB Vcb,
IN PUDF_DATALOC_INFO Dloc);
//
OSSTATUS UDFReleaseDloc(IN PVCB Vcb,
IN PUDF_DATALOC_INFO Dloc);
//
OSSTATUS UDFStoreDloc(IN PVCB Vcb,
IN PUDF_FILE_INFO fi,
IN uint32 Lba);
//
OSSTATUS UDFRemoveDloc(IN PVCB Vcb,
IN PUDF_DATALOC_INFO Dloc);
//
OSSTATUS UDFUnlinkDloc(IN PVCB Vcb,
IN PUDF_DATALOC_INFO Dloc);
//
void UDFFreeDloc(IN PVCB Vcb,
IN PUDF_DATALOC_INFO Dloc);
//
void UDFRelocateDloc(IN PVCB Vcb,
IN PUDF_DATALOC_INFO Dloc,
IN uint32 NewLba);
//
void UDFReleaseDlocList(IN PVCB Vcb);
//
PUDF_FILE_INFO UDFLocateParallelFI(PUDF_FILE_INFO di, // parent FileInfo
uint_di i, // Index
PUDF_FILE_INFO fi);
//
PUDF_FILE_INFO UDFLocateAnyParallelFI(PUDF_FILE_INFO fi); // FileInfo to start search from
//
void UDFInsertLinkedFile(PUDF_FILE_INFO fi, // FileInfo to be added to chain
PUDF_FILE_INFO fi2); // any FileInfo fro the chain
//
OSSTATUS UDFCreateRootFile__(IN PVCB Vcb,
// IN uint16 AllocMode, // short/long/ext/in-icb // always in-ICB
IN uint32 PartNum,
IN uint32 ExtAttrSz,
IN uint32 ImpUseLen,
IN BOOLEAN Extended,
OUT PUDF_FILE_INFO* _FileInfo);
// try to create StreamDirectory associated with given file
OSSTATUS UDFCreateStreamDir__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo, // file containing stream-dir
OUT PUDF_FILE_INFO* _SDirInfo);
//
OSSTATUS UDFOpenStreamDir__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo, // file containing stream-dir
OUT PUDF_FILE_INFO* _SDirInfo);
//
#define UDFIsAStreamDir(FI) ((FI) && ((FI)->Dloc) && ((FI)->Dloc->FE_Flags & UDF_FE_FLAG_IS_SDIR))
//
#define UDFHasAStreamDir(FI) ((FI) && ((FI)->Dloc) && ((FI)->Dloc->FE_Flags & UDF_FE_FLAG_HAS_SDIR))
//
#define UDFIsAStream(FI) ((FI) && UDFIsAStreamDir((FI)->ParentFile))
//
#define UDFIsSDirDeleted(FI) ((FI) && (FI)->Dloc && ((FI)->Dloc->FE_Flags & UDF_FE_FLAG_IS_DEL_SDIR))
// Record updated VAT (if updated)
OSSTATUS UDFRecordVAT(IN PVCB Vcb);
//
OSSTATUS UDFModifyVAT(IN PVCB Vcb,
IN uint32 Lba,
IN uint32 Length);
//
OSSTATUS UDFUpdateVAT(IN void* _Vcb,
IN uint32 Lba,
IN uint32* RelocTab,
IN uint32 BCount);
//
OSSTATUS
__fastcall UDFUnPackMapping(IN PVCB Vcb,
IN PEXTENT_INFO ExtInfo); // Extent array
//
OSSTATUS UDFConvertFEToNonInICB(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo,
IN uint8 NewAllocMode);
//
OSSTATUS UDFConvertFEToExtended(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo);
//
#define UDFGetPartNumByPartNdx(Vcb, pi) (Vcb->Partitions[pi].PartitionNum)
//
uint32
__fastcall UDFPartLen(PVCB Vcb,
uint32 PartNum);
//
OSSTATUS UDFPretendFileDeleted__(IN PVCB Vcb,
IN PUDF_FILE_INFO FileInfo);
#define UDFStreamsSupported(Vcb) \
(Vcb->maxUDFWriteRev >= 0x0200)
#define UDFNtAclSupported(Vcb) \
(Vcb->maxUDFWriteRev >= 0x0200)
#define UDFReferenceFile__(fi) \
{ \
UDFInterlockedIncrement((PLONG)&((fi)->RefCount)); \
UDFInterlockedIncrement((PLONG)&((fi)->Dloc->LinkRefCount)); \
if((fi)->ParentFile) { \
UDFInterlockedIncrement((PLONG)&((fi)->ParentFile->OpenCount)); \
} \
}
#define UDFReferenceFileEx__(fi,i) \
{ \
UDFInterlockedExchangeAdd((PLONG)&((fi)->RefCount),i); \
UDFInterlockedExchangeAdd((PLONG)&((fi)->Dloc->LinkRefCount),i); \
if((fi)->ParentFile) { \
UDFInterlockedExchangeAdd((PLONG)&((fi)->ParentFile->OpenCount),i); \
} \
}
#define UDFDereferenceFile__(fi) \
{ \
UDFInterlockedDecrement((PLONG)&((fi)->RefCount)); \
UDFInterlockedDecrement((PLONG)&((fi)->Dloc->LinkRefCount)); \
if((fi)->ParentFile) { \
UDFInterlockedDecrement((PLONG)&((fi)->ParentFile->OpenCount)); \
} \
}
#define UDFIsDirEmpty__(fi) UDFIsDirEmpty((fi)->Dloc->DirIndex)
#define UDFIsDirOpened__(fi) (fi->OpenCount)
#define UDFSetFileAllocMode__(fi, mode) \
{ \
(fi)->Dloc->DataLoc.Flags = \
((fi)->Dloc->DataLoc.Flags & ~EXTENT_FLAG_ALLOC_MASK) | (mode & EXTENT_FLAG_ALLOC_MASK); \
}
#define UDFGetFileAllocMode__(fi) ((fi)->Dloc->DataLoc.Flags & EXTENT_FLAG_ALLOC_MASK)
#define UDFGetFileICBAllocMode__(fi) (((PFILE_ENTRY)((fi)->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK)
#ifndef UDF_LIMIT_DIR_SIZE // release
#define UDF_DIR_INDEX_FRAME_SH 9
#else // demo
#define UDF_DIR_INDEX_FRAME_SH 7
#endif
#define UDF_DIR_INDEX_FRAME ((uint_di)(1 << UDF_DIR_INDEX_FRAME_SH))
#define UDF_DIR_INDEX_FRAME_GRAN (32)
#define UDF_DIR_INDEX_FRAME_GRAN_MASK (UDF_DIR_INDEX_FRAME_GRAN-1)
#define AlignDirIndex(n) ((n+UDF_DIR_INDEX_FRAME_GRAN_MASK) & ~(UDF_DIR_INDEX_FRAME_GRAN_MASK))
#if defined _X86_ && !defined UDF_LIMIT_DIR_SIZE
PDIR_INDEX_ITEM
__fastcall
UDFDirIndex(
IN PDIR_INDEX_HDR hDirNdx,
IN uint32 i
);
#else // NO X86 optimization , use generic C/C++
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx,
IN uint_di i)
{
#ifdef UDF_LIMIT_DIR_SIZE
if( hDirNdx && (i < hDirNdx->LastFrameCount))
return &( (((PDIR_INDEX_ITEM*)(hDirNdx+1))[0])[i] );
#else //UDF_LIMIT_DIR_SIZE
uint_di j, k;
if( hDirNdx &&
((j = (i >> UDF_DIR_INDEX_FRAME_SH)) < (k = hDirNdx->FrameCount) ) &&
((i = (i & (UDF_DIR_INDEX_FRAME-1))) < ((j < (k-1)) ? UDF_DIR_INDEX_FRAME : hDirNdx->LastFrameCount)) )
return &( (((PDIR_INDEX_ITEM*)(hDirNdx+1))[j])[i] );
#endif // UDF_LIMIT_DIR_SIZE
return NULL;
}
#endif // _X86_
#define UDFDirIndexGetLastIndex(di) ((((di)->FrameCount - 1) << UDF_DIR_INDEX_FRAME_SH) + (di)->LastFrameCount)
// arr - bit array, bit - number of bit
#ifdef _X86_
#ifdef _CONSOLE
#define CheckAddr(addr) {ASSERT((uint32)(addr) > 0x1000);}
#else
#define CheckAddr(addr) {ASSERT((uint32)(addr) & 0x80000000);}
#endif
#define UDFGetBit(arr, bit) UDFGetBit__((uint32*)(arr), bit)
BOOLEAN
__fastcall
UDFGetBit__(
IN uint32* arr,
IN uint32 bit
);
#define UDFSetBit(arr, bit) UDFSetBit__((uint32*)(arr), bit)
void
__fastcall
UDFSetBit__(
IN uint32* arr,
IN uint32 bit
);
#define UDFSetBits(arr, bit, bc) UDFSetBits__((uint32*)(arr), bit, bc)
void
UDFSetBits__(
IN uint32* arr,
IN uint32 bit,
IN uint32 bc
);
#define UDFClrBit(arr, bit) UDFClrBit__((uint32*)(arr), bit)
void
__fastcall
UDFClrBit__(
IN uint32* arr,
IN uint32 bit
);
#define UDFClrBits(arr, bit, bc) UDFClrBits__((uint32*)(arr), bit, bc)
void
UDFClrBits__(
IN uint32* arr,
IN uint32 bit,
IN uint32 bc
);
#else // NO X86 optimization , use generic C/C++
#define UDFGetBit(arr, bit) ( (BOOLEAN) ( ((((uint32*)(arr))[(bit)>>5]) >> ((bit)&31)) &1 ) )
#define UDFSetBit(arr, bit) ( (((uint32*)(arr))[(bit)>>5]) |= (((uint32)1) << ((bit)&31)) )
#define UDFClrBit(arr, bit) ( (((uint32*)(arr))[(bit)>>5]) &= (~(((uint32)1) << ((bit)&31))) )
#define UDFSetBits(arr, bit, bc) \
{uint32 j; \
for(j=0;j<bc;j++) { \
UDFSetBit(arr, (bit)+j); \
}}
#define UDFClrBits(arr, bit, bc) \
{uint32 j; \
for(j=0;j<bc;j++) { \
UDFClrBit(arr, (bit)+j); \
}}
#endif // _X86_
#define UDFGetUsedBit(arr,bit) (!UDFGetBit(arr,bit))
#define UDFGetFreeBit(arr,bit) UDFGetBit(arr,bit)
#define UDFSetUsedBit(arr,bit) UDFClrBit(arr,bit)
#define UDFSetFreeBit(arr,bit) UDFSetBit(arr,bit)
#define UDFSetUsedBits(arr,bit,bc) UDFClrBits(arr,bit,bc)
#define UDFSetFreeBits(arr,bit,bc) UDFSetBits(arr,bit,bc)
#define UDFGetBadBit(arr,bit) UDFGetBit(arr,bit)
#define UDFGetZeroBit(arr,bit) UDFGetBit(arr,bit)
#define UDFSetZeroBit(arr,bit) UDFSetBit(arr,bit)
#define UDFClrZeroBit(arr,bit) UDFClrBit(arr,bit)
#define UDFSetZeroBits(arr,bit,bc) UDFSetBits(arr,bit,bc)
#define UDFClrZeroBits(arr,bit,bc) UDFClrBits(arr,bit,bc)
#if defined UDF_DBG || defined _CONSOLE
#ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS
#define UDFSetFreeBitOwner(Vcb, i) (Vcb)->FSBM_Bitmap_owners[i] = 0;
#define UDFSetUsedBitOwner(Vcb, i, o) (Vcb)->FSBM_Bitmap_owners[i] = o;
#define UDFGetUsedBitOwner(Vcb, i) ((Vcb)->FSBM_Bitmap_owners[i])
#define UDFCheckUsedBitOwner(Vcb, i, o) { \
ASSERT(i<(Vcb)->FSBM_BitCount); \
if((Vcb)->FSBM_Bitmap_owners[i] != -1) { \
ASSERT((Vcb)->FSBM_Bitmap_owners[i] == o); \
} else { \
ASSERT((Vcb)->FSBM_Bitmap_owners[i] != 0); \
(Vcb)->FSBM_Bitmap_owners[i] = o; \
} \
}
#define UDFCheckFreeBitOwner(Vcb, i) ASSERT((Vcb)->FSBM_Bitmap_owners[i] == 0);
#else
#define UDFSetFreeBitOwner(Vcb, i)
#define UDFSetUsedBitOwner(Vcb, i, o)
#define UDFCheckUsedBitOwner(Vcb, i, o)
#define UDFCheckFreeBitOwner(Vcb, i)
#endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS
#else
#define UDFSetFreeBitOwner(Vcb, i)
#define UDFSetUsedBitOwner(Vcb, i, o)
#define UDFCheckUsedBitOwner(Vcb, i, o)
#define UDFCheckFreeBitOwner(Vcb, i)
#endif //UDF_DBG
#ifdef UDF_TRACK_FS_STRUCTURES
extern
VOID
UDFRegisterFsStructure(
PVCB Vcb,
uint32 Lba,
uint32 Length // sectors
);
#else //UDF_TRACK_FS_STRUCTURES
#define UDFRegisterFsStructure(Vcb, Lba, Length) {NOTHING;}
#endif //UDF_TRACK_FS_STRUCTURES
extern const char hexChar[];
#define UDF_MAX_VERIFY_CACHE (8*1024*1024/2048)
#define UDF_VERIFY_CACHE_LOW (4*1024*1024/2048)
#define UDF_VERIFY_CACHE_GRAN (512*1024/2048)
#define UDF_SYS_CACHE_STOP_THR (10*1024*1024/2048)
OSSTATUS
UDFVInit(
IN PVCB Vcb
);
VOID
UDFVRelease(
IN PVCB Vcb
);
#define PH_FORGET_VERIFIED 0x00800000
#define PH_READ_VERIFY_CACHE 0x00400000
#define PH_KEEP_VERIFY_CACHE 0x00200000
OSSTATUS
UDFVWrite(
IN PVCB Vcb,
IN void* Buffer, // Target buffer
IN uint32 BCount,
IN uint32 LBA,
// OUT PSIZE_T WrittenBytes,
IN uint32 Flags
);
OSSTATUS
UDFVRead(
IN PVCB Vcb,
IN void* Buffer, // Target buffer
IN uint32 BCount,
IN uint32 LBA,
// OUT uint32* ReadBytes,
IN uint32 Flags
);
OSSTATUS
UDFVForget(
IN PVCB Vcb,
IN uint32 BCount,
IN uint32 LBA,
IN uint32 Flags
);
#define UFD_VERIFY_FLAG_FORCE 0x01
#define UFD_VERIFY_FLAG_WAIT 0x02
#define UFD_VERIFY_FLAG_BG 0x04
#define UFD_VERIFY_FLAG_LOCKED 0x10
VOID
UDFVVerify(
IN PVCB Vcb,
IN ULONG Flags
);
VOID
UDFVFlush(
IN PVCB Vcb
);
__inline
BOOLEAN
__fastcall UDFVIsStored(
IN PVCB Vcb,
IN lba_t lba
)
{
if(!Vcb->VerifyCtx.VInited)
return FALSE;
return UDFGetBit(Vcb->VerifyCtx.StoredBitMap, lba);
} // end UDFVIsStored()
BOOLEAN
__fastcall
UDFCheckArea(
IN PVCB Vcb,
IN lba_t LBA,
IN uint32 BCount
);
#endif // __UDF_STRUCT_SUPPORT_H__