* [PATCH v4 0/2] UDF partition driver fix
@ 2017-09-22 18:11 Paulo Alcantara
2017-09-22 18:11 ` [PATCH v4 1/2] MdePkg: Add UDF volume structure definitions Paulo Alcantara
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Paulo Alcantara @ 2017-09-22 18:11 UTC (permalink / raw)
To: edk2-devel
Cc: Paulo Alcantara, Michael D Kinney, Liming Gao, Laszlo Ersek,
Ruiyu Ni, Star Zeng, Jiewen Yao
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=707
Hi,
This patchset fixes a bug in Partition driver that created UDF logical
partitions by using entire block device space and thus polluting
protocol database with broken handles.
v1->v2:
- Followed Laszlo's suggestions to submit a proper patchset. Thanks!
- As I'm still waiting for Ruiyu and Star to test this fix, I took
advantage of it and did some code cleanups :-)
v2->v3:
- Followed Ruiyu's suggestions to improve code and add additional
checks for ensuring a valid UDF file system and supported by current
EDK2 UDF file system implementation. Also run Ecc.py to make sure the
files I touched did not break EDK2 C Coding Style, as well as
PatchCheck.py for mal-formed patches.
v3->v4:
- Change 2/2's title as suggested by Star.
- Remove UDF_TAG_ID() and refactor out UDF_ENTITY_ID structure as
suggested by Ruiyu.
- Tested build with VS2015 toolchain.
I've had a chance to test these changes with my 32GiB USB stick
and formatted it on Windows 10 with `format` command. The UDF revisions
I tested (by specifying it with "/R:revision") were 1.02, 1.50, 2.00,
2.01 (default) and 2.50. They all worked except the 2.50 revision which
adds a Type 2 (Metadata) Partition and it's not supported by current
EDK2 UDF implementation -- which handles only Type 1 (Physical)
Partitions. The UDF 2.60 revision I tested with the usual
`sudo mkudffs -b 512 --media-type=hd /dev/sdX` command in Linux.
Remember, the *officially* supported revision is 2.60, however all
revisions use the same volume structures as defined by ECMA 167
specification, and they usually differ from each other by means of
new optional features, so that's why all those revisions worked with
this implementation.
Well, at least this what I understood when looking at the
specifications. Please correct me if I'm wrong.
Please, test building these changes in toolchains other than GCC and
make sure they don't break the world :-)
Thanks!
Paulo
Repo: https://github.com/pcacjr/edk2.git
Branch: udf-partition-fix-v4
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
---
Paulo Alcantara (2):
MdePkg: Add UDF volume structure definitions
MdeModulePkg/UDF: Fix creation of UDF logical partition
MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 366 ++++++++++--
MdeModulePkg/Universal/Disk/UdfDxe/File.c | 16 +-
MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 ++++++++------------
MdeModulePkg/Universal/Disk/UdfDxe/Udf.c | 7 -
MdeModulePkg/Universal/Disk/UdfDxe/Udf.h | 158 ++---
MdePkg/Include/IndustryStandard/Udf.h | 97 ++-
6 files changed, 698 insertions(+), 573 deletions(-)
--
2.13.3.windows.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 1/2] MdePkg: Add UDF volume structure definitions
2017-09-22 18:11 [PATCH v4 0/2] UDF partition driver fix Paulo Alcantara
@ 2017-09-22 18:11 ` Paulo Alcantara
2017-09-22 18:11 ` [PATCH v4 2/2] MdeModulePkg/UDF: Fix creation of UDF logical partition Paulo Alcantara
2017-09-25 0:31 ` [PATCH v4 0/2] UDF partition driver fix Ni, Ruiyu
2 siblings, 0 replies; 5+ messages in thread
From: Paulo Alcantara @ 2017-09-22 18:11 UTC (permalink / raw)
To: edk2-devel
Cc: Paulo Alcantara, Michael D Kinney, Liming Gao, Laszlo Ersek,
Ruiyu Ni
This patch adds a few more UDF volume structures in order to detect an
UDF file system which is supported by current EDK2 UDF file system
implementation in Partition driver.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
Build-tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Tested-by: Hao Wu <hao.a.wu@intel.com>
Build-tested-by: Star Zeng <star.zeng@intel.com>
Build-tested-by: Paulo Alcantara <paulo@hp.com>
---
MdePkg/Include/IndustryStandard/Udf.h | 97 +++++++++++++++++++-
1 file changed, 92 insertions(+), 5 deletions(-)
diff --git a/MdePkg/Include/IndustryStandard/Udf.h b/MdePkg/Include/IndustryStandard/Udf.h
index 0febb4bcda..5806560aee 100644
--- a/MdePkg/Include/IndustryStandard/Udf.h
+++ b/MdePkg/Include/IndustryStandard/Udf.h
@@ -24,11 +24,22 @@
#define UDF_LOGICAL_SECTOR_SIZE ((UINT64)(1ULL << UDF_LOGICAL_SECTOR_SHIFT))
#define UDF_VRS_START_OFFSET ((UINT64)(16ULL << UDF_LOGICAL_SECTOR_SHIFT))
-#define _GET_TAG_ID(_Pointer) \
- (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)
-
-#define IS_AVDP(_Pointer) \
- ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))
+typedef enum {
+ UdfPrimaryVolumeDescriptor = 1,
+ UdfAnchorVolumeDescriptorPointer = 2,
+ UdfVolumeDescriptorPointer = 3,
+ UdfImplemenationUseVolumeDescriptor = 4,
+ UdfPartitionDescriptor = 5,
+ UdfLogicalVolumeDescriptor = 6,
+ UdfUnallocatedSpaceDescriptor = 7,
+ UdfTerminatingDescriptor = 8,
+ UdfLogicalVolumeIntegrityDescriptor = 9,
+ UdfFileSetDescriptor = 256,
+ UdfFileIdentifierDescriptor = 257,
+ UdfAllocationExtentDescriptor = 258,
+ UdfFileEntry = 261,
+ UdfExtendedFileEntry = 266,
+} UDF_VOLUME_DESCRIPTOR_ID;
#pragma pack(1)
@@ -49,12 +60,88 @@ typedef struct {
} UDF_EXTENT_AD;
typedef struct {
+ UINT8 CharacterSetType;
+ UINT8 CharacterSetInfo[63];
+} UDF_CHAR_SPEC;
+
+typedef struct {
+ UINT8 Flags;
+ UINT8 Identifier[23];
+ union {
+ //
+ // Domain Entity Identifier
+ //
+ struct {
+ UINT16 UdfRevision;
+ UINT8 DomainFlags;
+ UINT8 Reserved[5];
+ } Domain;
+ //
+ // UDF Entity Identifier
+ //
+ struct {
+ UINT16 UdfRevision;
+ UINT8 OSClass;
+ UINT8 OSIdentifier;
+ UINT8 Reserved[4];
+ } Entity;
+ //
+ // Implementation Entity Identifier
+ //
+ struct {
+ UINT8 OSClass;
+ UINT8 OSIdentifier;
+ UINT8 ImplementationUseArea[6];
+ } ImplementationEntity;
+ //
+ // Application Entity Identifier
+ //
+ struct {
+ UINT8 ApplicationUseArea[8];
+ } ApplicationEntity;
+ //
+ // Raw Identifier Suffix
+ //
+ struct {
+ UINT8 Data[8];
+ } Raw;
+ } Suffix;
+} UDF_ENTITY_ID;
+
+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;
UDF_EXTENT_AD MainVolumeDescriptorSequenceExtent;
UDF_EXTENT_AD ReserveVolumeDescriptorSequenceExtent;
UINT8 Reserved[480];
} UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER;
+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;
+
#pragma pack()
#endif
--
2.13.3.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 2/2] MdeModulePkg/UDF: Fix creation of UDF logical partition
2017-09-22 18:11 [PATCH v4 0/2] UDF partition driver fix Paulo Alcantara
2017-09-22 18:11 ` [PATCH v4 1/2] MdePkg: Add UDF volume structure definitions Paulo Alcantara
@ 2017-09-22 18:11 ` Paulo Alcantara
2017-09-25 0:31 ` [PATCH v4 0/2] UDF partition driver fix Ni, Ruiyu
2 siblings, 0 replies; 5+ messages in thread
From: Paulo Alcantara @ 2017-09-22 18:11 UTC (permalink / raw)
To: edk2-devel; +Cc: Paulo Alcantara, Eric Dong, Ruiyu Ni, Star Zeng, Laszlo Ersek
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>
---
MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 366 ++++++++++--
MdeModulePkg/Universal/Disk/UdfDxe/File.c | 16 +-
MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 ++++++++------------
MdeModulePkg/Universal/Disk/UdfDxe/Udf.c | 7 -
MdeModulePkg/Universal/Disk/UdfDxe/Udf.h | 158 ++---
5 files changed, 606 insertions(+), 568 deletions(-)
diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
index 609f56cef6..8aee30c759 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
@@ -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,15 +219,291 @@ SupportUdfFileSystem (
if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
(VOID *)UDF_TEA_IDENTIFIER,
sizeof (VolDescriptor.Unknown.Id)) != 0) {
- 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 EFI_UNSUPPORTED;
+ return Status;
}
- return EFI_SUCCESS;
+ //
+ // Find Logical Volume location
+ //
+ Status = FindLogicalVolumeLocation (
+ BlockIo,
+ DiskIo,
+ &AnchorPoint,
+ (UINT64 *)StartingLBA,
+ (UINT64 *)EndingLBA
+ );
+
+ return Status;
}
/**
@@ -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;
}
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
index 625f2c5637..6f07bf2066 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
@@ -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;
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
index 5df267761f..b336ffc553 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
@@ -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.
- //
- // Note also that each descriptor will be aligned on a block size (BlockSize)
- // boundary, so we need to read one block at a time.
+ // Allocate buffer for reading disk blocks
//
- 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) {
- 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);
+ Buffer = AllocateZeroPool ((UINTN)BlockSize);
if (Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error_Alloc_Buf;
+ return EFI_OUT_OF_RESOURCES;
}
- 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;
- }
- if (IS_LVD (Buffer)) {
+ case UdfLogicalVolumeDescriptor:
//
- // Found a Logical Volume Descriptor.
+ // Save 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 (&Volume->LogicalVolDesc, Buffer, sizeof (Volume->LogicalVolDesc));
+ break;
- 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;
- }
+ case UdfTerminatingDescriptor:
+ StopSequence = TRUE;
+ break;
- CopyMem ((VOID *)PartitionDesc, Buffer,
- sizeof (UDF_PARTITION_DESCRIPTOR));
- Volume->PartitionDescs[Volume->PartitionDescsNo++] = PartitionDesc;
+ default:
+ ;
}
-
- 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;
}
- FreePool (Buffer);
+ Status = EFI_SUCCESS;
- 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:
+Out_Free:
+ //
+ // Free block read buffer
+ //
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.
//
- PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
- break;
- case 0x0150:
+ // UDF 1.50 through 2.60 specs say:
//
- // Ensure Type 1 Partition map. Other types aren't supported in this
- // implementation.
+ // 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.
//
- if (LogicalVolDesc->PartitionMaps[0] != 1 ||
- LogicalVolDesc->PartitionMaps[1] != 6) {
- return NULL;
- }
PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
break;
- case 0x0260:
+
+ default:
//
- // Fall through.
+ // Unsupported UDF revision
//
- default:
- PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
- break;
+ 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,36 +333,42 @@ 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;
}
@@ -412,82 +376,6 @@ FindFileSetDescriptor (
}
/**
- 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.
@param[in] BlockIo BlockIo interface.
@@ -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);
@@ -2197,43 +2110,6 @@ Error_Find_File:
}
/**
- 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.
@param[in] File File information pointer.
@@ -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;
-
- *VolumeSize = 0;
- *FreeSpaceSize = 0;
-
- for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {
- CopyMem ((VOID *)&ExtentAd,
- (VOID *)&Volume->LogicalVolDescs[Index]->IntegritySequenceExtent,
- sizeof (UDF_EXTENT_AD));
- if (ExtentAd.ExtentLength == 0) {
- continue;
- }
+ 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;
- LogicalBlockSize = LV_BLOCK_SIZE (Volume, Index);
+ LogicalVolDesc = &Volume->LogicalVolDesc;
- Read_Next_Sequence:
- LogicalVolInt = (UDF_LOGICAL_VOLUME_INTEGRITY *)
- AllocatePool (ExtentAd.ExtentLength);
- if (LogicalVolInt == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
+ ExtentAd = &LogicalVolDesc->IntegritySequenceExtent;
+
+ if (ExtentAd->ExtentLength == 0) {
+ return EFI_VOLUME_CORRUPTED;
+ }
- Lsn = (UINT64)ExtentAd.ExtentLocation;
+ LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);
+ if (LogicalVolInt == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
- Status = DiskIo->ReadDisk (
- DiskIo,
- BlockIo->Media->MediaId,
- MultU64x32 (Lsn, LogicalBlockSize),
- ExtentAd.ExtentLength,
- (VOID *)LogicalVolInt
- );
- if (EFI_ERROR (Status)) {
- FreePool ((VOID *)LogicalVolInt);
- return Status;
- }
+ //
+ // Get location of Logical Volume Integrity Descriptor
+ //
+ Lsn = (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation;
- if (!IS_LVID (LogicalVolInt)) {
- FreePool ((VOID *)LogicalVolInt);
- return EFI_VOLUME_CORRUPTED;
- }
+ LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;
- Length = LogicalVolInt->NumberOfPartitions;
- for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
- LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
- if (LsnsNo == 0xFFFFFFFFUL) {
- //
- // Size not specified.
- //
- continue;
- }
+ //
+ // Read disk block
+ //
+ Status = DiskIo->ReadDisk (
+ DiskIo,
+ BlockIo->Media->MediaId,
+ MultU64x32 (Lsn, LogicalBlockSize),
+ ExtentAd->ExtentLength,
+ LogicalVolInt
+ );
+ if (EFI_ERROR (Status)) {
+ goto Out_Free;
+ }
- *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
- }
+ DescriptorTag = &LogicalVolInt->DescriptorTag;
- 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;
- }
+ //
+ // Check if read block is a Logical Volume Integrity Descriptor
+ //
+ if (DescriptorTag->TagIdentifier != UdfLogicalVolumeIntegrityDescriptor) {
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Out_Free;
+ }
- *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
- }
+ *VolumeSize = 0;
+ *FreeSpaceSize = 0;
- CopyMem ((VOID *)&ExtentAd,(VOID *)&LogicalVolInt->NextIntegrityExtent,
- sizeof (UDF_EXTENT_AD));
- if (ExtentAd.ExtentLength > 0) {
- FreePool ((VOID *)LogicalVolInt);
- goto Read_Next_Sequence;
+ 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);
+ }
- FreePool ((VOID *)LogicalVolInt);
+ 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);
}
- return EFI_SUCCESS;
+ Status = EFI_SUCCESS;
+
+Out_Free:
+ //
+ // Free Logical Volume Integrity Descriptor
+ //
+ FreePool (LogicalVolInt);
+
+ return Status;
}
/**
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
index 49dc7077b7..d4163b89ca 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
@@ -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);
}
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
index 44c843fd4d..d441539d16 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
@@ -49,61 +49,34 @@
{ 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A } \
}
-#define UDF_DEFAULT_LV_NUM 0
-
-#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))
+#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)
+
+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 {
@@ -186,17 +153,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;
UINT8 Month;
@@ -210,17 +166,6 @@ typedef struct {
} 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;
UINT32 LengthOfAllocationDescriptors;
@@ -235,6 +180,17 @@ typedef struct {
} 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;
UINT16 PartitionFlags;
@@ -251,33 +207,6 @@ typedef struct {
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;
UINT16 InterchangeLevel;
UINT16 MaximumInterchangeLevel;
@@ -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;
@@ -884,17 +811,6 @@ ResolveSymlink (
);
/**
- 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.
@param[in] File File information pointer.
--
2.13.3.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 0/2] UDF partition driver fix
2017-09-22 18:11 [PATCH v4 0/2] UDF partition driver fix Paulo Alcantara
2017-09-22 18:11 ` [PATCH v4 1/2] MdePkg: Add UDF volume structure definitions Paulo Alcantara
2017-09-22 18:11 ` [PATCH v4 2/2] MdeModulePkg/UDF: Fix creation of UDF logical partition Paulo Alcantara
@ 2017-09-25 0:31 ` Ni, Ruiyu
2017-09-25 7:38 ` Zeng, Star
2 siblings, 1 reply; 5+ messages in thread
From: Ni, Ruiyu @ 2017-09-25 0:31 UTC (permalink / raw)
To: Paulo Alcantara, edk2-devel@lists.01.org
Cc: Kinney, Michael D, Gao, Liming, Laszlo Ersek, Zeng, Star,
Yao, Jiewen
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
-----Original Message-----
From: Paulo Alcantara [mailto:pcacjr@zytor.com]
Sent: Saturday, September 23, 2017 2:12 AM
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pcacjr@zytor.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ni, Ruiyu <ruiyu.ni@intel.com>; Zeng, Star <star.zeng@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>
Subject: [PATCH v4 0/2] UDF partition driver fix
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=707
Hi,
This patchset fixes a bug in Partition driver that created UDF logical partitions by using entire block device space and thus polluting protocol database with broken handles.
v1->v2:
- Followed Laszlo's suggestions to submit a proper patchset. Thanks!
- As I'm still waiting for Ruiyu and Star to test this fix, I took
advantage of it and did some code cleanups :-)
v2->v3:
- Followed Ruiyu's suggestions to improve code and add additional
checks for ensuring a valid UDF file system and supported by current
EDK2 UDF file system implementation. Also run Ecc.py to make sure the
files I touched did not break EDK2 C Coding Style, as well as
PatchCheck.py for mal-formed patches.
v3->v4:
- Change 2/2's title as suggested by Star.
- Remove UDF_TAG_ID() and refactor out UDF_ENTITY_ID structure as
suggested by Ruiyu.
- Tested build with VS2015 toolchain.
I've had a chance to test these changes with my 32GiB USB stick and formatted it on Windows 10 with `format` command. The UDF revisions I tested (by specifying it with "/R:revision") were 1.02, 1.50, 2.00,
2.01 (default) and 2.50. They all worked except the 2.50 revision which adds a Type 2 (Metadata) Partition and it's not supported by current
EDK2 UDF implementation -- which handles only Type 1 (Physical) Partitions. The UDF 2.60 revision I tested with the usual `sudo mkudffs -b 512 --media-type=hd /dev/sdX` command in Linux.
Remember, the *officially* supported revision is 2.60, however all revisions use the same volume structures as defined by ECMA 167 specification, and they usually differ from each other by means of new optional features, so that's why all those revisions worked with this implementation.
Well, at least this what I understood when looking at the specifications. Please correct me if I'm wrong.
Please, test building these changes in toolchains other than GCC and make sure they don't break the world :-)
Thanks!
Paulo
Repo: https://github.com/pcacjr/edk2.git
Branch: udf-partition-fix-v4
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
---
Paulo Alcantara (2):
MdePkg: Add UDF volume structure definitions
MdeModulePkg/UDF: Fix creation of UDF logical partition
MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 366 ++++++++++--
MdeModulePkg/Universal/Disk/UdfDxe/File.c | 16 +-
MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 ++++++++------------
MdeModulePkg/Universal/Disk/UdfDxe/Udf.c | 7 -
MdeModulePkg/Universal/Disk/UdfDxe/Udf.h | 158 ++---
MdePkg/Include/IndustryStandard/Udf.h | 97 ++-
6 files changed, 698 insertions(+), 573 deletions(-)
--
2.13.3.windows.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v4 0/2] UDF partition driver fix
2017-09-25 0:31 ` [PATCH v4 0/2] UDF partition driver fix Ni, Ruiyu
@ 2017-09-25 7:38 ` Zeng, Star
0 siblings, 0 replies; 5+ messages in thread
From: Zeng, Star @ 2017-09-25 7:38 UTC (permalink / raw)
To: Ni, Ruiyu, Paulo Alcantara, edk2-devel@lists.01.org
Cc: Kinney, Michael D, Gao, Liming, Laszlo Ersek, Yao, Jiewen,
Zeng, Star
Pushed at https://github.com/tianocore/edk2/compare/e921f58d4458...baaa3cee1eaf.
Thanks all. :)
Star
-----Original Message-----
From: Ni, Ruiyu
Sent: Monday, September 25, 2017 8:31 AM
To: Paulo Alcantara <pcacjr@zytor.com>; edk2-devel@lists.01.org
Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Laszlo Ersek <lersek@redhat.com>; Zeng, Star <star.zeng@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>
Subject: RE: [PATCH v4 0/2] UDF partition driver fix
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
-----Original Message-----
From: Paulo Alcantara [mailto:pcacjr@zytor.com]
Sent: Saturday, September 23, 2017 2:12 AM
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pcacjr@zytor.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ni, Ruiyu <ruiyu.ni@intel.com>; Zeng, Star <star.zeng@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>
Subject: [PATCH v4 0/2] UDF partition driver fix
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=707
Hi,
This patchset fixes a bug in Partition driver that created UDF logical partitions by using entire block device space and thus polluting protocol database with broken handles.
v1->v2:
- Followed Laszlo's suggestions to submit a proper patchset. Thanks!
- As I'm still waiting for Ruiyu and Star to test this fix, I took
advantage of it and did some code cleanups :-)
v2->v3:
- Followed Ruiyu's suggestions to improve code and add additional
checks for ensuring a valid UDF file system and supported by current
EDK2 UDF file system implementation. Also run Ecc.py to make sure the
files I touched did not break EDK2 C Coding Style, as well as
PatchCheck.py for mal-formed patches.
v3->v4:
- Change 2/2's title as suggested by Star.
- Remove UDF_TAG_ID() and refactor out UDF_ENTITY_ID structure as
suggested by Ruiyu.
- Tested build with VS2015 toolchain.
I've had a chance to test these changes with my 32GiB USB stick and formatted it on Windows 10 with `format` command. The UDF revisions I tested (by specifying it with "/R:revision") were 1.02, 1.50, 2.00,
2.01 (default) and 2.50. They all worked except the 2.50 revision which adds a Type 2 (Metadata) Partition and it's not supported by current
EDK2 UDF implementation -- which handles only Type 1 (Physical) Partitions. The UDF 2.60 revision I tested with the usual `sudo mkudffs -b 512 --media-type=hd /dev/sdX` command in Linux.
Remember, the *officially* supported revision is 2.60, however all revisions use the same volume structures as defined by ECMA 167 specification, and they usually differ from each other by means of new optional features, so that's why all those revisions worked with this implementation.
Well, at least this what I understood when looking at the specifications. Please correct me if I'm wrong.
Please, test building these changes in toolchains other than GCC and make sure they don't break the world :-)
Thanks!
Paulo
Repo: https://github.com/pcacjr/edk2.git
Branch: udf-partition-fix-v4
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
---
Paulo Alcantara (2):
MdePkg: Add UDF volume structure definitions
MdeModulePkg/UDF: Fix creation of UDF logical partition
MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 366 ++++++++++--
MdeModulePkg/Universal/Disk/UdfDxe/File.c | 16 +-
MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 ++++++++------------
MdeModulePkg/Universal/Disk/UdfDxe/Udf.c | 7 -
MdeModulePkg/Universal/Disk/UdfDxe/Udf.h | 158 ++---
MdePkg/Include/IndustryStandard/Udf.h | 97 ++-
6 files changed, 698 insertions(+), 573 deletions(-)
--
2.13.3.windows.1
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-09-25 7:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-22 18:11 [PATCH v4 0/2] UDF partition driver fix Paulo Alcantara
2017-09-22 18:11 ` [PATCH v4 1/2] MdePkg: Add UDF volume structure definitions Paulo Alcantara
2017-09-22 18:11 ` [PATCH v4 2/2] MdeModulePkg/UDF: Fix creation of UDF logical partition Paulo Alcantara
2017-09-25 0:31 ` [PATCH v4 0/2] UDF partition driver fix Ni, Ruiyu
2017-09-25 7:38 ` Zeng, Star
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox