From nobody Fri Dec 27 02:36:55 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 1503597569182877.665033308836; Thu, 24 Aug 2017 10:59:29 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 419E12095AE58; Thu, 24 Aug 2017 10:56:52 -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 433112095AE4F for ; Thu, 24 Aug 2017 10:56:50 -0700 (PDT) Received: from localhost.localdomain ([IPv6:2804:7f4:c480:f0c1:0:0:0:1]) (authenticated bits=0) by mail.zytor.com (8.15.2/8.15.2) with ESMTPSA id v7OHuv33026217 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 24 Aug 2017 10:57:11 -0700 X-Original-To: edk2-devel@lists.01.org From: Paulo Alcantara To: edk2-devel@lists.01.org Date: Thu, 24 Aug 2017 14:56:23 -0300 Message-Id: X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: Subject: [edk2] [PATCH v4 2/6] MdeModulePkg/PartitionDxe: Add UDF file system support 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: 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" Scan for UDF file systems on all block devices, as specified by OSTA Universal Disk Format Specification 2.60, and install a Vendor-Defined Media Device Path for each file system found. The Vendor-Defined Media Device Path for the UDF file system is then checked by UdfDxe to decide whether or not start the driver. Cc: Star Zeng Cc: Eric Dong Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Paulo Alcantara --- .../Universal/Disk/PartitionDxe/Partition.c | 9 +- .../Universal/Disk/PartitionDxe/Partition.h | 32 ++- .../Universal/Disk/PartitionDxe/PartitionDxe.inf | 3 +- MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 318 +++++++++++++++++= ++++ 4 files changed, 355 insertions(+), 7 deletions(-) create mode 100644 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c b/MdeModu= lePkg/Universal/Disk/PartitionDxe/Partition.c index 5a7d119b43..f6030e0897 100644 --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c @@ -1,7 +1,7 @@ /** @file Partition driver that produces logical BlockIo devices from a physical BlockIo device. The logical BlockIo devices are based on the format - of the raw block devices media. Currently "El Torito CD-ROM", Legacy + of the raw block devices media. Currently "El Torito CD-ROM", UDF, Legacy MBR, and GPT partition schemes are supported. =20 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
@@ -45,6 +45,7 @@ PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = =3D { PartitionInstallGptChildHandles, PartitionInstallElToritoChildHandles, PartitionInstallMbrChildHandles, + PartitionInstallUdfChildHandles, NULL }; =20 @@ -305,9 +306,9 @@ PartitionDriverBindingStart ( if (BlockIo->Media->MediaPresent || (BlockIo->Media->RemovableMedia && !BlockIo->Media->LogicalPartition= )) { // - // Try for GPT, then El Torito, and then legacy MBR partition types. I= f the - // media supports a given partition type install child handles to repr= esent - // the partitions described by the media. + // Try for GPT, then El Torito, then UDF, and then legacy MBR partition + // types. If the media supports a given partition type install child h= andles + // to represent the partitions described by the media. // Routine =3D &mPartitionDetectRoutineTable[0]; while (*Routine !=3D NULL) { diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.h b/MdeModu= lePkg/Universal/Disk/PartitionDxe/Partition.h index f2f6185317..c763c676a9 100644 --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.h +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.h @@ -1,7 +1,7 @@ /** @file Partition driver that produces logical BlockIo devices from a physical=20 BlockIo device. The logical BlockIo devices are based on the format - of the raw block devices media. Currently "El Torito CD-ROM", Legacy=20 + of the raw block devices media. Currently "El Torito CD-ROM", UDF, Legacy MBR, and GPT partition schemes are supported. =20 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
@@ -39,7 +39,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER= EXPRESS OR IMPLIED. =20 #include #include - +#include =20 // // Partition private data @@ -445,6 +445,34 @@ PartitionInstallMbrChildHandles ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ); =20 +/** + Install child handles if the Handle supports UDF/ECMA-167 volume format. + + @param[in] This Calling context. + @param[in] Handle Parent Handle. + @param[in] DiskIo Parent DiskIo interface. + @param[in] DiskIo2 Parent DiskIo2 interface. + @param[in] BlockIo Parent BlockIo interface. + @param[in] BlockIo2 Parent BlockIo2 interface. + @param[in] DevicePath Parent Device Path + + + @retval EFI_SUCCESS Child handle(s) was added. + @retval EFI_MEDIA_CHANGED Media changed Detected. + @retval other no child handle was added. + +**/ +EFI_STATUS +PartitionInstallUdfChildHandles ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_DISK_IO2_PROTOCOL *DiskIo2, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + typedef EFI_STATUS (*PARTITION_DETECT_ROUTINE) ( diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf b/Md= eModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf index 48212773e8..fb2ea87a9d 100644 --- a/MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf @@ -4,7 +4,7 @@ # This module produces the logical Block I/O device that represents # the bytes from Start to End of the Parent Block I/O device. # The partition of physical BlockIo device supported is one of legacy MBR= , GPT, -# and "El Torito" partitions. +# UDF and "El Torito" partitions. # # Caution: This module requires additional review when modified. # This driver will have external input - disk partition. @@ -46,6 +46,7 @@ Mbr.c Gpt.c ElTorito.c + Udf.c Partition.c Partition.h =20 diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c b/MdeModulePkg/= Universal/Disk/PartitionDxe/Udf.c new file mode 100644 index 0000000000..c1d44809bf --- /dev/null +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c @@ -0,0 +1,318 @@ +/** @file + Scan for an UDF file system on a formatted media. + + Copyright (C) 2014-2017 Paulo Alcantara + + This program and the accompanying materials are licensed and made availa= ble + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WI= THOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include "Partition.h" + +// +// C5BD4D42-1A76-4996-8956-73CDA326CD0A +// +#define EFI_UDF_DEVICE_PATH_GUID \ + { 0xC5BD4D42, 0x1A76, 0x4996, \ + { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A } \ + } + +typedef struct { + VENDOR_DEVICE_PATH DevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} UDF_DEVICE_PATH; + +// +// Vendor-Defined Media Device Path for UDF file system +// +UDF_DEVICE_PATH gUdfDevicePath =3D { + { { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, + { sizeof (VENDOR_DEVICE_PATH), 0 } }, + EFI_UDF_DEVICE_PATH_GUID + }, + { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, + { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } + } +}; + +EFI_STATUS +FindAnchorVolumeDescriptorPointer ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + OUT UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint + ) +{ + EFI_STATUS Status; + UINT32 BlockSize =3D BlockIo->Media->BlockSize; + EFI_LBA EndLBA =3D BlockIo->Media->LastBlock; + EFI_LBA DescriptorLBAs[] =3D { 256, EndLBA - 256, EndLBA, 512 }; + UINTN Index; + + for (Index =3D 0; Index < ARRAY_SIZE (DescriptorLBAs); Index++) { + Status =3D DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + MultU64x32 (DescriptorLBAs[Index], BlockSize), + sizeof (UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER), + (VOID *)AnchorPoint + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Check if read LBA has a valid AVDP descriptor. + // + if (IS_AVDP (AnchorPoint)) { + return EFI_SUCCESS; + } + } + // + // No AVDP found. + // + return EFI_VOLUME_CORRUPTED; +} + +/** + Check if block device supports a valid UDF file system as specified by O= STA + Universal Disk Format Specification 2.60. + + @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. + +**/ +EFI_STATUS +SupportUdfFileSystem ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo + ) +{ + EFI_STATUS Status; + UINT64 Offset; + UINT64 EndDiskOffset; + CDROM_VOLUME_DESCRIPTOR VolDescriptor; + CDROM_VOLUME_DESCRIPTOR TerminatingVolDescriptor; + UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER AnchorPoint; + + ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIP= TOR)); + + // + // Start Volume Recognition Sequence + // + EndDiskOffset =3D MultU64x32 (BlockIo->Media->LastBlock, + BlockIo->Media->BlockSize); + + for (Offset =3D UDF_VRS_START_OFFSET; Offset < EndDiskOffset; + Offset +=3D UDF_LOGICAL_SECTOR_SIZE) { + // + // Check if block device has a Volume Structure Descriptor and an Exte= nded + // Area. + // + Status =3D DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + Offset, + sizeof (CDROM_VOLUME_DESCRIPTOR), + (VOID *)&VolDescriptor + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (CompareMem ((VOID *)VolDescriptor.Unknown.Id, + (VOID *)UDF_BEA_IDENTIFIER, + sizeof (VolDescriptor.Unknown.Id)) =3D=3D 0) { + break; + } + + if ((CompareMem ((VOID *)VolDescriptor.Unknown.Id, + (VOID *)CDVOL_ID, + sizeof (VolDescriptor.Unknown.Id)) !=3D 0) || + (CompareMem ((VOID *)&VolDescriptor, + (VOID *)&TerminatingVolDescriptor, + sizeof (CDROM_VOLUME_DESCRIPTOR)) =3D=3D 0)) { + return EFI_UNSUPPORTED; + } + } + + // + // Look for "NSR0{2,3}" identifiers in the Extended Area. + // + Offset +=3D UDF_LOGICAL_SECTOR_SIZE; + if (Offset >=3D EndDiskOffset) { + return EFI_UNSUPPORTED; + } + + Status =3D DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + Offset, + sizeof (CDROM_VOLUME_DESCRIPTOR), + (VOID *)&VolDescriptor + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if ((CompareMem ((VOID *)VolDescriptor.Unknown.Id, + (VOID *)UDF_NSR2_IDENTIFIER, + sizeof (VolDescriptor.Unknown.Id)) !=3D 0) && + (CompareMem ((VOID *)VolDescriptor.Unknown.Id, + (VOID *)UDF_NSR3_IDENTIFIER, + sizeof (VolDescriptor.Unknown.Id)) !=3D 0)) { + return EFI_UNSUPPORTED; + } + + // + // Look for "TEA01" identifier in the Extended Area + // + Offset +=3D UDF_LOGICAL_SECTOR_SIZE; + if (Offset >=3D EndDiskOffset) { + return EFI_UNSUPPORTED; + } + + Status =3D DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + Offset, + sizeof (CDROM_VOLUME_DESCRIPTOR), + (VOID *)&VolDescriptor + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (CompareMem ((VOID *)VolDescriptor.Unknown.Id, + (VOID *)UDF_TEA_IDENTIFIER, + sizeof (VolDescriptor.Unknown.Id)) !=3D 0) { + return EFI_UNSUPPORTED; + } + + Status =3D FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPo= int); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + Install child handles if the Handle supports UDF/ECMA-167 volume format. + + @param[in] This Calling context. + @param[in] Handle Parent Handle. + @param[in] DiskIo Parent DiskIo interface. + @param[in] DiskIo2 Parent DiskIo2 interface. + @param[in] BlockIo Parent BlockIo interface. + @param[in] BlockIo2 Parent BlockIo2 interface. + @param[in] DevicePath Parent Device Path + + + @retval EFI_SUCCESS Child handle(s) was added. + @retval EFI_MEDIA_CHANGED Media changed Detected. + @retval other no child handle was added. + +**/ +EFI_STATUS +PartitionInstallUdfChildHandles ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_DISK_IO2_PROTOCOL *DiskIo2, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_MEDIA *Media; + EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; + EFI_GUID *VendorDefinedGuid; + EFI_GUID UdfDevPathGuid =3D EFI_UDF_DEVICE_PATH_GUID; + EFI_PARTITION_INFO_PROTOCOL PartitionInfo; + + Media =3D BlockIo->Media; + + // + // Check if UDF logical block size is multiple of underlying device bloc= k size + // + if ((UDF_LOGICAL_SECTOR_SIZE % Media->BlockSize) !=3D 0 || + Media->BlockSize > UDF_LOGICAL_SECTOR_SIZE) { + return EFI_NOT_FOUND; + } + + 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, &UdfDevPathGuid)) { + return EFI_NOT_FOUND; + } + } + } + // + // Try next device path node + // + DevicePathNode =3D NextDevicePathNode (DevicePathNode); + } + + // + // Check if block device supports an UDF file system + // + Status =3D SupportUdfFileSystem (BlockIo, DiskIo); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // Create Partition Info protocol for UDF file system + // + ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL)); + PartitionInfo.Revision =3D EFI_PARTITION_INFO_PROTOCOL_REVISION; + PartitionInfo.Type =3D PARTITION_TYPE_OTHER; + + // + // Install partition child handle for UDF file system + // + Status =3D PartitionInstallChildHandle ( + This, + Handle, + DiskIo, + DiskIo2, + BlockIo, + BlockIo2, + DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath, + &PartitionInfo, + 0, + Media->LastBlock, + Media->BlockSize + ); + if (!EFI_ERROR (Status)) { + Status =3D EFI_NOT_FOUND; + } + + return Status; +} --=20 2.11.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel