mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/UDF: Fix creation of UDF logical partition
Do not reserve entire block device size for an UDF file system - instead, reserve the appropriate space (UDF logical volume space) for it. Additionally, only create a logical partition for UDF logical volumes that are currently supported by EDK2 UDF file system implementation. For instance, an UDF volume with a single LVD and a single Physical (Type 1) Partition will be supported. Cc: Eric Dong <eric.dong@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Reported-by: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Paulo Alcantara <pcacjr@zytor.com> Tested-by: Hao Wu <hao.a.wu@intel.com> Build-tested-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Star Zeng <star.zeng@intel.com> Build-tested-by: Star Zeng <star.zeng@intel.com> Build-tested-by: Paulo Alcantara <paulo@hp.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
This commit is contained in:
parent
264d16fcbf
commit
baaa3cee1e
|
@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
|
|||
OUT UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 BlockSize;
|
||||
EFI_LBA EndLBA;
|
||||
EFI_LBA DescriptorLBAs[4];
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
UINT32 BlockSize;
|
||||
EFI_LBA EndLBA;
|
||||
EFI_LBA DescriptorLBAs[4];
|
||||
UINTN Index;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
|
||||
BlockSize = BlockIo->Media->BlockSize;
|
||||
EndLBA = BlockIo->Media->LastBlock;
|
||||
|
@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
|
|||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DescriptorTag = &AnchorPoint->DescriptorTag;
|
||||
|
||||
//
|
||||
// Check if read LBA has a valid AVDP descriptor.
|
||||
//
|
||||
if (IS_AVDP (AnchorPoint)) {
|
||||
if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
|
|||
}
|
||||
|
||||
/**
|
||||
Check if block device supports a valid UDF file system as specified by OSTA
|
||||
Universal Disk Format Specification 2.60.
|
||||
Find UDF volume identifiers in a Volume Recognition Sequence.
|
||||
|
||||
@param[in] BlockIo BlockIo interface.
|
||||
@param[in] DiskIo DiskIo interface.
|
||||
@param[in] BlockIo BlockIo interface.
|
||||
@param[in] DiskIo DiskIo interface.
|
||||
|
||||
@retval EFI_SUCCESS UDF file system found.
|
||||
@retval EFI_UNSUPPORTED UDF file system not found.
|
||||
@retval EFI_NO_MEDIA The device has no media.
|
||||
@retval EFI_DEVICE_ERROR The device reported an error.
|
||||
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
|
||||
@retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
|
||||
resources.
|
||||
@retval EFI_SUCCESS UDF volume identifiers were found.
|
||||
@retval EFI_NOT_FOUND UDF volume identifiers were not found.
|
||||
@retval other Failed to perform disk I/O.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SupportUdfFileSystem (
|
||||
FindUdfVolumeIdentifiers (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||
IN EFI_DISK_IO_PROTOCOL *DiskIo
|
||||
)
|
||||
|
@ -128,7 +127,6 @@ SupportUdfFileSystem (
|
|||
UINT64 EndDiskOffset;
|
||||
CDROM_VOLUME_DESCRIPTOR VolDescriptor;
|
||||
CDROM_VOLUME_DESCRIPTOR TerminatingVolDescriptor;
|
||||
UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER AnchorPoint;
|
||||
|
||||
ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIPTOR));
|
||||
|
||||
|
@ -167,7 +165,7 @@ SupportUdfFileSystem (
|
|||
(CompareMem ((VOID *)&VolDescriptor,
|
||||
(VOID *)&TerminatingVolDescriptor,
|
||||
sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +174,7 @@ SupportUdfFileSystem (
|
|||
//
|
||||
Offset += UDF_LOGICAL_SECTOR_SIZE;
|
||||
if (Offset >= EndDiskOffset) {
|
||||
return EFI_UNSUPPORTED;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Status = DiskIo->ReadDisk (
|
||||
|
@ -196,7 +194,7 @@ SupportUdfFileSystem (
|
|||
(CompareMem ((VOID *)VolDescriptor.Unknown.Id,
|
||||
(VOID *)UDF_NSR3_IDENTIFIER,
|
||||
sizeof (VolDescriptor.Unknown.Id)) != 0)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -204,7 +202,7 @@ SupportUdfFileSystem (
|
|||
//
|
||||
Offset += UDF_LOGICAL_SECTOR_SIZE;
|
||||
if (Offset >= EndDiskOffset) {
|
||||
return EFI_UNSUPPORTED;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Status = DiskIo->ReadDisk (
|
||||
|
@ -221,17 +219,293 @@ SupportUdfFileSystem (
|
|||
if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
|
||||
(VOID *)UDF_TEA_IDENTIFIER,
|
||||
sizeof (VolDescriptor.Unknown.Id)) != 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPoint);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Check if Logical Volume Descriptor is supported by current EDK2 UDF file
|
||||
system implementation.
|
||||
|
||||
@param[in] LogicalVolDesc Logical Volume Descriptor pointer.
|
||||
|
||||
@retval TRUE Logical Volume Descriptor is supported.
|
||||
@retval FALSE Logical Volume Descriptor is not supported.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsLogicalVolumeDescriptorSupported (
|
||||
UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc
|
||||
)
|
||||
{
|
||||
//
|
||||
// Check for a valid UDF revision range
|
||||
//
|
||||
switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {
|
||||
case 0x0102:
|
||||
case 0x0150:
|
||||
case 0x0200:
|
||||
case 0x0201:
|
||||
case 0x0250:
|
||||
case 0x0260:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for a single Partition Map
|
||||
//
|
||||
if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
|
||||
return FALSE;
|
||||
}
|
||||
//
|
||||
// UDF 1.02 revision supports only Type 1 (Physical) partitions, but
|
||||
// let's check it any way.
|
||||
//
|
||||
// PartitionMap[0] -> type
|
||||
// PartitionMap[1] -> length (in bytes)
|
||||
//
|
||||
if (LogicalVolDesc->PartitionMaps[0] != 1 ||
|
||||
LogicalVolDesc->PartitionMaps[1] != 6) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Find UDF logical volume location and whether it is supported by current EDK2
|
||||
UDF file system implementation.
|
||||
|
||||
@param[in] BlockIo BlockIo interface.
|
||||
@param[in] DiskIo DiskIo interface.
|
||||
@param[in] AnchorPoint Anchor volume descriptor pointer.
|
||||
@param[out] MainVdsStartBlock Main VDS starting block number.
|
||||
@param[out] MainVdsEndBlock Main VDS ending block number.
|
||||
|
||||
@retval EFI_SUCCESS UDF logical volume was found.
|
||||
@retval EFI_VOLUME_CORRUPTED UDF file system structures are corrupted.
|
||||
@retval EFI_UNSUPPORTED UDF logical volume is not supported.
|
||||
@retval other Failed to perform disk I/O.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
FindLogicalVolumeLocation (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||
IN UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint,
|
||||
OUT UINT64 *MainVdsStartBlock,
|
||||
OUT UINT64 *MainVdsEndBlock
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 BlockSize;
|
||||
EFI_LBA LastBlock;
|
||||
UDF_EXTENT_AD *ExtentAd;
|
||||
UINT64 SeqBlocksNum;
|
||||
UINT64 SeqStartBlock;
|
||||
UINT64 GuardMainVdsStartBlock;
|
||||
VOID *Buffer;
|
||||
UINT64 SeqEndBlock;
|
||||
BOOLEAN StopSequence;
|
||||
UINTN LvdsCount;
|
||||
UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
|
||||
BlockSize = BlockIo->Media->BlockSize;
|
||||
LastBlock = BlockIo->Media->LastBlock;
|
||||
ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
|
||||
|
||||
//
|
||||
// UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
|
||||
//
|
||||
// The Main Volume Descriptor Sequence Extent shall have a minimum length of
|
||||
// 16 logical sectors.
|
||||
//
|
||||
// Also make sure it does not exceed maximum number of blocks in the disk.
|
||||
//
|
||||
SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
|
||||
if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for valid Volume Descriptor Sequence starting block number
|
||||
//
|
||||
SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
|
||||
if (SeqStartBlock > LastBlock ||
|
||||
SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
GuardMainVdsStartBlock = SeqStartBlock;
|
||||
|
||||
//
|
||||
// Allocate buffer for reading disk blocks
|
||||
//
|
||||
Buffer = AllocateZeroPool ((UINTN)BlockSize);
|
||||
if (Buffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
SeqEndBlock = SeqStartBlock + SeqBlocksNum;
|
||||
StopSequence = FALSE;
|
||||
LvdsCount = 0;
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
//
|
||||
// Start Main Volume Descriptor Sequence
|
||||
//
|
||||
for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
|
||||
//
|
||||
// Read disk block
|
||||
//
|
||||
Status = BlockIo->ReadBlocks (
|
||||
BlockIo,
|
||||
BlockIo->Media->MediaId,
|
||||
SeqStartBlock,
|
||||
BlockSize,
|
||||
Buffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Out_Free;
|
||||
}
|
||||
|
||||
DescriptorTag = Buffer;
|
||||
|
||||
//
|
||||
// ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
|
||||
//
|
||||
// - A Volume Descriptor Sequence shall contain one or more Primary Volume
|
||||
// Descriptors.
|
||||
// - A Volume Descriptor Sequence shall contain zero or more Implementation
|
||||
// Use Volume Descriptors.
|
||||
// - A Volume Descriptor Sequence shall contain zero or more Partition
|
||||
// Descriptors.
|
||||
// - A Volume Descriptor Sequence shall contain zero or more Logical Volume
|
||||
// Descriptors.
|
||||
// - A Volume Descriptor Sequence shall contain zero or more Unallocated
|
||||
// Space Descriptors.
|
||||
//
|
||||
switch (DescriptorTag->TagIdentifier) {
|
||||
case UdfPrimaryVolumeDescriptor:
|
||||
case UdfImplemenationUseVolumeDescriptor:
|
||||
case UdfPartitionDescriptor:
|
||||
case UdfUnallocatedSpaceDescriptor:
|
||||
break;
|
||||
|
||||
case UdfLogicalVolumeDescriptor:
|
||||
LogicalVolDesc = Buffer;
|
||||
|
||||
//
|
||||
// Check for existence of a single LVD and whether it is supported by
|
||||
// current EDK2 UDF file system implementation.
|
||||
//
|
||||
if (++LvdsCount > 1 ||
|
||||
!IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
StopSequence = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UdfTerminatingDescriptor:
|
||||
//
|
||||
// Stop the sequence when we find a Terminating Descriptor
|
||||
// (aka Unallocated Sector), se we don't have to walk all the unallocated
|
||||
// area unnecessarily.
|
||||
//
|
||||
StopSequence = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// An invalid Volume Descriptor has been found in the sequece. Volume is
|
||||
// corrupted.
|
||||
//
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
goto Out_Free;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check if LVD was found
|
||||
//
|
||||
if (!EFI_ERROR (Status) && LvdsCount == 1) {
|
||||
*MainVdsStartBlock = GuardMainVdsStartBlock;
|
||||
//
|
||||
// We do not need to read either LVD or PD descriptors to know the last
|
||||
// valid block in the found UDF file system. It's already LastBlock.
|
||||
//
|
||||
*MainVdsEndBlock = LastBlock;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Out_Free:
|
||||
//
|
||||
// Free block read buffer
|
||||
//
|
||||
FreePool (Buffer);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Find a supported UDF file system in block device.
|
||||
|
||||
@param[in] BlockIo BlockIo interface.
|
||||
@param[in] DiskIo DiskIo interface.
|
||||
@param[out] StartingLBA UDF file system starting LBA.
|
||||
@param[out] EndingLBA UDF file system starting LBA.
|
||||
|
||||
@retval EFI_SUCCESS UDF file system was found.
|
||||
@retval other UDF file system was not found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
FindUdfFileSystem (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||
OUT EFI_LBA *StartingLBA,
|
||||
OUT EFI_LBA *EndingLBA
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER AnchorPoint;
|
||||
|
||||
//
|
||||
// Find UDF volume identifiers
|
||||
//
|
||||
Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Anchor Volume Descriptor Pointer
|
||||
//
|
||||
Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPoint);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Logical Volume location
|
||||
//
|
||||
Status = FindLogicalVolumeLocation (
|
||||
BlockIo,
|
||||
DiskIo,
|
||||
&AnchorPoint,
|
||||
(UINT64 *)StartingLBA,
|
||||
(UINT64 *)EndingLBA
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Install child handles if the Handle supports UDF/ECMA-167 volume format.
|
||||
|
||||
|
@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
|
|||
UINT32 RemainderByMediaBlockSize;
|
||||
EFI_STATUS Status;
|
||||
EFI_BLOCK_IO_MEDIA *Media;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
|
||||
EFI_GUID *VendorDefinedGuid;
|
||||
EFI_PARTITION_INFO_PROTOCOL PartitionInfo;
|
||||
EFI_LBA StartingLBA;
|
||||
EFI_LBA EndingLBA;
|
||||
|
||||
Media = BlockIo->Media;
|
||||
|
||||
|
@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
|
|||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
DevicePathNode = DevicePath;
|
||||
while (!IsDevicePathEnd (DevicePathNode)) {
|
||||
//
|
||||
// Do not allow checking for UDF file systems in CDROM "El Torito"
|
||||
// partitions, and skip duplicate installation of UDF file system child
|
||||
// nodes.
|
||||
//
|
||||
if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
|
||||
if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
|
||||
VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
|
||||
OFFSET_OF (VENDOR_DEVICE_PATH, Guid));
|
||||
if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Try next device path node
|
||||
//
|
||||
DevicePathNode = NextDevicePathNode (DevicePathNode);
|
||||
}
|
||||
|
||||
//
|
||||
// Check if block device supports an UDF file system
|
||||
// Search for an UDF file system on block device
|
||||
//
|
||||
Status = SupportUdfFileSystem (BlockIo, DiskIo);
|
||||
Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
@ -334,13 +583,10 @@ PartitionInstallUdfChildHandles (
|
|||
DevicePath,
|
||||
(EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
|
||||
&PartitionInfo,
|
||||
0,
|
||||
Media->LastBlock,
|
||||
StartingLBA,
|
||||
EndingLBA,
|
||||
Media->BlockSize
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
|
|||
CleanupFileInformation (&PrivFsData->Root);
|
||||
|
||||
Error_Find_Root_Dir:
|
||||
CleanupVolumeInformation (&PrivFsData->Volume);
|
||||
|
||||
Error_Read_Udf_Volume:
|
||||
Error_Invalid_Params:
|
||||
|
@ -429,7 +428,7 @@ UdfRead (
|
|||
}
|
||||
ASSERT (NewFileEntryData != NULL);
|
||||
|
||||
if (IS_FE_SYMLINK (NewFileEntryData)) {
|
||||
if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink) {
|
||||
Status = ResolveSymlink (
|
||||
BlockIo,
|
||||
DiskIo,
|
||||
|
@ -529,7 +528,6 @@ UdfClose (
|
|||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
||||
PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
|
@ -542,8 +540,6 @@ UdfClose (
|
|||
|
||||
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
|
||||
|
||||
PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);
|
||||
|
||||
if (!PrivFileData->IsRootDirectory) {
|
||||
CleanupFileInformation (&PrivFileData->File);
|
||||
|
||||
|
@ -552,10 +548,6 @@ UdfClose (
|
|||
}
|
||||
}
|
||||
|
||||
if (--PrivFsData->OpenFiles == 0) {
|
||||
CleanupVolumeInformation (&PrivFsData->Volume);
|
||||
}
|
||||
|
||||
FreePool ((VOID *)PrivFileData);
|
||||
|
||||
Exit:
|
||||
|
@ -652,7 +644,7 @@ UdfGetPosition (
|
|||
// As per UEFI spec, if the file handle is a directory, then the current file
|
||||
// position has no meaning and the operation is not supported.
|
||||
//
|
||||
if (IS_FID_DIRECTORY_FILE (&PrivFileData->File.FileIdentifierDesc)) {
|
||||
if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -788,7 +780,7 @@ UdfGetInfo (
|
|||
} else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
|
||||
String = VolumeLabel;
|
||||
|
||||
FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
|
||||
FileSetDesc = &PrivFsData->Volume.FileSetDesc;
|
||||
|
||||
OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
|
||||
|
||||
|
@ -847,7 +839,7 @@ UdfGetInfo (
|
|||
FileSystemInfo->Size = FileSystemInfoLength;
|
||||
FileSystemInfo->ReadOnly = TRUE;
|
||||
FileSystemInfo->BlockSize =
|
||||
LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);
|
||||
PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
|
||||
FileSystemInfo->VolumeSize = VolumeSize;
|
||||
FileSystemInfo->FreeSpace = FreeSpaceSize;
|
||||
|
||||
|
|
|
@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
|
|||
OUT UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 BlockSize;
|
||||
EFI_LBA EndLBA;
|
||||
EFI_LBA DescriptorLBAs[4];
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
UINT32 BlockSize;
|
||||
EFI_LBA EndLBA;
|
||||
EFI_LBA DescriptorLBAs[4];
|
||||
UINTN Index;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
|
||||
BlockSize = BlockIo->Media->BlockSize;
|
||||
EndLBA = BlockIo->Media->LastBlock;
|
||||
|
@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer (
|
|||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DescriptorTag = &AnchorPoint->DescriptorTag;
|
||||
|
||||
//
|
||||
// Check if read LBA has a valid AVDP descriptor.
|
||||
//
|
||||
if (IS_AVDP (AnchorPoint)) {
|
||||
if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
|
|||
OUT UDF_VOLUME_INFO *Volume
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 BlockSize;
|
||||
UDF_EXTENT_AD *ExtentAd;
|
||||
UINT64 StartingLsn;
|
||||
UINT64 EndingLsn;
|
||||
VOID *Buffer;
|
||||
UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc;
|
||||
UDF_PARTITION_DESCRIPTOR *PartitionDesc;
|
||||
UINTN Index;
|
||||
UINT32 LogicalBlockSize;
|
||||
EFI_STATUS Status;
|
||||
UINT32 BlockSize;
|
||||
UDF_EXTENT_AD *ExtentAd;
|
||||
EFI_LBA SeqStartBlock;
|
||||
EFI_LBA SeqEndBlock;
|
||||
BOOLEAN StopSequence;
|
||||
VOID *Buffer;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
UINT32 LogicalBlockSize;
|
||||
|
||||
BlockSize = BlockIo->Media->BlockSize;
|
||||
ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
|
||||
|
||||
//
|
||||
// We've already found an ADVP on the volume. It contains the extent
|
||||
// (MainVolumeDescriptorSequenceExtent) where the Main Volume Descriptor
|
||||
// Sequence starts. Therefore, we'll look for Logical Volume Descriptors and
|
||||
// Partitions Descriptors and save them in memory, accordingly.
|
||||
// Allocate buffer for reading disk blocks
|
||||
//
|
||||
// Note also that each descriptor will be aligned on a block size (BlockSize)
|
||||
// boundary, so we need to read one block at a time.
|
||||
//
|
||||
BlockSize = BlockIo->Media->BlockSize;
|
||||
ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
|
||||
StartingLsn = (UINT64)ExtentAd->ExtentLocation;
|
||||
EndingLsn = StartingLsn + DivU64x32 (
|
||||
(UINT64)ExtentAd->ExtentLength,
|
||||
BlockSize
|
||||
);
|
||||
|
||||
Volume->LogicalVolDescs =
|
||||
(UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd->ExtentLength);
|
||||
if (Volume->LogicalVolDescs == NULL) {
|
||||
Buffer = AllocateZeroPool ((UINTN)BlockSize);
|
||||
if (Buffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Volume->PartitionDescs =
|
||||
(UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd->ExtentLength);
|
||||
if (Volume->PartitionDescs == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error_Alloc_Pds;
|
||||
}
|
||||
|
||||
Buffer = AllocateZeroPool (BlockSize);
|
||||
if (Buffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error_Alloc_Buf;
|
||||
}
|
||||
|
||||
Volume->LogicalVolDescsNo = 0;
|
||||
Volume->PartitionDescsNo = 0;
|
||||
|
||||
while (StartingLsn <= EndingLsn) {
|
||||
Status = DiskIo->ReadDisk (
|
||||
DiskIo,
|
||||
//
|
||||
// The logical partition created by Partition driver is relative to the main
|
||||
// VDS extent location, so we start the Main Volume Descriptor Sequence at
|
||||
// LBA 0.
|
||||
//
|
||||
// We don't need to check again if we have valid Volume Descriptors here since
|
||||
// Partition driver already did.
|
||||
//
|
||||
SeqStartBlock = 0;
|
||||
SeqEndBlock = SeqStartBlock + DivU64x32 ((UINT64)ExtentAd->ExtentLength,
|
||||
BlockSize);
|
||||
StopSequence = FALSE;
|
||||
for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
|
||||
//
|
||||
// Read disk block
|
||||
//
|
||||
Status = BlockIo->ReadBlocks (
|
||||
BlockIo,
|
||||
BlockIo->Media->MediaId,
|
||||
MultU64x32 (StartingLsn, BlockSize),
|
||||
SeqStartBlock,
|
||||
BlockSize,
|
||||
Buffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error_Read_Disk_Blk;
|
||||
goto Out_Free;
|
||||
}
|
||||
|
||||
if (IS_TD (Buffer)) {
|
||||
DescriptorTag = Buffer;
|
||||
|
||||
switch (DescriptorTag->TagIdentifier) {
|
||||
case UdfPartitionDescriptor:
|
||||
//
|
||||
// Found a Terminating Descriptor. Stop the sequence then.
|
||||
// Save Partition Descriptor
|
||||
//
|
||||
CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume->PartitionDesc));
|
||||
break;
|
||||
|
||||
case UdfLogicalVolumeDescriptor:
|
||||
//
|
||||
// Save Logical Volume Descriptor
|
||||
//
|
||||
CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume->LogicalVolDesc));
|
||||
break;
|
||||
|
||||
case UdfTerminatingDescriptor:
|
||||
StopSequence = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if (IS_LVD (Buffer)) {
|
||||
//
|
||||
// Found a Logical Volume Descriptor.
|
||||
//
|
||||
LogicalVolDesc =
|
||||
(UDF_LOGICAL_VOLUME_DESCRIPTOR *)
|
||||
AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
|
||||
if (LogicalVolDesc == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error_Alloc_Lvd;
|
||||
}
|
||||
|
||||
CopyMem ((VOID *)LogicalVolDesc, Buffer,
|
||||
sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));
|
||||
Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] = LogicalVolDesc;
|
||||
} else if (IS_PD (Buffer)) {
|
||||
//
|
||||
// Found a Partition Descriptor.
|
||||
//
|
||||
PartitionDesc =
|
||||
(UDF_PARTITION_DESCRIPTOR *)
|
||||
AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));
|
||||
if (PartitionDesc == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error_Alloc_Pd;
|
||||
}
|
||||
|
||||
CopyMem ((VOID *)PartitionDesc, Buffer,
|
||||
sizeof (UDF_PARTITION_DESCRIPTOR));
|
||||
Volume->PartitionDescs[Volume->PartitionDescsNo++] = PartitionDesc;
|
||||
}
|
||||
|
||||
StartingLsn++;
|
||||
}
|
||||
|
||||
//
|
||||
// When an UDF volume (revision 2.00 or higher) contains a File Entry rather
|
||||
// than an Extended File Entry (which is not recommended as per spec), we need
|
||||
// to make sure the size of a FE will be _at least_ 2048
|
||||
// (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward compatibility.
|
||||
// Determine FE (File Entry) size
|
||||
//
|
||||
LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
|
||||
LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
|
||||
if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
|
||||
Volume->FileEntrySize = LogicalBlockSize;
|
||||
Volume->FileEntrySize = (UINTN)LogicalBlockSize;
|
||||
} else {
|
||||
Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
Out_Free:
|
||||
//
|
||||
// Free block read buffer
|
||||
//
|
||||
FreePool (Buffer);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
Error_Alloc_Pd:
|
||||
Error_Alloc_Lvd:
|
||||
for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
|
||||
FreePool ((VOID *)Volume->PartitionDescs[Index]);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
|
||||
FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
|
||||
}
|
||||
|
||||
Error_Read_Disk_Blk:
|
||||
FreePool (Buffer);
|
||||
|
||||
Error_Alloc_Buf:
|
||||
FreePool ((VOID *)Volume->PartitionDescs);
|
||||
Volume->PartitionDescs = NULL;
|
||||
|
||||
Error_Alloc_Pds:
|
||||
FreePool ((VOID *)Volume->LogicalVolDescs);
|
||||
Volume->LogicalVolDescs = NULL;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -262,48 +216,53 @@ GetPdFromLongAd (
|
|||
)
|
||||
{
|
||||
UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc;
|
||||
UINTN Index;
|
||||
UDF_PARTITION_DESCRIPTOR *PartitionDesc;
|
||||
UINT16 PartitionNum;
|
||||
|
||||
LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];
|
||||
LogicalVolDesc = &Volume->LogicalVolDesc;
|
||||
|
||||
switch (LV_UDF_REVISION (LogicalVolDesc)) {
|
||||
switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {
|
||||
case 0x0102:
|
||||
case 0x0150:
|
||||
case 0x0200:
|
||||
case 0x0201:
|
||||
case 0x0250:
|
||||
case 0x0260:
|
||||
//
|
||||
// As per UDF 1.02 specification:
|
||||
// UDF 1.02 specification:
|
||||
//
|
||||
// There shall be exactly one prevailing Logical Volume Descriptor recorded
|
||||
// per Volume Set. The Partition Maps field shall contain only Type 1
|
||||
// Partition Maps.
|
||||
//
|
||||
// UDF 1.50 through 2.60 specs say:
|
||||
//
|
||||
// For the purpose of interchange partition maps shall be limited to
|
||||
// Partition Map type 1, except type 2 maps as described in the document.
|
||||
//
|
||||
// NOTE: Only one Type 1 (Physical) Partition is supported. It has been
|
||||
// checked already in Partition driver for existence of a single Type 1
|
||||
// Partition map, so we don't have to double check here.
|
||||
//
|
||||
// Partition reference number can also be retrieved from
|
||||
// LongAd->ExtentLocation.PartitionReferenceNumber, however the spec says
|
||||
// it may be 0, so let's not rely on it.
|
||||
//
|
||||
PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
|
||||
break;
|
||||
case 0x0150:
|
||||
//
|
||||
// Ensure Type 1 Partition map. Other types aren't supported in this
|
||||
// implementation.
|
||||
//
|
||||
if (LogicalVolDesc->PartitionMaps[0] != 1 ||
|
||||
LogicalVolDesc->PartitionMaps[1] != 6) {
|
||||
return NULL;
|
||||
}
|
||||
PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
|
||||
break;
|
||||
case 0x0260:
|
||||
//
|
||||
// Fall through.
|
||||
//
|
||||
|
||||
default:
|
||||
PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
|
||||
break;
|
||||
//
|
||||
// Unsupported UDF revision
|
||||
//
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
|
||||
PartitionDesc = Volume->PartitionDescs[Index];
|
||||
if (PartitionDesc->PartitionNumber == PartitionNum) {
|
||||
return PartitionDesc;
|
||||
}
|
||||
//
|
||||
// Check if partition number matches Partition Descriptor found in Main Volume
|
||||
// Descriptor Sequence.
|
||||
//
|
||||
if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {
|
||||
return &Volume->PartitionDesc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -329,13 +288,15 @@ GetLongAdLsn (
|
|||
PartitionDesc = GetPdFromLongAd (Volume, LongAd);
|
||||
ASSERT (PartitionDesc != NULL);
|
||||
|
||||
return (UINT64)PartitionDesc->PartitionStartingLocation +
|
||||
LongAd->ExtentLocation.LogicalBlockNumber;
|
||||
return (UINT64)PartitionDesc->PartitionStartingLocation -
|
||||
Volume->MainVdsStartLocation +
|
||||
LongAd->ExtentLocation.LogicalBlockNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
Return logical sector number of a given Short Allocation Descriptor.
|
||||
|
||||
@param[in] Volume Volume pointer.
|
||||
@param[in] PartitionDesc Partition Descriptor pointer.
|
||||
@param[in] ShortAd Short Allocation Descriptor pointer.
|
||||
|
||||
|
@ -344,14 +305,13 @@ GetLongAdLsn (
|
|||
**/
|
||||
UINT64
|
||||
GetShortAdLsn (
|
||||
IN UDF_VOLUME_INFO *Volume,
|
||||
IN UDF_PARTITION_DESCRIPTOR *PartitionDesc,
|
||||
IN UDF_SHORT_ALLOCATION_DESCRIPTOR *ShortAd
|
||||
)
|
||||
{
|
||||
ASSERT (PartitionDesc != NULL);
|
||||
|
||||
return (UINT64)PartitionDesc->PartitionStartingLocation +
|
||||
ShortAd->ExtentPosition;
|
||||
return (UINT64)PartitionDesc->PartitionStartingLocation -
|
||||
Volume->MainVdsStartLocation + ShortAd->ExtentPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -363,8 +323,6 @@ GetShortAdLsn (
|
|||
@param[in] BlockIo BlockIo interface.
|
||||
@param[in] DiskIo DiskIo interface.
|
||||
@param[in] Volume Volume information pointer.
|
||||
@param[in] LogicalVolDescNum Index of Logical Volume Descriptor
|
||||
@param[out] FileSetDesc File Set Descriptor pointer.
|
||||
|
||||
@retval EFI_SUCCESS File Set Descriptor pointer found.
|
||||
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
|
||||
|
@ -375,118 +333,48 @@ EFI_STATUS
|
|||
FindFileSetDescriptor (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||
IN UDF_VOLUME_INFO *Volume,
|
||||
IN UINTN LogicalVolDescNum,
|
||||
OUT UDF_FILE_SET_DESCRIPTOR *FileSetDesc
|
||||
IN UDF_VOLUME_INFO *Volume
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 Lsn;
|
||||
UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
|
||||
LogicalVolDesc = Volume->LogicalVolDescs[LogicalVolDescNum];
|
||||
LogicalVolDesc = &Volume->LogicalVolDesc;
|
||||
Lsn = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse);
|
||||
|
||||
//
|
||||
// Read extent (Long Ad).
|
||||
// As per UDF 2.60 specification:
|
||||
//
|
||||
// There shall be exactly one File Set Descriptor recorded per Logical
|
||||
// Volume.
|
||||
//
|
||||
// Read disk block
|
||||
//
|
||||
Status = DiskIo->ReadDisk (
|
||||
DiskIo,
|
||||
BlockIo->Media->MediaId,
|
||||
MultU64x32 (Lsn, LogicalVolDesc->LogicalBlockSize),
|
||||
sizeof (UDF_FILE_SET_DESCRIPTOR),
|
||||
(VOID *)FileSetDesc
|
||||
sizeof (Volume->FileSetDesc),
|
||||
&Volume->FileSetDesc
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DescriptorTag = &Volume->FileSetDesc.DescriptorTag;
|
||||
|
||||
//
|
||||
// Check if the read extent contains a valid FSD's tag identifier.
|
||||
// Check if read block is a File Set Descriptor
|
||||
//
|
||||
if (!IS_FSD (FileSetDesc)) {
|
||||
if (DescriptorTag->TagIdentifier != UdfFileSetDescriptor) {
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Get all File Set Descriptors for each Logical Volume Descriptor.
|
||||
|
||||
@param[in] BlockIo BlockIo interface.
|
||||
@param[in] DiskIo DiskIo interface.
|
||||
@param[in, out] Volume Volume information pointer.
|
||||
|
||||
@retval EFI_SUCCESS File Set Descriptors were got.
|
||||
@retval EFI_OUT_OF_RESOURCES File Set Descriptors were not got due to lack
|
||||
of resources.
|
||||
@retval other Error occured when finding File Set
|
||||
Descriptor in Logical Volume Descriptor.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetFileSetDescriptors (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||
IN OUT UDF_VOLUME_INFO *Volume
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UDF_FILE_SET_DESCRIPTOR *FileSetDesc;
|
||||
UINTN Count;
|
||||
|
||||
Volume->FileSetDescs =
|
||||
(UDF_FILE_SET_DESCRIPTOR **)AllocateZeroPool (
|
||||
Volume->LogicalVolDescsNo * sizeof (UDF_FILE_SET_DESCRIPTOR));
|
||||
if (Volume->FileSetDescs == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
|
||||
FileSetDesc = AllocateZeroPool (sizeof (UDF_FILE_SET_DESCRIPTOR));
|
||||
if (FileSetDesc == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error_Alloc_Fsd;
|
||||
}
|
||||
|
||||
//
|
||||
// Find a FSD for this LVD.
|
||||
//
|
||||
Status = FindFileSetDescriptor (
|
||||
BlockIo,
|
||||
DiskIo,
|
||||
Volume,
|
||||
Index,
|
||||
FileSetDesc
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error_Find_Fsd;
|
||||
}
|
||||
|
||||
//
|
||||
// Got one. Save it.
|
||||
//
|
||||
Volume->FileSetDescs[Index] = FileSetDesc;
|
||||
}
|
||||
|
||||
Volume->FileSetDescsNo = Volume->LogicalVolDescsNo;
|
||||
return EFI_SUCCESS;
|
||||
|
||||
Error_Find_Fsd:
|
||||
Count = Index + 1;
|
||||
for (Index = 0; Index < Count; Index++) {
|
||||
FreePool ((VOID *)Volume->FileSetDescs[Index]);
|
||||
}
|
||||
|
||||
FreePool ((VOID *)Volume->FileSetDescs);
|
||||
Volume->FileSetDescs = NULL;
|
||||
|
||||
Error_Alloc_Fsd:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Read Volume and File Structure on an UDF file system.
|
||||
|
||||
|
@ -507,9 +395,10 @@ ReadVolumeFileStructure (
|
|||
{
|
||||
EFI_STATUS Status;
|
||||
UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER AnchorPoint;
|
||||
UDF_EXTENT_AD *ExtentAd;
|
||||
|
||||
//
|
||||
// Find an AVDP.
|
||||
// Find Anchor Volume Descriptor Pointer
|
||||
//
|
||||
Status = FindAnchorVolumeDescriptorPointer (
|
||||
BlockIo,
|
||||
|
@ -521,7 +410,14 @@ ReadVolumeFileStructure (
|
|||
}
|
||||
|
||||
//
|
||||
// AVDP has been found. Start MVDS.
|
||||
// Save Main VDS start block number
|
||||
//
|
||||
ExtentAd = &AnchorPoint.MainVolumeDescriptorSequenceExtent;
|
||||
|
||||
Volume->MainVdsStartLocation = (UINT64)ExtentAd->ExtentLocation;
|
||||
|
||||
//
|
||||
// Start Main Volume Descriptor Sequence.
|
||||
//
|
||||
Status = StartMainVolumeDescriptorSequence (
|
||||
BlockIo,
|
||||
|
@ -620,16 +516,19 @@ GetFileEntryData (
|
|||
OUT UINT64 *Length
|
||||
)
|
||||
{
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
UDF_EXTENDED_FILE_ENTRY *ExtendedFileEntry;
|
||||
UDF_FILE_ENTRY *FileEntry;
|
||||
|
||||
if (IS_EFE (FileEntryData)) {
|
||||
DescriptorTag = FileEntryData;
|
||||
|
||||
if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {
|
||||
ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
|
||||
|
||||
*Length = ExtendedFileEntry->InformationLength;
|
||||
*Data = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
|
||||
ExtendedFileEntry->LengthOfExtendedAttributes);
|
||||
} else if (IS_FE (FileEntryData)) {
|
||||
} else if (DescriptorTag->TagIdentifier == UdfFileEntry) {
|
||||
FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
|
||||
|
||||
*Length = FileEntry->InformationLength;
|
||||
|
@ -654,16 +553,19 @@ GetAdsInformation (
|
|||
OUT UINT64 *Length
|
||||
)
|
||||
{
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
UDF_EXTENDED_FILE_ENTRY *ExtendedFileEntry;
|
||||
UDF_FILE_ENTRY *FileEntry;
|
||||
|
||||
if (IS_EFE (FileEntryData)) {
|
||||
DescriptorTag = FileEntryData;
|
||||
|
||||
if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {
|
||||
ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;
|
||||
|
||||
*Length = ExtendedFileEntry->LengthOfAllocationDescriptors;
|
||||
*AdsData = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
|
||||
ExtendedFileEntry->LengthOfExtendedAttributes);
|
||||
} else if (IS_FE (FileEntryData)) {
|
||||
} else if (DescriptorTag->TagIdentifier == UdfFileEntry) {
|
||||
FileEntry = (UDF_FILE_ENTRY *)FileEntryData;
|
||||
|
||||
*Length = FileEntry->LengthOfAllocationDescriptors;
|
||||
|
@ -850,6 +752,7 @@ GetAllocationDescriptorLsn (
|
|||
return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR *)Ad);
|
||||
} else if (RecordingFlags == ShortAdsSequence) {
|
||||
return GetShortAdLsn (
|
||||
Volume,
|
||||
GetPdFromLongAd (Volume, ParentIcb),
|
||||
(UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad
|
||||
);
|
||||
|
@ -897,6 +800,7 @@ GetAedAdsOffset (
|
|||
VOID *Data;
|
||||
UINT32 LogicalBlockSize;
|
||||
UDF_ALLOCATION_EXTENT_DESCRIPTOR *AllocExtDesc;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
|
||||
ExtentLength = GET_EXTENT_LENGTH (RecordingFlags, Ad);
|
||||
Lsn = GetAllocationDescriptorLsn (RecordingFlags,
|
||||
|
@ -909,7 +813,7 @@ GetAedAdsOffset (
|
|||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
|
||||
LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
|
||||
|
||||
//
|
||||
// Read extent.
|
||||
|
@ -925,11 +829,14 @@ GetAedAdsOffset (
|
|||
goto Exit;
|
||||
}
|
||||
|
||||
AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
|
||||
|
||||
DescriptorTag = &AllocExtDesc->DescriptorTag;
|
||||
|
||||
//
|
||||
// Check if read extent contains a valid tag identifier for AED.
|
||||
//
|
||||
AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;
|
||||
if (!IS_AED (AllocExtDesc)) {
|
||||
if (DescriptorTag->TagIdentifier != UdfAllocationExtentDescriptor) {
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
@ -1102,7 +1009,7 @@ ReadFile (
|
|||
UINT32 ExtentLength;
|
||||
UDF_FE_RECORDING_FLAGS RecordingFlags;
|
||||
|
||||
LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
|
||||
LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
|
||||
DoFreeAed = FALSE;
|
||||
|
||||
//
|
||||
|
@ -1444,7 +1351,7 @@ InternalFindFile (
|
|||
//
|
||||
// Check if parent file is really directory.
|
||||
//
|
||||
if (!IS_FE_DIRECTORY (Parent->FileEntry)) {
|
||||
if (FE_ICB_FILE_TYPE (Parent->FileEntry) != UdfFileEntryDirectory) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
@ -1489,7 +1396,7 @@ InternalFindFile (
|
|||
break;
|
||||
}
|
||||
|
||||
if (IS_FID_PARENT_FILE (FileIdentifierDesc)) {
|
||||
if (FileIdentifierDesc->FileCharacteristics & PARENT_FILE) {
|
||||
//
|
||||
// This FID contains the location (FE/EFE) of the parent directory of this
|
||||
// directory (Parent), and if FileName is either ".." or "\\", then it's
|
||||
|
@ -1592,6 +1499,9 @@ ReadUdfVolumeInformation (
|
|||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Read all necessary UDF volume information and keep it private to the driver
|
||||
//
|
||||
Status = ReadVolumeFileStructure (
|
||||
BlockIo,
|
||||
DiskIo,
|
||||
|
@ -1601,13 +1511,12 @@ ReadUdfVolumeInformation (
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = GetFileSetDescriptors (
|
||||
BlockIo,
|
||||
DiskIo,
|
||||
Volume
|
||||
);
|
||||
//
|
||||
// Find File Set Descriptor
|
||||
//
|
||||
Status = FindFileSetDescriptor (BlockIo, DiskIo, Volume);
|
||||
if (EFI_ERROR (Status)) {
|
||||
CleanupVolumeInformation (Volume);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
@ -1644,7 +1553,7 @@ FindRootDirectory (
|
|||
BlockIo,
|
||||
DiskIo,
|
||||
Volume,
|
||||
&Volume->FileSetDescs[0]->RootDirectoryIcb,
|
||||
&Volume->FileSetDesc.RootDirectoryIcb,
|
||||
&File->FileEntry
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -1661,7 +1570,7 @@ FindRootDirectory (
|
|||
L"\\",
|
||||
NULL,
|
||||
&Parent,
|
||||
&Volume->FileSetDescs[0]->RootDirectoryIcb,
|
||||
&Volume->FileSetDesc.RootDirectoryIcb,
|
||||
File
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -1697,12 +1606,13 @@ FindFileEntry (
|
|||
OUT VOID **FileEntry
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 Lsn;
|
||||
UINT32 LogicalBlockSize;
|
||||
EFI_STATUS Status;
|
||||
UINT64 Lsn;
|
||||
UINT32 LogicalBlockSize;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
|
||||
Lsn = GetLongAdLsn (Volume, Icb);
|
||||
LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);
|
||||
LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
|
||||
|
||||
*FileEntry = AllocateZeroPool (Volume->FileEntrySize);
|
||||
if (*FileEntry == NULL) {
|
||||
|
@ -1723,11 +1633,14 @@ FindFileEntry (
|
|||
goto Error_Read_Disk_Blk;
|
||||
}
|
||||
|
||||
DescriptorTag = *FileEntry;
|
||||
|
||||
//
|
||||
// Check if the read extent contains a valid Tag Identifier for the expected
|
||||
// FE/EFE.
|
||||
//
|
||||
if (!IS_FE (*FileEntry) && !IS_EFE (*FileEntry)) {
|
||||
if (DescriptorTag->TagIdentifier != UdfFileEntry &&
|
||||
DescriptorTag->TagIdentifier != UdfExtendedFileEntry) {
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
goto Error_Invalid_Fe;
|
||||
}
|
||||
|
@ -1837,7 +1750,7 @@ FindFile (
|
|||
// If the found file is a symlink, then find its respective FE/EFE and
|
||||
// FID descriptors.
|
||||
//
|
||||
if (IS_FE_SYMLINK (File->FileEntry)) {
|
||||
if (FE_ICB_FILE_TYPE (File->FileEntry) == UdfFileEntrySymlink) {
|
||||
FreePool ((VOID *)File->FileIdentifierDesc);
|
||||
|
||||
FileEntry = File->FileEntry;
|
||||
|
@ -1951,7 +1864,7 @@ ReadDirectoryEntry (
|
|||
// Update FidOffset to point to next FID.
|
||||
//
|
||||
ReadDirInfo->FidOffset += GetFidDescriptorLength (FileIdentifierDesc);
|
||||
} while (IS_FID_DELETED_FILE (FileIdentifierDesc));
|
||||
} while (FileIdentifierDesc->FileCharacteristics & DELETED_FILE);
|
||||
|
||||
DuplicateFid (FileIdentifierDesc, FoundFid);
|
||||
|
||||
|
@ -2196,43 +2109,6 @@ Error_Find_File:
|
|||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Clean up in-memory UDF volume information.
|
||||
|
||||
@param[in] Volume Volume information pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
CleanupVolumeInformation (
|
||||
IN UDF_VOLUME_INFO *Volume
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
if (Volume->LogicalVolDescs != NULL) {
|
||||
for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
|
||||
FreePool ((VOID *)Volume->LogicalVolDescs[Index]);
|
||||
}
|
||||
FreePool ((VOID *)Volume->LogicalVolDescs);
|
||||
}
|
||||
|
||||
if (Volume->PartitionDescs != NULL) {
|
||||
for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {
|
||||
FreePool ((VOID *)Volume->PartitionDescs[Index]);
|
||||
}
|
||||
FreePool ((VOID *)Volume->PartitionDescs);
|
||||
}
|
||||
|
||||
if (Volume->FileSetDescs != NULL) {
|
||||
for (Index = 0; Index < Volume->FileSetDescsNo; Index++) {
|
||||
FreePool ((VOID *)Volume->FileSetDescs[Index]);
|
||||
}
|
||||
FreePool ((VOID *)Volume->FileSetDescs);
|
||||
}
|
||||
|
||||
ZeroMem ((VOID *)Volume, sizeof (UDF_VOLUME_INFO));
|
||||
}
|
||||
|
||||
/**
|
||||
Clean up in-memory UDF file information.
|
||||
|
||||
|
@ -2333,6 +2209,7 @@ SetFileInfo (
|
|||
EFI_FILE_INFO *FileInfo;
|
||||
UDF_FILE_ENTRY *FileEntry;
|
||||
UDF_EXTENDED_FILE_ENTRY *ExtendedFileEntry;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
|
||||
//
|
||||
// Calculate the needed size for the EFI_FILE_INFO structure.
|
||||
|
@ -2367,7 +2244,9 @@ SetFileInfo (
|
|||
FileInfo->Attribute |= EFI_FILE_HIDDEN;
|
||||
}
|
||||
|
||||
if (IS_FE (File->FileEntry)) {
|
||||
DescriptorTag = File->FileEntry;
|
||||
|
||||
if (DescriptorTag->TagIdentifier == UdfFileEntry) {
|
||||
FileEntry = (UDF_FILE_ENTRY *)File->FileEntry;
|
||||
|
||||
//
|
||||
|
@ -2403,7 +2282,7 @@ SetFileInfo (
|
|||
FileEntry->AccessTime.Second;
|
||||
FileInfo->LastAccessTime.Nanosecond =
|
||||
FileEntry->AccessTime.HundredsOfMicroseconds;
|
||||
} else if (IS_EFE (File->FileEntry)) {
|
||||
} else if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {
|
||||
ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry;
|
||||
|
||||
//
|
||||
|
@ -2487,91 +2366,103 @@ GetVolumeSize (
|
|||
OUT UINT64 *FreeSpaceSize
|
||||
)
|
||||
{
|
||||
UDF_EXTENT_AD ExtentAd;
|
||||
UINT32 LogicalBlockSize;
|
||||
UINT64 Lsn;
|
||||
EFI_STATUS Status;
|
||||
UDF_LOGICAL_VOLUME_INTEGRITY *LogicalVolInt;
|
||||
UINTN Index;
|
||||
UINTN Length;
|
||||
UINT32 LsnsNo;
|
||||
EFI_STATUS Status;
|
||||
UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc;
|
||||
UDF_EXTENT_AD *ExtentAd;
|
||||
UINT64 Lsn;
|
||||
UINT32 LogicalBlockSize;
|
||||
UDF_LOGICAL_VOLUME_INTEGRITY *LogicalVolInt;
|
||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
||||
UINTN Index;
|
||||
UINTN Length;
|
||||
UINT32 LsnsNo;
|
||||
|
||||
*VolumeSize = 0;
|
||||
*FreeSpaceSize = 0;
|
||||
LogicalVolDesc = &Volume->LogicalVolDesc;
|
||||
|
||||
for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
|
||||
CopyMem ((VOID *)&ExtentAd,
|
||||
(VOID *)&Volume->LogicalVolDescs[Index]->IntegritySequenceExtent,
|
||||
sizeof (UDF_EXTENT_AD));
|
||||
if (ExtentAd.ExtentLength == 0) {
|
||||
continue;
|
||||
}
|
||||
ExtentAd = &LogicalVolDesc->IntegritySequenceExtent;
|
||||
|
||||
LogicalBlockSize = LV_BLOCK_SIZE (Volume, Index);
|
||||
|
||||
Read_Next_Sequence:
|
||||
LogicalVolInt = (UDF_LOGICAL_VOLUME_INTEGRITY *)
|
||||
AllocatePool (ExtentAd.ExtentLength);
|
||||
if (LogicalVolInt == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Lsn = (UINT64)ExtentAd.ExtentLocation;
|
||||
|
||||
Status = DiskIo->ReadDisk (
|
||||
DiskIo,
|
||||
BlockIo->Media->MediaId,
|
||||
MultU64x32 (Lsn, LogicalBlockSize),
|
||||
ExtentAd.ExtentLength,
|
||||
(VOID *)LogicalVolInt
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool ((VOID *)LogicalVolInt);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (!IS_LVID (LogicalVolInt)) {
|
||||
FreePool ((VOID *)LogicalVolInt);
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
Length = LogicalVolInt->NumberOfPartitions;
|
||||
for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
|
||||
LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
|
||||
if (LsnsNo == 0xFFFFFFFFUL) {
|
||||
//
|
||||
// Size not specified.
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
*FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
|
||||
}
|
||||
|
||||
Length = (LogicalVolInt->NumberOfPartitions * sizeof (UINT32)) << 1;
|
||||
for (; Index < Length; Index += sizeof (UINT32)) {
|
||||
LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
|
||||
if (LsnsNo == 0xFFFFFFFFUL) {
|
||||
//
|
||||
// Size not specified.
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
*VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
|
||||
}
|
||||
|
||||
CopyMem ((VOID *)&ExtentAd,(VOID *)&LogicalVolInt->NextIntegrityExtent,
|
||||
sizeof (UDF_EXTENT_AD));
|
||||
if (ExtentAd.ExtentLength > 0) {
|
||||
FreePool ((VOID *)LogicalVolInt);
|
||||
goto Read_Next_Sequence;
|
||||
}
|
||||
|
||||
FreePool ((VOID *)LogicalVolInt);
|
||||
if (ExtentAd->ExtentLength == 0) {
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);
|
||||
if (LogicalVolInt == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Get location of Logical Volume Integrity Descriptor
|
||||
//
|
||||
Lsn = (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation;
|
||||
|
||||
LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;
|
||||
|
||||
//
|
||||
// Read disk block
|
||||
//
|
||||
Status = DiskIo->ReadDisk (
|
||||
DiskIo,
|
||||
BlockIo->Media->MediaId,
|
||||
MultU64x32 (Lsn, LogicalBlockSize),
|
||||
ExtentAd->ExtentLength,
|
||||
LogicalVolInt
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Out_Free;
|
||||
}
|
||||
|
||||
DescriptorTag = &LogicalVolInt->DescriptorTag;
|
||||
|
||||
//
|
||||
// Check if read block is a Logical Volume Integrity Descriptor
|
||||
//
|
||||
if (DescriptorTag->TagIdentifier != UdfLogicalVolumeIntegrityDescriptor) {
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
goto Out_Free;
|
||||
}
|
||||
|
||||
*VolumeSize = 0;
|
||||
*FreeSpaceSize = 0;
|
||||
|
||||
Length = LogicalVolInt->NumberOfPartitions;
|
||||
for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
|
||||
LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
|
||||
//
|
||||
// Check if size is not specified
|
||||
//
|
||||
if (LsnsNo == 0xFFFFFFFFUL) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Accumulate free space size
|
||||
//
|
||||
*FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
|
||||
}
|
||||
|
||||
Length = LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2;
|
||||
for (; Index < Length; Index += sizeof (UINT32)) {
|
||||
LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
|
||||
//
|
||||
// Check if size is not specified
|
||||
//
|
||||
if (LsnsNo == 0xFFFFFFFFUL) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Accumulate used volume space
|
||||
//
|
||||
*VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
Out_Free:
|
||||
//
|
||||
// Free Logical Volume Integrity Descriptor
|
||||
//
|
||||
FreePool (LogicalVolInt);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -276,13 +276,6 @@ UdfDriverBindingStop (
|
|||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// Check if there's any open file. If so, clean them up.
|
||||
//
|
||||
if (PrivFsData->OpenFiles > 0) {
|
||||
CleanupVolumeInformation (&PrivFsData->Volume);
|
||||
}
|
||||
|
||||
FreePool ((VOID *)PrivFsData);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,61 +49,34 @@
|
|||
{ 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A } \
|
||||
}
|
||||
|
||||
#define UDF_DEFAULT_LV_NUM 0
|
||||
#define FE_ICB_FILE_TYPE(_Ptr) \
|
||||
(UDF_FILE_ENTRY_TYPE)( \
|
||||
((UDF_DESCRIPTOR_TAG *)(_Ptr))->TagIdentifier == UdfFileEntry ? \
|
||||
((UDF_FILE_ENTRY *)(_Ptr))->IcbTag.FileType : \
|
||||
((UDF_EXTENDED_FILE_ENTRY *)(_Ptr))->IcbTag.FileType)
|
||||
|
||||
#define IS_PVD(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 1))
|
||||
#define IS_PD(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
|
||||
#define IS_LVD(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
|
||||
#define IS_TD(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
|
||||
#define IS_FSD(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 256))
|
||||
#define IS_FE(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 261))
|
||||
#define IS_EFE(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 266))
|
||||
#define IS_FID(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 257))
|
||||
#define IS_AED(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 258))
|
||||
#define IS_LVID(_Pointer) \
|
||||
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 9))
|
||||
|
||||
#define _GET_FILETYPE(_Pointer) \
|
||||
(IS_FE (_Pointer) ? \
|
||||
(((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType) \
|
||||
: \
|
||||
(((UDF_EXTENDED_FILE_ENTRY *)(_Pointer))->IcbTag.FileType))
|
||||
|
||||
#define IS_FE_DIRECTORY(_Pointer) \
|
||||
((BOOLEAN)(_GET_FILETYPE (_Pointer) == 4))
|
||||
#define IS_FE_STANDARD_FILE(_Pointer) \
|
||||
((BOOLEAN)(_GET_FILETYPE (_Pointer) == 5))
|
||||
#define IS_FE_SYMLINK(_Pointer) \
|
||||
((BOOLEAN)(_GET_FILETYPE (_Pointer) == 12))
|
||||
typedef enum {
|
||||
UdfFileEntryDirectory = 4,
|
||||
UdfFileEntryStandardFile = 5,
|
||||
UdfFileEntrySymlink = 12,
|
||||
} UDF_FILE_ENTRY_TYPE;
|
||||
|
||||
#define HIDDEN_FILE (1 << 0)
|
||||
#define DIRECTORY_FILE (1 << 1)
|
||||
#define DELETED_FILE (1 << 2)
|
||||
#define PARENT_FILE (1 << 3)
|
||||
|
||||
#define _GET_FILE_CHARS(_Pointer) \
|
||||
(((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics)
|
||||
|
||||
#define IS_FID_HIDDEN_FILE(_Pointer) \
|
||||
((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & HIDDEN_FILE))
|
||||
#define IS_FID_DIRECTORY_FILE(_Pointer) \
|
||||
((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DIRECTORY_FILE))
|
||||
#define IS_FID_DELETED_FILE(_Pointer) \
|
||||
((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DELETED_FILE))
|
||||
#define IS_FID_PARENT_FILE(_Pointer) \
|
||||
((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & PARENT_FILE))
|
||||
#define IS_FID_NORMAL_FILE(_Pointer) \
|
||||
((BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Pointer) && \
|
||||
!IS_FID_PARENT_FILE (_Pointer)))
|
||||
#define IS_FID_HIDDEN_FILE(_Fid) \
|
||||
(BOOLEAN)((_Fid)->FileCharacteristics & HIDDEN_FILE)
|
||||
#define IS_FID_DIRECTORY_FILE(_Fid) \
|
||||
(BOOLEAN)((_Fid)->FileCharacteristics & DIRECTORY_FILE)
|
||||
#define IS_FID_DELETED_FILE(_Fid) \
|
||||
(BOOLEAN)((_Fid)->FileCharacteristics & DELETED_FILE)
|
||||
#define IS_FID_PARENT_FILE(_Fid) \
|
||||
(BOOLEAN)((_Fid)->FileCharacteristics & PARENT_FILE)
|
||||
#define IS_FID_NORMAL_FILE(_Fid) \
|
||||
(BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Fid) && \
|
||||
!IS_FID_PARENT_FILE (_Fid))
|
||||
|
||||
typedef enum {
|
||||
ShortAdsSequence,
|
||||
|
@ -152,14 +125,8 @@ typedef enum {
|
|||
#define IS_VALID_COMPRESSION_ID(_CompId) \
|
||||
((BOOLEAN)((_CompId) == 8 || (_CompId) == 16))
|
||||
|
||||
#define LV_BLOCK_SIZE(_Vol, _LvNum) \
|
||||
(_Vol)->LogicalVolDescs[(_LvNum)]->LogicalBlockSize
|
||||
|
||||
#define UDF_STANDARD_IDENTIFIER_LENGTH 5
|
||||
|
||||
#define LV_UDF_REVISION(_Lv) \
|
||||
*(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
|
@ -185,17 +152,6 @@ typedef struct {
|
|||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
UINT8 CharacterSetType;
|
||||
UINT8 CharacterSetInfo[63];
|
||||
} UDF_CHAR_SPEC;
|
||||
|
||||
typedef struct {
|
||||
UINT8 Flags;
|
||||
UINT8 Identifier[23];
|
||||
UINT8 IdentifierSuffix[8];
|
||||
} UDF_ENTITY_ID;
|
||||
|
||||
typedef struct {
|
||||
UINT16 TypeAndTimezone;
|
||||
INT16 Year;
|
||||
|
@ -209,17 +165,6 @@ typedef struct {
|
|||
UINT8 Microseconds;
|
||||
} UDF_TIMESTAMP;
|
||||
|
||||
typedef struct {
|
||||
UINT32 LogicalBlockNumber;
|
||||
UINT16 PartitionReferenceNumber;
|
||||
} UDF_LB_ADDR;
|
||||
|
||||
typedef struct {
|
||||
UINT32 ExtentLength;
|
||||
UDF_LB_ADDR ExtentLocation;
|
||||
UINT8 ImplementationUse[6];
|
||||
} UDF_LONG_ALLOCATION_DESCRIPTOR;
|
||||
|
||||
typedef struct {
|
||||
UDF_DESCRIPTOR_TAG DescriptorTag;
|
||||
UINT32 PrevAllocationExtentDescriptor;
|
||||
|
@ -234,6 +179,17 @@ typedef struct {
|
|||
UINT8 StructureData[2040];
|
||||
} UDF_VOLUME_DESCRIPTOR;
|
||||
|
||||
typedef struct {
|
||||
UDF_DESCRIPTOR_TAG DescriptorTag;
|
||||
UDF_TIMESTAMP RecordingDateTime;
|
||||
UINT32 IntegrityType;
|
||||
UDF_EXTENT_AD NextIntegrityExtent;
|
||||
UINT8 LogicalVolumeContentsUse[32];
|
||||
UINT32 NumberOfPartitions;
|
||||
UINT32 LengthOfImplementationUse;
|
||||
UINT8 Data[0];
|
||||
} UDF_LOGICAL_VOLUME_INTEGRITY;
|
||||
|
||||
typedef struct {
|
||||
UDF_DESCRIPTOR_TAG DescriptorTag;
|
||||
UINT32 VolumeDescriptorSequenceNumber;
|
||||
|
@ -249,33 +205,6 @@ typedef struct {
|
|||
UINT8 Reserved[156];
|
||||
} UDF_PARTITION_DESCRIPTOR;
|
||||
|
||||
typedef struct {
|
||||
UDF_DESCRIPTOR_TAG DescriptorTag;
|
||||
UINT32 VolumeDescriptorSequenceNumber;
|
||||
UDF_CHAR_SPEC DescriptorCharacterSet;
|
||||
UINT8 LogicalVolumeIdentifier[128];
|
||||
UINT32 LogicalBlockSize;
|
||||
UDF_ENTITY_ID DomainIdentifier;
|
||||
UDF_LONG_ALLOCATION_DESCRIPTOR LogicalVolumeContentsUse;
|
||||
UINT32 MapTableLength;
|
||||
UINT32 NumberOfPartitionMaps;
|
||||
UDF_ENTITY_ID ImplementationIdentifier;
|
||||
UINT8 ImplementationUse[128];
|
||||
UDF_EXTENT_AD IntegritySequenceExtent;
|
||||
UINT8 PartitionMaps[6];
|
||||
} UDF_LOGICAL_VOLUME_DESCRIPTOR;
|
||||
|
||||
typedef struct {
|
||||
UDF_DESCRIPTOR_TAG DescriptorTag;
|
||||
UDF_TIMESTAMP RecordingDateTime;
|
||||
UINT32 IntegrityType;
|
||||
UDF_EXTENT_AD NextIntegrityExtent;
|
||||
UINT8 LogicalVolumeContentsUse[32];
|
||||
UINT32 NumberOfPartitions;
|
||||
UINT32 LengthOfImplementationUse;
|
||||
UINT8 Data[0];
|
||||
} UDF_LOGICAL_VOLUME_INTEGRITY;
|
||||
|
||||
typedef struct {
|
||||
UDF_DESCRIPTOR_TAG DescriptorTag;
|
||||
UDF_TIMESTAMP RecordingDateAndTime;
|
||||
|
@ -389,12 +318,10 @@ typedef struct {
|
|||
// UDF filesystem driver's private data
|
||||
//
|
||||
typedef struct {
|
||||
UDF_LOGICAL_VOLUME_DESCRIPTOR **LogicalVolDescs;
|
||||
UINTN LogicalVolDescsNo;
|
||||
UDF_PARTITION_DESCRIPTOR **PartitionDescs;
|
||||
UINTN PartitionDescsNo;
|
||||
UDF_FILE_SET_DESCRIPTOR **FileSetDescs;
|
||||
UINTN FileSetDescsNo;
|
||||
UINT64 MainVdsStartLocation;
|
||||
UDF_LOGICAL_VOLUME_DESCRIPTOR LogicalVolDesc;
|
||||
UDF_PARTITION_DESCRIPTOR PartitionDesc;
|
||||
UDF_FILE_SET_DESCRIPTOR FileSetDesc;
|
||||
UINTN FileEntrySize;
|
||||
} UDF_VOLUME_INFO;
|
||||
|
||||
|
@ -883,17 +810,6 @@ ResolveSymlink (
|
|||
OUT UDF_FILE_INFO *File
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up in-memory UDF volume information.
|
||||
|
||||
@param[in] Volume Volume information pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
CleanupVolumeInformation (
|
||||
IN UDF_VOLUME_INFO *Volume
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up in-memory UDF file information.
|
||||
|
||||
|
|
Loading…
Reference in New Issue