From nobody Thu Dec 26 13:30:58 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1506104091473828.7478594170251; Fri, 22 Sep 2017 11:14:51 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id C186421D046B7; Fri, 22 Sep 2017 11:11:41 -0700 (PDT) Received: from mail.zytor.com (terminus.zytor.com [65.50.211.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E9C5D21E43B50 for ; Fri, 22 Sep 2017 11:11:39 -0700 (PDT) Received: from ALCANTAP5.auth.hpicorp.net (corporativo.static.gvt.net.br [177.135.97.54] (may be forged)) (authenticated bits=0) by mail.zytor.com (8.15.2/8.15.2) with ESMTPSA id v8MICCkV014705 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=NO); Fri, 22 Sep 2017 11:12:31 -0700 X-Original-To: edk2-devel@lists.01.org From: Paulo Alcantara To: edk2-devel@lists.01.org Date: Fri, 22 Sep 2017 15:11:32 -0300 Message-Id: <12c51958d9945cf59ecd413fc2def2c802c8d2a5.1506103370.git.pcacjr@zytor.com> X-Mailer: git-send-email 2.13.3.windows.1 In-Reply-To: References: In-Reply-To: References: Subject: [edk2] [PATCH v4 2/2] MdeModulePkg/UDF: Fix creation of UDF logical partition X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ruiyu Ni , Laszlo Ersek , Eric Dong , Star Zeng MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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 Cc: Ruiyu Ni Cc: Star Zeng Cc: Laszlo Ersek Reported-by: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Paulo Alcantara Tested-by: Hao Wu Build-tested-by: Laszlo Ersek Reviewed-by: Star Zeng Build-tested-by: Star Zeng Build-tested-by: Paulo Alcantara --- 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; =20 BlockSize =3D BlockIo->Media->BlockSize; EndLBA =3D BlockIo->Media->LastBlock; @@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer ( if (EFI_ERROR (Status)) { return Status; } + + DescriptorTag =3D &AnchorPoint->DescriptorTag; + // // Check if read LBA has a valid AVDP descriptor. // - if (IS_AVDP (AnchorPoint)) { + if (DescriptorTag->TagIdentifier =3D=3D UdfAnchorVolumeDescriptorPoint= er) { return EFI_SUCCESS; } } @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer ( } =20 /** - Check if block device supports a valid UDF file system as specified by O= STA - Universal Disk Format Specification 2.60. + Find UDF volume identifiers in a Volume Recognition Sequence. =20 - @param[in] BlockIo BlockIo interface. - @param[in] DiskIo DiskIo interface. + @param[in] BlockIo BlockIo interface. + @param[in] DiskIo DiskIo interface. =20 - @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. =20 **/ 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; =20 ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIP= TOR)); =20 @@ -167,7 +165,7 @@ SupportUdfFileSystem ( (CompareMem ((VOID *)&VolDescriptor, (VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIPTOR)) =3D=3D 0)) { - return EFI_UNSUPPORTED; + return EFI_NOT_FOUND; } } =20 @@ -176,7 +174,7 @@ SupportUdfFileSystem ( // Offset +=3D UDF_LOGICAL_SECTOR_SIZE; if (Offset >=3D EndDiskOffset) { - return EFI_UNSUPPORTED; + return EFI_NOT_FOUND; } =20 Status =3D DiskIo->ReadDisk ( @@ -196,7 +194,7 @@ SupportUdfFileSystem ( (CompareMem ((VOID *)VolDescriptor.Unknown.Id, (VOID *)UDF_NSR3_IDENTIFIER, sizeof (VolDescriptor.Unknown.Id)) !=3D 0)) { - return EFI_UNSUPPORTED; + return EFI_NOT_FOUND; } =20 // @@ -204,7 +202,7 @@ SupportUdfFileSystem ( // Offset +=3D UDF_LOGICAL_SECTOR_SIZE; if (Offset >=3D EndDiskOffset) { - return EFI_UNSUPPORTED; + return EFI_NOT_FOUND; } =20 Status =3D DiskIo->ReadDisk ( @@ -221,15 +219,291 @@ SupportUdfFileSystem ( if (CompareMem ((VOID *)VolDescriptor.Unknown.Id, (VOID *)UDF_TEA_IDENTIFIER, sizeof (VolDescriptor.Unknown.Id)) !=3D 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] !=3D 1 || + LogicalVolDesc->PartitionMaps[1] !=3D 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 =3D BlockIo->Media->BlockSize; + LastBlock =3D BlockIo->Media->LastBlock; + ExtentAd =3D &AnchorPoint->MainVolumeDescriptorSequenceExtent; + + // + // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent + // + // The Main Volume Descriptor Sequence Extent shall have a minimum lengt= h of + // 16 logical sectors. + // + // Also make sure it does not exceed maximum number of blocks in the dis= k. + // + SeqBlocksNum =3D 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 =3D (UINT64)ExtentAd->ExtentLocation; + if (SeqStartBlock > LastBlock || + SeqStartBlock + SeqBlocksNum - 1 > LastBlock) { + return EFI_VOLUME_CORRUPTED; + } + + GuardMainVdsStartBlock =3D SeqStartBlock; + + // + // Allocate buffer for reading disk blocks + // + Buffer =3D AllocateZeroPool ((UINTN)BlockSize); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SeqEndBlock =3D SeqStartBlock + SeqBlocksNum; + StopSequence =3D FALSE; + LvdsCount =3D 0; + Status =3D EFI_VOLUME_CORRUPTED; + // + // Start Main Volume Descriptor Sequence + // + for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) { + // + // Read disk block + // + Status =3D BlockIo->ReadBlocks ( + BlockIo, + BlockIo->Media->MediaId, + SeqStartBlock, + BlockSize, + Buffer + ); + if (EFI_ERROR (Status)) { + goto Out_Free; + } + + DescriptorTag =3D Buffer; + + // + // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence + // + // - A Volume Descriptor Sequence shall contain one or more Primary Vo= lume + // Descriptors. + // - A Volume Descriptor Sequence shall contain zero or more Implement= ation + // Use Volume Descriptors. + // - A Volume Descriptor Sequence shall contain zero or more Partition + // Descriptors. + // - A Volume Descriptor Sequence shall contain zero or more Logical V= olume + // Descriptors. + // - A Volume Descriptor Sequence shall contain zero or more Unallocat= ed + // Space Descriptors. + // + switch (DescriptorTag->TagIdentifier) { + case UdfPrimaryVolumeDescriptor: + case UdfImplemenationUseVolumeDescriptor: + case UdfPartitionDescriptor: + case UdfUnallocatedSpaceDescriptor: + break; + + case UdfLogicalVolumeDescriptor: + LogicalVolDesc =3D 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 =3D EFI_UNSUPPORTED; + StopSequence =3D 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 unallo= cated + // area unnecessarily. + // + StopSequence =3D TRUE; + break; + + default: + // + // An invalid Volume Descriptor has been found in the sequece. Volum= e is + // corrupted. + // + Status =3D EFI_VOLUME_CORRUPTED; + goto Out_Free; + } + } + + // + // Check if LVD was found + // + if (!EFI_ERROR (Status) && LvdsCount =3D=3D 1) { + *MainVdsStartBlock =3D 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 =3D LastBlock; + + Status =3D 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 =3D FindUdfVolumeIdentifiers (BlockIo, DiskIo); + if (EFI_ERROR (Status)) { + return Status; } =20 + // + // Find Anchor Volume Descriptor Pointer + // Status =3D FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPo= int); if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; + return Status; } =20 - return EFI_SUCCESS; + // + // Find Logical Volume location + // + Status =3D FindLogicalVolumeLocation ( + BlockIo, + DiskIo, + &AnchorPoint, + (UINT64 *)StartingLBA, + (UINT64 *)EndingLBA + ); + + return Status; } =20 /** @@ -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; =20 Media =3D BlockIo->Media; =20 @@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles ( return EFI_NOT_FOUND; } =20 - DevicePathNode =3D 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) =3D=3D MEDIA_DEVICE_PATH) { - if (DevicePathSubType (DevicePathNode) =3D=3D MEDIA_CDROM_DP) { - return EFI_NOT_FOUND; - } - if (DevicePathSubType (DevicePathNode) =3D=3D MEDIA_VENDOR_DP) { - VendorDefinedGuid =3D (EFI_GUID *)((UINTN)DevicePathNode + - OFFSET_OF (VENDOR_DEVICE_PATH, Gu= id)); - if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) { - return EFI_NOT_FOUND; - } - } - } - // - // Try next device path node - // - DevicePathNode =3D NextDevicePathNode (DevicePathNode); - } - // - // Check if block device supports an UDF file system + // Search for an UDF file system on block device // - Status =3D SupportUdfFileSystem (BlockIo, DiskIo); + Status =3D 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 =3D EFI_NOT_FOUND; - } =20 return Status; } diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c b/MdeModulePkg/Unive= rsal/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); =20 Error_Find_Root_Dir: - CleanupVolumeInformation (&PrivFsData->Volume); =20 Error_Read_Udf_Volume: Error_Invalid_Params: @@ -429,7 +428,7 @@ UdfRead ( } ASSERT (NewFileEntryData !=3D NULL); =20 - if (IS_FE_SYMLINK (NewFileEntryData)) { + if (FE_ICB_FILE_TYPE (NewFileEntryData) =3D=3D UdfFileEntrySymlink) { Status =3D 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; =20 OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); =20 @@ -542,8 +540,6 @@ UdfClose ( =20 PrivFileData =3D PRIVATE_UDF_FILE_DATA_FROM_THIS (This); =20 - PrivFsData =3D PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->Simpl= eFs); - if (!PrivFileData->IsRootDirectory) { CleanupFileInformation (&PrivFileData->File); =20 @@ -552,10 +548,6 @@ UdfClose ( } } =20 - if (--PrivFsData->OpenFiles =3D=3D 0) { - CleanupVolumeInformation (&PrivFsData->Volume); - } - FreePool ((VOID *)PrivFileData); =20 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; } =20 @@ -788,7 +780,7 @@ UdfGetInfo ( } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { String =3D VolumeLabel; =20 - FileSetDesc =3D PrivFsData->Volume.FileSetDescs[0]; + FileSetDesc =3D &PrivFsData->Volume.FileSetDesc; =20 OstaCompressed =3D &FileSetDesc->LogicalVolumeIdentifier[0]; =20 @@ -847,7 +839,7 @@ UdfGetInfo ( FileSystemInfo->Size =3D FileSystemInfoLength; FileSystemInfo->ReadOnly =3D TRUE; FileSystemInfo->BlockSize =3D - LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM); + PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize; FileSystemInfo->VolumeSize =3D VolumeSize; FileSystemInfo->FreeSpace =3D FreeSpaceSize; =20 diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c b/Md= eModulePkg/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; =20 BlockSize =3D BlockIo->Media->BlockSize; EndLBA =3D BlockIo->Media->LastBlock; @@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer ( if (EFI_ERROR (Status)) { return Status; } + + DescriptorTag =3D &AnchorPoint->DescriptorTag; + // // Check if read LBA has a valid AVDP descriptor. // - if (IS_AVDP (AnchorPoint)) { + if (DescriptorTag->TagIdentifier =3D=3D UdfAnchorVolumeDescriptorPoint= er) { 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 =3D BlockIo->Media->BlockSize; + ExtentAd =3D &AnchorPoint->MainVolumeDescriptorSequenceExtent; =20 // - // 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 (Block= Size) - // boundary, so we need to read one block at a time. + // Allocate buffer for reading disk blocks // - BlockSize =3D BlockIo->Media->BlockSize; - ExtentAd =3D &AnchorPoint->MainVolumeDescriptorSequenceExtent; - StartingLsn =3D (UINT64)ExtentAd->ExtentLocation; - EndingLsn =3D StartingLsn + DivU64x32 ( - (UINT64)ExtentAd->ExtentLength, - BlockSize - ); - - Volume->LogicalVolDescs =3D - (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd->ExtentLe= ngth); - if (Volume->LogicalVolDescs =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Volume->PartitionDescs =3D - (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd->ExtentLength); - if (Volume->PartitionDescs =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto Error_Alloc_Pds; - } - - Buffer =3D AllocateZeroPool (BlockSize); + Buffer =3D AllocateZeroPool ((UINTN)BlockSize); if (Buffer =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto Error_Alloc_Buf; + return EFI_OUT_OF_RESOURCES; } =20 - Volume->LogicalVolDescsNo =3D 0; - Volume->PartitionDescsNo =3D 0; - - while (StartingLsn <=3D EndingLsn) { - Status =3D 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 =3D 0; + SeqEndBlock =3D SeqStartBlock + DivU64x32 ((UINT64)ExtentAd->ExtentLengt= h, + BlockSize); + StopSequence =3D FALSE; + for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) { + // + // Read disk block + // + Status =3D BlockIo->ReadBlocks ( + BlockIo, BlockIo->Media->MediaId, - MultU64x32 (StartingLsn, BlockSize), + SeqStartBlock, BlockSize, Buffer ); if (EFI_ERROR (Status)) { - goto Error_Read_Disk_Blk; + goto Out_Free; } =20 - if (IS_TD (Buffer)) { + DescriptorTag =3D Buffer; + + switch (DescriptorTag->TagIdentifier) { + case UdfPartitionDescriptor: // - // Found a Terminating Descriptor. Stop the sequence then. + // Save Partition Descriptor // + CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume->PartitionDe= sc)); break; - } =20 - if (IS_LVD (Buffer)) { + case UdfLogicalVolumeDescriptor: // - // Found a Logical Volume Descriptor. + // Save Logical Volume Descriptor // - LogicalVolDesc =3D - (UDF_LOGICAL_VOLUME_DESCRIPTOR *) - AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR)); - if (LogicalVolDesc =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto Error_Alloc_Lvd; - } + CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume->LogicalVol= Desc)); + break; =20 - CopyMem ((VOID *)LogicalVolDesc, Buffer, - sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR)); - Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] =3D LogicalVolD= esc; - } else if (IS_PD (Buffer)) { - // - // Found a Partition Descriptor. - // - PartitionDesc =3D - (UDF_PARTITION_DESCRIPTOR *) - AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR)); - if (PartitionDesc =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto Error_Alloc_Pd; - } + case UdfTerminatingDescriptor: + StopSequence =3D TRUE; + break; =20 - CopyMem ((VOID *)PartitionDesc, Buffer, - sizeof (UDF_PARTITION_DESCRIPTOR)); - Volume->PartitionDescs[Volume->PartitionDescsNo++] =3D PartitionDesc; + default: + ; } - - StartingLsn++; } =20 // - // When an UDF volume (revision 2.00 or higher) contains a File Entry ra= ther - // than an Extended File Entry (which is not recommended as per spec), w= e 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 =3D LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM); + LogicalBlockSize =3D Volume->LogicalVolDesc.LogicalBlockSize; if (LogicalBlockSize >=3D UDF_LOGICAL_SECTOR_SIZE) { - Volume->FileEntrySize =3D LogicalBlockSize; + Volume->FileEntrySize =3D (UINTN)LogicalBlockSize; } else { Volume->FileEntrySize =3D UDF_LOGICAL_SECTOR_SIZE; } =20 - FreePool (Buffer); + Status =3D EFI_SUCCESS; =20 - return EFI_SUCCESS; - -Error_Alloc_Pd: -Error_Alloc_Lvd: - for (Index =3D 0; Index < Volume->PartitionDescsNo; Index++) { - FreePool ((VOID *)Volume->PartitionDescs[Index]); - } - - for (Index =3D 0; Index < Volume->LogicalVolDescsNo; Index++) { - FreePool ((VOID *)Volume->LogicalVolDescs[Index]); - } - -Error_Read_Disk_Blk: +Out_Free: + // + // Free block read buffer + // FreePool (Buffer); =20 -Error_Alloc_Buf: - FreePool ((VOID *)Volume->PartitionDescs); - Volume->PartitionDescs =3D NULL; - -Error_Alloc_Pds: - FreePool ((VOID *)Volume->LogicalVolDescs); - Volume->LogicalVolDescs =3D NULL; - return Status; } =20 @@ -262,48 +216,53 @@ GetPdFromLongAd ( ) { UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc; - UINTN Index; - UDF_PARTITION_DESCRIPTOR *PartitionDesc; UINT16 PartitionNum; =20 - LogicalVolDesc =3D Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM]; + LogicalVolDesc =3D &Volume->LogicalVolDesc; =20 - 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 rec= orded // per Volume Set. The Partition Maps field shall contain only Type 1 // Partition Maps. // - PartitionNum =3D *(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 docume= nt. + // + // 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 s= ays + // it may be 0, so let's not rely on it. // - if (LogicalVolDesc->PartitionMaps[0] !=3D 1 || - LogicalVolDesc->PartitionMaps[1] !=3D 6) { - return NULL; - } PartitionNum =3D *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]); break; - case 0x0260: + + default: // - // Fall through. + // Unsupported UDF revision // - default: - PartitionNum =3D LongAd->ExtentLocation.PartitionReferenceNumber; - break; + return NULL; } =20 - for (Index =3D 0; Index < Volume->PartitionDescsNo; Index++) { - PartitionDesc =3D Volume->PartitionDescs[Index]; - if (PartitionDesc->PartitionNumber =3D=3D PartitionNum) { - return PartitionDesc; - } + // + // Check if partition number matches Partition Descriptor found in Main = Volume + // Descriptor Sequence. + // + if (Volume->PartitionDesc.PartitionNumber =3D=3D PartitionNum) { + return &Volume->PartitionDesc; } =20 return NULL; @@ -329,13 +288,15 @@ GetLongAdLsn ( PartitionDesc =3D GetPdFromLongAd (Volume, LongAd); ASSERT (PartitionDesc !=3D NULL); =20 - return (UINT64)PartitionDesc->PartitionStartingLocation + - LongAd->ExtentLocation.LogicalBlockNumber; + return (UINT64)PartitionDesc->PartitionStartingLocation - + Volume->MainVdsStartLocation + + LongAd->ExtentLocation.LogicalBlockNumber; } =20 /** Return logical sector number of a given Short Allocation Descriptor. =20 + @param[in] Volume Volume pointer. @param[in] PartitionDesc Partition Descriptor pointer. @param[in] ShortAd Short Allocation Descriptor pointer. =20 @@ -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 !=3D NULL); - - return (UINT64)PartitionDesc->PartitionStartingLocation + - ShortAd->ExtentPosition; + return (UINT64)PartitionDesc->PartitionStartingLocation - + Volume->MainVdsStartLocation + ShortAd->ExtentPosition; } =20 /** @@ -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. =20 @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; =20 - LogicalVolDesc =3D Volume->LogicalVolDescs[LogicalVolDescNum]; + LogicalVolDesc =3D &Volume->LogicalVolDesc; Lsn =3D GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse); =20 // - // 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 =3D 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; } =20 + DescriptorTag =3D &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 !=3D UdfFileSetDescriptor) { return EFI_VOLUME_CORRUPTED; } =20 @@ -412,82 +376,6 @@ FindFileSetDescriptor ( } =20 /** - 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 =3D - (UDF_FILE_SET_DESCRIPTOR **)AllocateZeroPool ( - Volume->LogicalVolDescsNo * sizeof (UDF_FILE_SET_DESCRIPTOR)); - if (Volume->FileSetDescs =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - for (Index =3D 0; Index < Volume->LogicalVolDescsNo; Index++) { - FileSetDesc =3D AllocateZeroPool (sizeof (UDF_FILE_SET_DESCRIPTOR)); - if (FileSetDesc =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto Error_Alloc_Fsd; - } - - // - // Find a FSD for this LVD. - // - Status =3D FindFileSetDescriptor ( - BlockIo, - DiskIo, - Volume, - Index, - FileSetDesc - ); - if (EFI_ERROR (Status)) { - goto Error_Find_Fsd; - } - - // - // Got one. Save it. - // - Volume->FileSetDescs[Index] =3D FileSetDesc; - } - - Volume->FileSetDescsNo =3D Volume->LogicalVolDescsNo; - return EFI_SUCCESS; - -Error_Find_Fsd: - Count =3D Index + 1; - for (Index =3D 0; Index < Count; Index++) { - FreePool ((VOID *)Volume->FileSetDescs[Index]); - } - - FreePool ((VOID *)Volume->FileSetDescs); - Volume->FileSetDescs =3D NULL; - -Error_Alloc_Fsd: - return Status; -} - -/** Read Volume and File Structure on an UDF file system. =20 @param[in] BlockIo BlockIo interface. @@ -507,9 +395,10 @@ ReadVolumeFileStructure ( { EFI_STATUS Status; UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER AnchorPoint; + UDF_EXTENT_AD *ExtentAd; =20 // - // Find an AVDP. + // Find Anchor Volume Descriptor Pointer // Status =3D FindAnchorVolumeDescriptorPointer ( BlockIo, @@ -521,7 +410,14 @@ ReadVolumeFileStructure ( } =20 // - // AVDP has been found. Start MVDS. + // Save Main VDS start block number + // + ExtentAd =3D &AnchorPoint.MainVolumeDescriptorSequenceExtent; + + Volume->MainVdsStartLocation =3D (UINT64)ExtentAd->ExtentLocation; + + // + // Start Main Volume Descriptor Sequence. // Status =3D StartMainVolumeDescriptorSequence ( BlockIo, @@ -620,16 +516,19 @@ GetFileEntryData ( OUT UINT64 *Length ) { + UDF_DESCRIPTOR_TAG *DescriptorTag; UDF_EXTENDED_FILE_ENTRY *ExtendedFileEntry; UDF_FILE_ENTRY *FileEntry; =20 - if (IS_EFE (FileEntryData)) { + DescriptorTag =3D FileEntryData; + + if (DescriptorTag->TagIdentifier =3D=3D UdfExtendedFileEntry) { ExtendedFileEntry =3D (UDF_EXTENDED_FILE_ENTRY *)FileEntryData; =20 *Length =3D ExtendedFileEntry->InformationLength; *Data =3D (VOID *)((UINT8 *)ExtendedFileEntry->Data + ExtendedFileEntry->LengthOfExtendedAttributes); - } else if (IS_FE (FileEntryData)) { + } else if (DescriptorTag->TagIdentifier =3D=3D UdfFileEntry) { FileEntry =3D (UDF_FILE_ENTRY *)FileEntryData; =20 *Length =3D FileEntry->InformationLength; @@ -654,16 +553,19 @@ GetAdsInformation ( OUT UINT64 *Length ) { + UDF_DESCRIPTOR_TAG *DescriptorTag; UDF_EXTENDED_FILE_ENTRY *ExtendedFileEntry; UDF_FILE_ENTRY *FileEntry; =20 - if (IS_EFE (FileEntryData)) { + DescriptorTag =3D FileEntryData; + + if (DescriptorTag->TagIdentifier =3D=3D UdfExtendedFileEntry) { ExtendedFileEntry =3D (UDF_EXTENDED_FILE_ENTRY *)FileEntryData; =20 *Length =3D ExtendedFileEntry->LengthOfAllocationDescriptors; *AdsData =3D (VOID *)((UINT8 *)ExtendedFileEntry->Data + ExtendedFileEntry->LengthOfExtendedAttributes); - } else if (IS_FE (FileEntryData)) { + } else if (DescriptorTag->TagIdentifier =3D=3D UdfFileEntry) { FileEntry =3D (UDF_FILE_ENTRY *)FileEntryData; =20 *Length =3D FileEntry->LengthOfAllocationDescriptors; @@ -850,6 +752,7 @@ GetAllocationDescriptorLsn ( return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR *)Ad); } else if (RecordingFlags =3D=3D 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; =20 ExtentLength =3D GET_EXTENT_LENGTH (RecordingFlags, Ad); Lsn =3D GetAllocationDescriptorLsn (RecordingFlags, @@ -909,7 +813,7 @@ GetAedAdsOffset ( return EFI_OUT_OF_RESOURCES; } =20 - LogicalBlockSize =3D LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM); + LogicalBlockSize =3D Volume->LogicalVolDesc.LogicalBlockSize; =20 // // Read extent. @@ -925,11 +829,14 @@ GetAedAdsOffset ( goto Exit; } =20 + AllocExtDesc =3D (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data; + + DescriptorTag =3D &AllocExtDesc->DescriptorTag; + // // Check if read extent contains a valid tag identifier for AED. // - AllocExtDesc =3D (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data; - if (!IS_AED (AllocExtDesc)) { + if (DescriptorTag->TagIdentifier !=3D UdfAllocationExtentDescriptor) { Status =3D EFI_VOLUME_CORRUPTED; goto Exit; } @@ -1102,7 +1009,7 @@ ReadFile ( UINT32 ExtentLength; UDF_FE_RECORDING_FLAGS RecordingFlags; =20 - LogicalBlockSize =3D LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM); + LogicalBlockSize =3D Volume->LogicalVolDesc.LogicalBlockSize; DoFreeAed =3D FALSE; =20 // @@ -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) !=3D UdfFileEntryDirectory) { return EFI_NOT_FOUND; } =20 @@ -1489,7 +1396,7 @@ InternalFindFile ( break; } =20 - if (IS_FID_PARENT_FILE (FileIdentifierDesc)) { + if (FileIdentifierDesc->FileCharacteristics & PARENT_FILE) { // // This FID contains the location (FE/EFE) of the parent directory o= f this // directory (Parent), and if FileName is either ".." or "\\", then = it's @@ -1592,6 +1499,9 @@ ReadUdfVolumeInformation ( { EFI_STATUS Status; =20 + // + // Read all necessary UDF volume information and keep it private to the = driver + // Status =3D ReadVolumeFileStructure ( BlockIo, DiskIo, @@ -1601,13 +1511,12 @@ ReadUdfVolumeInformation ( return Status; } =20 - Status =3D GetFileSetDescriptors ( - BlockIo, - DiskIo, - Volume - ); + // + // Find File Set Descriptor + // + Status =3D FindFileSetDescriptor (BlockIo, DiskIo, Volume); if (EFI_ERROR (Status)) { - CleanupVolumeInformation (Volume); + return Status; } =20 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; =20 Lsn =3D GetLongAdLsn (Volume, Icb); - LogicalBlockSize =3D LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM); + LogicalBlockSize =3D Volume->LogicalVolDesc.LogicalBlockSize; =20 *FileEntry =3D AllocateZeroPool (Volume->FileEntrySize); if (*FileEntry =3D=3D NULL) { @@ -1723,11 +1633,14 @@ FindFileEntry ( goto Error_Read_Disk_Blk; } =20 + DescriptorTag =3D *FileEntry; + // // Check if the read extent contains a valid Tag Identifier for the expe= cted // FE/EFE. // - if (!IS_FE (*FileEntry) && !IS_EFE (*FileEntry)) { + if (DescriptorTag->TagIdentifier !=3D UdfFileEntry && + DescriptorTag->TagIdentifier !=3D UdfExtendedFileEntry) { Status =3D 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) =3D=3D UdfFileEntrySymlink) { FreePool ((VOID *)File->FileIdentifierDesc); =20 FileEntry =3D File->FileEntry; @@ -1951,7 +1864,7 @@ ReadDirectoryEntry ( // Update FidOffset to point to next FID. // ReadDirInfo->FidOffset +=3D GetFidDescriptorLength (FileIdentifierDesc= ); - } while (IS_FID_DELETED_FILE (FileIdentifierDesc)); + } while (FileIdentifierDesc->FileCharacteristics & DELETED_FILE); =20 DuplicateFid (FileIdentifierDesc, FoundFid); =20 @@ -2197,43 +2110,6 @@ Error_Find_File: } =20 /** - 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 !=3D NULL) { - for (Index =3D 0; Index < Volume->LogicalVolDescsNo; Index++) { - FreePool ((VOID *)Volume->LogicalVolDescs[Index]); - } - FreePool ((VOID *)Volume->LogicalVolDescs); - } - - if (Volume->PartitionDescs !=3D NULL) { - for (Index =3D 0; Index < Volume->PartitionDescsNo; Index++) { - FreePool ((VOID *)Volume->PartitionDescs[Index]); - } - FreePool ((VOID *)Volume->PartitionDescs); - } - - if (Volume->FileSetDescs !=3D NULL) { - for (Index =3D 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. =20 @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; =20 // // Calculate the needed size for the EFI_FILE_INFO structure. @@ -2367,7 +2244,9 @@ SetFileInfo ( FileInfo->Attribute |=3D EFI_FILE_HIDDEN; } =20 - if (IS_FE (File->FileEntry)) { + DescriptorTag =3D File->FileEntry; + + if (DescriptorTag->TagIdentifier =3D=3D UdfFileEntry) { FileEntry =3D (UDF_FILE_ENTRY *)File->FileEntry; =20 // @@ -2403,7 +2282,7 @@ SetFileInfo ( FileEntry->AccessTime.Second; FileInfo->LastAccessTime.Nanosecond =3D FileEntry->AccessTime.HundredsOfMicrose= conds; - } else if (IS_EFE (File->FileEntry)) { + } else if (DescriptorTag->TagIdentifier =3D=3D UdfExtendedFileEntry) { ExtendedFileEntry =3D (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry; =20 // @@ -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 =3D 0; - *FreeSpaceSize =3D 0; - - for (Index =3D 0; Index < Volume->LogicalVolDescsNo; Index++) { - CopyMem ((VOID *)&ExtentAd, - (VOID *)&Volume->LogicalVolDescs[Index]->IntegritySequenceExt= ent, - sizeof (UDF_EXTENT_AD)); - if (ExtentAd.ExtentLength =3D=3D 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; =20 - LogicalBlockSize =3D LV_BLOCK_SIZE (Volume, Index); + LogicalVolDesc =3D &Volume->LogicalVolDesc; =20 - Read_Next_Sequence: - LogicalVolInt =3D (UDF_LOGICAL_VOLUME_INTEGRITY *) - AllocatePool (ExtentAd.ExtentLength); - if (LogicalVolInt =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } + ExtentAd =3D &LogicalVolDesc->IntegritySequenceExtent; + + if (ExtentAd->ExtentLength =3D=3D 0) { + return EFI_VOLUME_CORRUPTED; + } =20 - Lsn =3D (UINT64)ExtentAd.ExtentLocation; + LogicalVolInt =3D AllocatePool (ExtentAd->ExtentLength); + if (LogicalVolInt =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } =20 - Status =3D 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 =3D (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation; =20 - if (!IS_LVID (LogicalVolInt)) { - FreePool ((VOID *)LogicalVolInt); - return EFI_VOLUME_CORRUPTED; - } + LogicalBlockSize =3D LogicalVolDesc->LogicalBlockSize; =20 - Length =3D LogicalVolInt->NumberOfPartitions; - for (Index =3D 0; Index < Length; Index +=3D sizeof (UINT32)) { - LsnsNo =3D *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index); - if (LsnsNo =3D=3D 0xFFFFFFFFUL) { - // - // Size not specified. - // - continue; - } + // + // Read disk block + // + Status =3D DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + MultU64x32 (Lsn, LogicalBlockSize), + ExtentAd->ExtentLength, + LogicalVolInt + ); + if (EFI_ERROR (Status)) { + goto Out_Free; + } =20 - *FreeSpaceSize +=3D MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize); - } + DescriptorTag =3D &LogicalVolInt->DescriptorTag; =20 - Length =3D (LogicalVolInt->NumberOfPartitions * sizeof (UINT32)) << 1; - for (; Index < Length; Index +=3D sizeof (UINT32)) { - LsnsNo =3D *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index); - if (LsnsNo =3D=3D 0xFFFFFFFFUL) { - // - // Size not specified. - // - continue; - } + // + // Check if read block is a Logical Volume Integrity Descriptor + // + if (DescriptorTag->TagIdentifier !=3D UdfLogicalVolumeIntegrityDescripto= r) { + Status =3D EFI_VOLUME_CORRUPTED; + goto Out_Free; + } =20 - *VolumeSize +=3D MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize); - } + *VolumeSize =3D 0; + *FreeSpaceSize =3D 0; =20 - CopyMem ((VOID *)&ExtentAd,(VOID *)&LogicalVolInt->NextIntegrityExtent, - sizeof (UDF_EXTENT_AD)); - if (ExtentAd.ExtentLength > 0) { - FreePool ((VOID *)LogicalVolInt); - goto Read_Next_Sequence; + Length =3D LogicalVolInt->NumberOfPartitions; + for (Index =3D 0; Index < Length; Index +=3D sizeof (UINT32)) { + LsnsNo =3D *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index); + // + // Check if size is not specified + // + if (LsnsNo =3D=3D 0xFFFFFFFFUL) { + continue; } + // + // Accumulate free space size + // + *FreeSpaceSize +=3D MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize); + } =20 - FreePool ((VOID *)LogicalVolInt); + Length =3D LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2; + for (; Index < Length; Index +=3D sizeof (UINT32)) { + LsnsNo =3D *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index); + // + // Check if size is not specified + // + if (LsnsNo =3D=3D 0xFFFFFFFFUL) { + continue; + } + // + // Accumulate used volume space + // + *VolumeSize +=3D MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize); } =20 - return EFI_SUCCESS; + Status =3D EFI_SUCCESS; + +Out_Free: + // + // Free Logical Volume Integrity Descriptor + // + FreePool (LogicalVolInt); + + return Status; } =20 /** diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c b/MdeModulePkg/Univer= sal/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 ); =20 - // - // Check if there's any open file. If so, clean them up. - // - if (PrivFsData->OpenFiles > 0) { - CleanupVolumeInformation (&PrivFsData->Volume); - } - FreePool ((VOID *)PrivFsData); } =20 diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h b/MdeModulePkg/Univer= sal/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 } \ } =20 -#define UDF_DEFAULT_LV_NUM 0 - -#define IS_PVD(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 1)) -#define IS_PD(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 5)) -#define IS_LVD(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 6)) -#define IS_TD(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 8)) -#define IS_FSD(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 256)) -#define IS_FE(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 261)) -#define IS_EFE(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 266)) -#define IS_FID(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 257)) -#define IS_AED(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 258)) -#define IS_LVID(_Pointer) \ - ((BOOLEAN)(_GET_TAG_ID (_Pointer) =3D=3D 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) =3D=3D 4)) -#define IS_FE_STANDARD_FILE(_Pointer) \ - ((BOOLEAN)(_GET_FILETYPE (_Pointer) =3D=3D 5)) -#define IS_FE_SYMLINK(_Pointer) \ - ((BOOLEAN)(_GET_FILETYPE (_Pointer) =3D=3D 12)) +#define FE_ICB_FILE_TYPE(_Ptr) \ + (UDF_FILE_ENTRY_TYPE)( \ + ((UDF_DESCRIPTOR_TAG *)(_Ptr))->TagIdentifier =3D=3D UdfFileEntry ? \ + ((UDF_FILE_ENTRY *)(_Ptr))->IcbTag.FileType : \ + ((UDF_EXTENDED_FILE_ENTRY *)(_Ptr))->IcbTag.FileType) + +typedef enum { + UdfFileEntryDirectory =3D 4, + UdfFileEntryStandardFile =3D 5, + UdfFileEntrySymlink =3D 12, +} UDF_FILE_ENTRY_TYPE; =20 #define HIDDEN_FILE (1 << 0) #define DIRECTORY_FILE (1 << 1) #define DELETED_FILE (1 << 2) #define PARENT_FILE (1 << 3) =20 -#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)) =20 typedef enum { ShortAdsSequence, @@ -152,14 +125,8 @@ typedef enum { #define IS_VALID_COMPRESSION_ID(_CompId) \ ((BOOLEAN)((_CompId) =3D=3D 8 || (_CompId) =3D=3D 16)) =20 -#define LV_BLOCK_SIZE(_Vol, _LvNum) \ - (_Vol)->LogicalVolDescs[(_LvNum)]->LogicalBlockSize - #define UDF_STANDARD_IDENTIFIER_LENGTH 5 =20 -#define LV_UDF_REVISION(_Lv) \ - *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix - #pragma pack(1) =20 typedef struct { @@ -186,17 +153,6 @@ typedef struct { #pragma pack(1) =20 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; =20 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; =20 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 { =20 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; =20 @@ -884,17 +811,6 @@ ResolveSymlink ( ); =20 /** - 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. =20 @param[in] File File information pointer. --=20 2.13.3.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel