MdeModulePkg: Remove the UDF/ECMA-167 file system support codes
The UDF feature is not ready for production. Remove it from the UDK2018 branch. This commit removes the UDF/ECMA-167 file system related code changes done within: MdeModulePkg/Universal/Disk/PartitionDxe/ MdeModulePkg/Universal/Disk/UdfDxe/ MdeModulePkg/MdeModulePkg.dsc Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Hao Wu <hao.a.wu@intel.com>
This commit is contained in:
@@ -349,7 +349,6 @@
|
|||||||
MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
|
MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
|
||||||
MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
|
MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
|
||||||
MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
|
MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
|
||||||
MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
|
|
||||||
MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
|
MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
|
||||||
MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
|
MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
|
||||||
MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
|
MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Partition driver that produces logical BlockIo devices from a physical
|
Partition driver that produces logical BlockIo devices from a physical
|
||||||
BlockIo device. The logical BlockIo devices are based on the format
|
BlockIo device. The logical BlockIo devices are based on the format
|
||||||
of the raw block devices media. Currently "El Torito CD-ROM", UDF, Legacy
|
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
|
||||||
MBR, and GPT partition schemes are supported.
|
MBR, and GPT partition schemes are supported.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
@@ -43,8 +43,8 @@ EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {
|
|||||||
//
|
//
|
||||||
PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {
|
PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {
|
||||||
PartitionInstallGptChildHandles,
|
PartitionInstallGptChildHandles,
|
||||||
|
PartitionInstallElToritoChildHandles,
|
||||||
PartitionInstallMbrChildHandles,
|
PartitionInstallMbrChildHandles,
|
||||||
PartitionInstallUdfChildHandles,
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -305,9 +305,9 @@ PartitionDriverBindingStart (
|
|||||||
if (BlockIo->Media->MediaPresent ||
|
if (BlockIo->Media->MediaPresent ||
|
||||||
(BlockIo->Media->RemovableMedia && !BlockIo->Media->LogicalPartition)) {
|
(BlockIo->Media->RemovableMedia && !BlockIo->Media->LogicalPartition)) {
|
||||||
//
|
//
|
||||||
// Try for GPT, then legacy MBR partition types, and then UDF and El Torito.
|
// Try for GPT, then El Torito, and then legacy MBR partition types. If the
|
||||||
// If the media supports a given partition type install child handles to
|
// media supports a given partition type install child handles to represent
|
||||||
// represent the partitions described by the media.
|
// the partitions described by the media.
|
||||||
//
|
//
|
||||||
Routine = &mPartitionDetectRoutineTable[0];
|
Routine = &mPartitionDetectRoutineTable[0];
|
||||||
while (*Routine != NULL) {
|
while (*Routine != NULL) {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Partition driver that produces logical BlockIo devices from a physical
|
Partition driver that produces logical BlockIo devices from a physical
|
||||||
BlockIo device. The logical BlockIo devices are based on the format
|
BlockIo device. The logical BlockIo devices are based on the format
|
||||||
of the raw block devices media. Currently "El Torito CD-ROM", UDF, Legacy
|
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
|
||||||
MBR, and GPT partition schemes are supported.
|
MBR, and GPT partition schemes are supported.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
@@ -39,7 +39,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
#include <IndustryStandard/Mbr.h>
|
#include <IndustryStandard/Mbr.h>
|
||||||
#include <IndustryStandard/ElTorito.h>
|
#include <IndustryStandard/ElTorito.h>
|
||||||
#include <IndustryStandard/Udf.h>
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Partition private data
|
// Partition private data
|
||||||
@@ -445,34 +445,6 @@ PartitionInstallMbrChildHandles (
|
|||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
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
|
typedef
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
(*PARTITION_DETECT_ROUTINE) (
|
(*PARTITION_DETECT_ROUTINE) (
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
# This module produces the logical Block I/O device that represents
|
# 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 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,
|
# The partition of physical BlockIo device supported is one of legacy MBR, GPT,
|
||||||
# UDF and "El Torito" partitions.
|
# and "El Torito" partitions.
|
||||||
#
|
#
|
||||||
# Caution: This module requires additional review when modified.
|
# Caution: This module requires additional review when modified.
|
||||||
# This driver will have external input - disk partition.
|
# This driver will have external input - disk partition.
|
||||||
@@ -46,7 +46,6 @@
|
|||||||
Mbr.c
|
Mbr.c
|
||||||
Gpt.c
|
Gpt.c
|
||||||
ElTorito.c
|
ElTorito.c
|
||||||
Udf.c
|
|
||||||
Partition.c
|
Partition.c
|
||||||
Partition.h
|
Partition.h
|
||||||
|
|
||||||
|
@@ -1,763 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Scan for an UDF file system on a formatted media.
|
|
||||||
|
|
||||||
Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
|
|
||||||
|
|
||||||
This program and the accompanying materials are licensed and made available
|
|
||||||
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, WITHOUT
|
|
||||||
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Partition.h"
|
|
||||||
|
|
||||||
#define MAX_CORRECTION_BLOCKS_NUM 512u
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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 Device Path GUID for UDF file system
|
|
||||||
//
|
|
||||||
EFI_GUID gUdfDevPathGuid = EFI_UDF_DEVICE_PATH_GUID;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Vendor-Defined Media Device Path for UDF file system
|
|
||||||
//
|
|
||||||
UDF_DEVICE_PATH gUdfDevicePath = {
|
|
||||||
{ { 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 }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Find the anchor volume descriptor pointer.
|
|
||||||
|
|
||||||
@param[in] BlockIo BlockIo interface.
|
|
||||||
@param[in] DiskIo DiskIo interface.
|
|
||||||
@param[out] AnchorPoint Anchor volume descriptor pointer.
|
|
||||||
@param[out] LastRecordedBlock Last recorded block.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Anchor volume descriptor pointer found.
|
|
||||||
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
|
|
||||||
@retval other Anchor volume descriptor pointer not found.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
FindAnchorVolumeDescriptorPointer (
|
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
|
||||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
|
||||||
OUT UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint,
|
|
||||||
OUT EFI_LBA *LastRecordedBlock
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
UINT32 BlockSize;
|
|
||||||
EFI_LBA EndLBA;
|
|
||||||
UDF_DESCRIPTOR_TAG *DescriptorTag;
|
|
||||||
UINTN AvdpsCount;
|
|
||||||
UINTN Size;
|
|
||||||
UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoints;
|
|
||||||
INTN Index;
|
|
||||||
UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPointPtr;
|
|
||||||
EFI_LBA LastAvdpBlockNum;
|
|
||||||
|
|
||||||
//
|
|
||||||
// UDF 2.60, 2.2.3 Anchor Volume Descriptor Pointer
|
|
||||||
//
|
|
||||||
// An Anchor Volume Descriptor Pointer structure shall be recorded in at
|
|
||||||
// least 2 of the following 3 locations on the media: Logical Sector 256,
|
|
||||||
// N - 256 or N, where N is the last *addressable* sector of a volume.
|
|
||||||
//
|
|
||||||
// To figure out what logical sector N is, the SCSI commands READ CAPACITY and
|
|
||||||
// READ TRACK INFORMATION are used, however many drives or medias report their
|
|
||||||
// "last recorded block" wrongly. Although, READ CAPACITY returns the last
|
|
||||||
// readable data block but there might be unwritten blocks, which are located
|
|
||||||
// outside any track and therefore AVDP will not be found at block N.
|
|
||||||
//
|
|
||||||
// That said, we define a magic number of 512 blocks to be used as correction
|
|
||||||
// when attempting to find AVDP and define last block number.
|
|
||||||
//
|
|
||||||
BlockSize = BlockIo->Media->BlockSize;
|
|
||||||
EndLBA = BlockIo->Media->LastBlock;
|
|
||||||
*LastRecordedBlock = EndLBA;
|
|
||||||
AvdpsCount = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Find AVDP at block 256
|
|
||||||
//
|
|
||||||
Status = DiskIo->ReadDisk (
|
|
||||||
DiskIo,
|
|
||||||
BlockIo->Media->MediaId,
|
|
||||||
MultU64x32 (256, BlockSize),
|
|
||||||
sizeof (*AnchorPoint),
|
|
||||||
AnchorPoint
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
DescriptorTag = &AnchorPoint->DescriptorTag;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if read block is a valid AVDP descriptor
|
|
||||||
//
|
|
||||||
if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
|
|
||||||
DEBUG ((DEBUG_INFO, "%a: found AVDP at block %d\n", __FUNCTION__, 256));
|
|
||||||
AvdpsCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Find AVDP at block N - 256
|
|
||||||
//
|
|
||||||
Status = DiskIo->ReadDisk (
|
|
||||||
DiskIo,
|
|
||||||
BlockIo->Media->MediaId,
|
|
||||||
MultU64x32 ((UINT64)EndLBA - 256, BlockSize),
|
|
||||||
sizeof (*AnchorPoint),
|
|
||||||
AnchorPoint
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if read block is a valid AVDP descriptor
|
|
||||||
//
|
|
||||||
if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer &&
|
|
||||||
++AvdpsCount == 2) {
|
|
||||||
DEBUG ((DEBUG_INFO, "%a: found AVDP at block %Ld\n", __FUNCTION__,
|
|
||||||
EndLBA - 256));
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if at least one AVDP was found in previous locations
|
|
||||||
//
|
|
||||||
if (AvdpsCount == 0) {
|
|
||||||
return EFI_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Find AVDP at block N
|
|
||||||
//
|
|
||||||
Status = DiskIo->ReadDisk (
|
|
||||||
DiskIo,
|
|
||||||
BlockIo->Media->MediaId,
|
|
||||||
MultU64x32 ((UINT64)EndLBA, BlockSize),
|
|
||||||
sizeof (*AnchorPoint),
|
|
||||||
AnchorPoint
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if read block is a valid AVDP descriptor
|
|
||||||
//
|
|
||||||
if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// No AVDP found at block N. Possibly drive/media returned bad last recorded
|
|
||||||
// block, or it is part of unwritten data blocks and outside any track.
|
|
||||||
//
|
|
||||||
// Search backwards for an AVDP from block N-1 through
|
|
||||||
// N-MAX_CORRECTION_BLOCKS_NUM. If any AVDP is found, then correct last block
|
|
||||||
// number for the new UDF partition child handle.
|
|
||||||
//
|
|
||||||
Size = MAX_CORRECTION_BLOCKS_NUM * BlockSize;
|
|
||||||
|
|
||||||
AnchorPoints = AllocateZeroPool (Size);
|
|
||||||
if (AnchorPoints == NULL) {
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read consecutive MAX_CORRECTION_BLOCKS_NUM disk blocks
|
|
||||||
//
|
|
||||||
Status = DiskIo->ReadDisk (
|
|
||||||
DiskIo,
|
|
||||||
BlockIo->Media->MediaId,
|
|
||||||
MultU64x32 ((UINT64)EndLBA - MAX_CORRECTION_BLOCKS_NUM, BlockSize),
|
|
||||||
Size,
|
|
||||||
AnchorPoints
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Out_Free;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_VOLUME_CORRUPTED;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Search for AVDP from blocks N-1 through N-MAX_CORRECTION_BLOCKS_NUM
|
|
||||||
//
|
|
||||||
for (Index = MAX_CORRECTION_BLOCKS_NUM - 2; Index >= 0; Index--) {
|
|
||||||
AnchorPointPtr = (VOID *)((UINTN)AnchorPoints + Index * BlockSize);
|
|
||||||
|
|
||||||
DescriptorTag = &AnchorPointPtr->DescriptorTag;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if read block is a valid AVDP descriptor
|
|
||||||
//
|
|
||||||
if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
|
|
||||||
//
|
|
||||||
// Calculate last recorded block number
|
|
||||||
//
|
|
||||||
LastAvdpBlockNum = EndLBA - (MAX_CORRECTION_BLOCKS_NUM - Index);
|
|
||||||
DEBUG ((DEBUG_WARN, "%a: found AVDP at block %Ld\n", __FUNCTION__,
|
|
||||||
LastAvdpBlockNum));
|
|
||||||
DEBUG ((DEBUG_WARN, "%a: correcting last block from %Ld to %Ld\n",
|
|
||||||
__FUNCTION__, EndLBA, LastAvdpBlockNum));
|
|
||||||
//
|
|
||||||
// Save read AVDP from last block
|
|
||||||
//
|
|
||||||
CopyMem (AnchorPoint, AnchorPointPtr, sizeof (*AnchorPointPtr));
|
|
||||||
//
|
|
||||||
// Set last recorded block number
|
|
||||||
//
|
|
||||||
*LastRecordedBlock = LastAvdpBlockNum;
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Out_Free:
|
|
||||||
FreePool (AnchorPoints);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Find UDF volume identifiers in a Volume Recognition Sequence.
|
|
||||||
|
|
||||||
@param[in] BlockIo BlockIo interface.
|
|
||||||
@param[in] DiskIo DiskIo interface.
|
|
||||||
|
|
||||||
@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
|
|
||||||
FindUdfVolumeIdentifiers (
|
|
||||||
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;
|
|
||||||
|
|
||||||
ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIPTOR));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Start Volume Recognition Sequence
|
|
||||||
//
|
|
||||||
EndDiskOffset = MultU64x32 (BlockIo->Media->LastBlock,
|
|
||||||
BlockIo->Media->BlockSize);
|
|
||||||
|
|
||||||
for (Offset = UDF_VRS_START_OFFSET; Offset < EndDiskOffset;
|
|
||||||
Offset += UDF_LOGICAL_SECTOR_SIZE) {
|
|
||||||
//
|
|
||||||
// Check if block device has a Volume Structure Descriptor and an Extended
|
|
||||||
// Area.
|
|
||||||
//
|
|
||||||
Status = 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)) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((CompareMem ((VOID *)VolDescriptor.Unknown.Id,
|
|
||||||
(VOID *)CDVOL_ID,
|
|
||||||
sizeof (VolDescriptor.Unknown.Id)) != 0) ||
|
|
||||||
(CompareMem ((VOID *)&VolDescriptor,
|
|
||||||
(VOID *)&TerminatingVolDescriptor,
|
|
||||||
sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Look for "NSR0{2,3}" identifiers in the Extended Area.
|
|
||||||
//
|
|
||||||
Offset += UDF_LOGICAL_SECTOR_SIZE;
|
|
||||||
if (Offset >= EndDiskOffset) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = 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)) != 0) &&
|
|
||||||
(CompareMem ((VOID *)VolDescriptor.Unknown.Id,
|
|
||||||
(VOID *)UDF_NSR3_IDENTIFIER,
|
|
||||||
sizeof (VolDescriptor.Unknown.Id)) != 0)) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Look for "TEA01" identifier in the Extended Area
|
|
||||||
//
|
|
||||||
Offset += UDF_LOGICAL_SECTOR_SIZE;
|
|
||||||
if (Offset >= EndDiskOffset) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = 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)) != 0) {
|
|
||||||
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[in] LastRecordedBlock Last recorded block in media.
|
|
||||||
@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,
|
|
||||||
IN EFI_LBA LastRecordedBlock,
|
|
||||||
OUT UINT64 *MainVdsStartBlock,
|
|
||||||
OUT UINT64 *MainVdsEndBlock
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
UINT32 BlockSize;
|
|
||||||
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;
|
|
||||||
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 > LastRecordedBlock + 1) {
|
|
||||||
return EFI_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check for valid Volume Descriptor Sequence starting block number
|
|
||||||
//
|
|
||||||
SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
|
|
||||||
if (SeqStartBlock > LastRecordedBlock ||
|
|
||||||
SeqStartBlock + SeqBlocksNum - 1 > LastRecordedBlock) {
|
|
||||||
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
|
|
||||||
// LastRecordedBlock.
|
|
||||||
//
|
|
||||||
*MainVdsEndBlock = LastRecordedBlock;
|
|
||||||
|
|
||||||
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;
|
|
||||||
EFI_LBA LastRecordedBlock;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Find UDF volume identifiers
|
|
||||||
//
|
|
||||||
Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Find Anchor Volume Descriptor Pointer
|
|
||||||
//
|
|
||||||
Status = FindAnchorVolumeDescriptorPointer (
|
|
||||||
BlockIo,
|
|
||||||
DiskIo,
|
|
||||||
&AnchorPoint,
|
|
||||||
&LastRecordedBlock
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Find Logical Volume location
|
|
||||||
//
|
|
||||||
Status = FindLogicalVolumeLocation (
|
|
||||||
BlockIo,
|
|
||||||
DiskIo,
|
|
||||||
&AnchorPoint,
|
|
||||||
LastRecordedBlock,
|
|
||||||
(UINT64 *)StartingLBA,
|
|
||||||
(UINT64 *)EndingLBA
|
|
||||||
);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
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
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 RemainderByMediaBlockSize;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_BLOCK_IO_MEDIA *Media;
|
|
||||||
EFI_PARTITION_INFO_PROTOCOL PartitionInfo;
|
|
||||||
EFI_LBA StartingLBA;
|
|
||||||
EFI_LBA EndingLBA;
|
|
||||||
BOOLEAN ChildCreated;
|
|
||||||
|
|
||||||
Media = BlockIo->Media;
|
|
||||||
ChildCreated = FALSE;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if UDF logical block size is multiple of underlying device block size
|
|
||||||
//
|
|
||||||
DivU64x32Remainder (
|
|
||||||
UDF_LOGICAL_SECTOR_SIZE, // Dividend
|
|
||||||
Media->BlockSize, // Divisor
|
|
||||||
&RemainderByMediaBlockSize // Remainder
|
|
||||||
);
|
|
||||||
if (RemainderByMediaBlockSize != 0) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Detect El Torito feature first.
|
|
||||||
// And always continue to search for UDF.
|
|
||||||
//
|
|
||||||
Status = PartitionInstallElToritoChildHandles (
|
|
||||||
This,
|
|
||||||
Handle,
|
|
||||||
DiskIo,
|
|
||||||
DiskIo2,
|
|
||||||
BlockIo,
|
|
||||||
BlockIo2,
|
|
||||||
DevicePath
|
|
||||||
);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
DEBUG ((DEBUG_INFO, "PartitionDxe: El Torito standard found on handle 0x%p.\n", Handle));
|
|
||||||
ChildCreated = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Search for an UDF file system on block device
|
|
||||||
//
|
|
||||||
Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return (ChildCreated ? EFI_SUCCESS : EFI_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create Partition Info protocol for UDF file system
|
|
||||||
//
|
|
||||||
ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL));
|
|
||||||
PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;
|
|
||||||
PartitionInfo.Type = PARTITION_TYPE_OTHER;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Install partition child handle for UDF file system
|
|
||||||
//
|
|
||||||
Status = PartitionInstallChildHandle (
|
|
||||||
This,
|
|
||||||
Handle,
|
|
||||||
DiskIo,
|
|
||||||
DiskIo2,
|
|
||||||
BlockIo,
|
|
||||||
BlockIo2,
|
|
||||||
DevicePath,
|
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
|
|
||||||
&PartitionInfo,
|
|
||||||
StartingLBA,
|
|
||||||
EndingLBA,
|
|
||||||
Media->BlockSize
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return (ChildCreated ? EFI_SUCCESS : Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
@@ -1,185 +0,0 @@
|
|||||||
/** @file
|
|
||||||
UEFI Component Name protocol for UDF/ECMA-167 file system driver.
|
|
||||||
|
|
||||||
Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
|
|
||||||
|
|
||||||
This program and the accompanying materials are licensed and made available
|
|
||||||
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, WITHOUT
|
|
||||||
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Udf.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// EFI Component Name Protocol
|
|
||||||
//
|
|
||||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUdfComponentName = {
|
|
||||||
UdfComponentNameGetDriverName,
|
|
||||||
UdfComponentNameGetControllerName,
|
|
||||||
"eng"
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// EFI Component Name 2 Protocol
|
|
||||||
//
|
|
||||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUdfComponentName2 = {
|
|
||||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UdfComponentNameGetDriverName,
|
|
||||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UdfComponentNameGetControllerName,
|
|
||||||
"en"
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Driver name table for Udf module.
|
|
||||||
// It is shared by the implementation of ComponentName & ComponentName2 Protocol.
|
|
||||||
//
|
|
||||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUdfDriverNameTable[] = {
|
|
||||||
{
|
|
||||||
"eng;en",
|
|
||||||
L"UDF File System Driver"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retrieves a Unicode string that is the user readable name of the driver.
|
|
||||||
|
|
||||||
This function retrieves the user readable name of a driver in the form of a
|
|
||||||
Unicode string. If the driver specified by This has a user readable name in
|
|
||||||
the language specified by Language, then a pointer to the driver name is
|
|
||||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
|
||||||
by This does not support the language specified by Language,
|
|
||||||
then EFI_UNSUPPORTED is returned.
|
|
||||||
|
|
||||||
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
|
||||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
|
||||||
|
|
||||||
@param Language[in] A pointer to a Null-terminated ASCII string
|
|
||||||
array indicating the language. This is the
|
|
||||||
language of the driver name that the caller is
|
|
||||||
requesting, and it must match one of the
|
|
||||||
languages specified in SupportedLanguages. The
|
|
||||||
number of languages supported by a driver is up
|
|
||||||
to the driver writer. Language is specified
|
|
||||||
in RFC 4646 or ISO 639-2 language code format.
|
|
||||||
|
|
||||||
@param DriverName[out] A pointer to the Unicode string to return.
|
|
||||||
This Unicode string is the name of the
|
|
||||||
driver specified by This in the language
|
|
||||||
specified by Language.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
|
||||||
This and the language specified by Language was
|
|
||||||
returned in DriverName.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
|
||||||
the language specified by Language.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfComponentNameGetDriverName (
|
|
||||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
||||||
IN CHAR8 *Language,
|
|
||||||
OUT CHAR16 **DriverName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return LookupUnicodeString2 (
|
|
||||||
Language,
|
|
||||||
This->SupportedLanguages,
|
|
||||||
mUdfDriverNameTable,
|
|
||||||
DriverName,
|
|
||||||
(BOOLEAN)(This == &gUdfComponentName)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retrieves a Unicode string that is the user readable name of the controller
|
|
||||||
that is being managed by a driver.
|
|
||||||
|
|
||||||
This function retrieves the user readable name of the controller specified by
|
|
||||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
|
||||||
driver specified by This has a user readable name in the language specified by
|
|
||||||
Language, then a pointer to the controller name is returned in ControllerName,
|
|
||||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
|
||||||
managing the controller specified by ControllerHandle and ChildHandle,
|
|
||||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
|
||||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
|
||||||
|
|
||||||
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
|
||||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
|
||||||
|
|
||||||
@param ControllerHandle[in] The handle of a controller that the driver
|
|
||||||
specified by This is managing. This handle
|
|
||||||
specifies the controller whose name is to be
|
|
||||||
returned.
|
|
||||||
|
|
||||||
@param ChildHandle[in] The handle of the child controller to retrieve
|
|
||||||
the name of. This is an optional parameter that
|
|
||||||
may be NULL. It will be NULL for device
|
|
||||||
drivers. It will also be NULL for a bus drivers
|
|
||||||
that wish to retrieve the name of the bus
|
|
||||||
controller. It will not be NULL for a bus
|
|
||||||
driver that wishes to retrieve the name of a
|
|
||||||
child controller.
|
|
||||||
|
|
||||||
@param Language[in] A pointer to a Null-terminated ASCII string
|
|
||||||
array indicating the language. This is the
|
|
||||||
language of the driver name that the caller is
|
|
||||||
requesting, and it must match one of the
|
|
||||||
languages specified in SupportedLanguages. The
|
|
||||||
number of languages supported by a driver is up
|
|
||||||
to the driver writer. Language is specified in
|
|
||||||
RFC 4646 or ISO 639-2 language code format.
|
|
||||||
|
|
||||||
@param ControllerName[out] A pointer to the Unicode string to return.
|
|
||||||
This Unicode string is the name of the
|
|
||||||
controller specified by ControllerHandle and
|
|
||||||
ChildHandle in the language specified by
|
|
||||||
Language from the point of view of the driver
|
|
||||||
specified by This.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The Unicode string for the user readable name in
|
|
||||||
the language specified by Language for the
|
|
||||||
driver specified by This was returned in
|
|
||||||
DriverName.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
|
||||||
EFI_HANDLE.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
|
||||||
|
|
||||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
|
||||||
managing the controller specified by
|
|
||||||
ControllerHandle and ChildHandle.
|
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
|
||||||
the language specified by Language.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfComponentNameGetControllerName (
|
|
||||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
|
||||||
IN CHAR8 *Language,
|
|
||||||
OUT CHAR16 **ControllerName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
@@ -1,904 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Handle operations in files and directories from UDF/ECMA-167 file systems.
|
|
||||||
|
|
||||||
Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
|
|
||||||
|
|
||||||
This program and the accompanying materials are licensed and made available
|
|
||||||
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, WITHOUT
|
|
||||||
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Udf.h"
|
|
||||||
|
|
||||||
EFI_FILE_PROTOCOL gUdfFileIoOps = {
|
|
||||||
EFI_FILE_PROTOCOL_REVISION,
|
|
||||||
UdfOpen,
|
|
||||||
UdfClose,
|
|
||||||
UdfDelete,
|
|
||||||
UdfRead,
|
|
||||||
UdfWrite,
|
|
||||||
UdfGetPosition,
|
|
||||||
UdfSetPosition,
|
|
||||||
UdfGetInfo,
|
|
||||||
UdfSetInfo,
|
|
||||||
UdfFlush,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
#define _ROOT_FILE(_PrivData) (_PrivData)->Root
|
|
||||||
#define _PARENT_FILE(_PrivData) \
|
|
||||||
((_PrivData)->IsRootDirectory ? (_PrivData)->Root : &(_PrivData)->File)
|
|
||||||
#define _FILE(_PrivData) _PARENT_FILE(_PrivData)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Open the root directory on a volume.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
@param Root Returns an Open file handle for the root directory
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device was opened.
|
|
||||||
@retval EFI_UNSUPPORTED This volume does not support the file system.
|
|
||||||
@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_ACCESS_DENIED The service denied access to the file.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
|
|
||||||
resources.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfOpenVolume (
|
|
||||||
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
|
|
||||||
OUT EFI_FILE_PROTOCOL **Root
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_TPL OldTpl;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
|
|
||||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
|
||||||
|
|
||||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
|
||||||
|
|
||||||
if (This == NULL || Root == NULL) {
|
|
||||||
Status = EFI_INVALID_PARAMETER;
|
|
||||||
goto Error_Invalid_Params;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (This);
|
|
||||||
|
|
||||||
if (PrivFsData->OpenFiles == 0) {
|
|
||||||
//
|
|
||||||
// There is no more open files. Read volume information again since it was
|
|
||||||
// cleaned up on the last UdfClose() call.
|
|
||||||
//
|
|
||||||
Status = ReadUdfVolumeInformation (
|
|
||||||
PrivFsData->BlockIo,
|
|
||||||
PrivFsData->DiskIo,
|
|
||||||
&PrivFsData->Volume
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Read_Udf_Volume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CleanupFileInformation (&PrivFsData->Root);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Find root directory file.
|
|
||||||
//
|
|
||||||
Status = FindRootDirectory (
|
|
||||||
PrivFsData->BlockIo,
|
|
||||||
PrivFsData->DiskIo,
|
|
||||||
&PrivFsData->Volume,
|
|
||||||
&PrivFsData->Root
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Find_Root_Dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData =
|
|
||||||
(PRIVATE_UDF_FILE_DATA *) AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA));
|
|
||||||
if (PrivFileData == NULL) {
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
goto Error_Alloc_Priv_File_Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData->Signature = PRIVATE_UDF_FILE_DATA_SIGNATURE;
|
|
||||||
PrivFileData->SimpleFs = This;
|
|
||||||
PrivFileData->Root = &PrivFsData->Root;
|
|
||||||
PrivFileData->IsRootDirectory = TRUE;
|
|
||||||
|
|
||||||
CopyMem ((VOID *)&PrivFileData->FileIo, (VOID *)&gUdfFileIoOps,
|
|
||||||
sizeof (EFI_FILE_PROTOCOL));
|
|
||||||
|
|
||||||
*Root = &PrivFileData->FileIo;
|
|
||||||
|
|
||||||
PrivFsData->OpenFiles++;
|
|
||||||
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
|
|
||||||
Error_Alloc_Priv_File_Data:
|
|
||||||
CleanupFileInformation (&PrivFsData->Root);
|
|
||||||
|
|
||||||
Error_Find_Root_Dir:
|
|
||||||
|
|
||||||
Error_Read_Udf_Volume:
|
|
||||||
Error_Invalid_Params:
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Opens a new file relative to the source file's location.
|
|
||||||
|
|
||||||
@param This The protocol instance pointer.
|
|
||||||
@param NewHandle Returns File Handle for FileName.
|
|
||||||
@param FileName Null terminated string. "\", ".", and ".." are supported.
|
|
||||||
@param OpenMode Open mode for file.
|
|
||||||
@param Attributes Only used for EFI_FILE_MODE_CREATE.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The device was opened.
|
|
||||||
@retval EFI_NOT_FOUND The specified file could not be found on the
|
|
||||||
device.
|
|
||||||
@retval EFI_NO_MEDIA The device has no media.
|
|
||||||
@retval EFI_MEDIA_CHANGED The media has changed.
|
|
||||||
@retval EFI_DEVICE_ERROR The device reported an error.
|
|
||||||
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
|
|
||||||
@retval EFI_ACCESS_DENIED The service denied access to the file.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
|
|
||||||
resources.
|
|
||||||
@retval EFI_VOLUME_FULL The volume is full.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfOpen (
|
|
||||||
IN EFI_FILE_PROTOCOL *This,
|
|
||||||
OUT EFI_FILE_PROTOCOL **NewHandle,
|
|
||||||
IN CHAR16 *FileName,
|
|
||||||
IN UINT64 OpenMode,
|
|
||||||
IN UINT64 Attributes
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_TPL OldTpl;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
|
||||||
PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
|
|
||||||
CHAR16 FilePath[UDF_PATH_LENGTH];
|
|
||||||
UDF_FILE_INFO File;
|
|
||||||
PRIVATE_UDF_FILE_DATA *NewPrivFileData;
|
|
||||||
CHAR16 *TempFileName;
|
|
||||||
|
|
||||||
ZeroMem (FilePath, sizeof FilePath);
|
|
||||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
|
||||||
|
|
||||||
if (This == NULL || NewHandle == NULL || FileName == NULL) {
|
|
||||||
Status = EFI_INVALID_PARAMETER;
|
|
||||||
goto Error_Invalid_Params;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpenMode != EFI_FILE_MODE_READ) {
|
|
||||||
Status = EFI_WRITE_PROTECTED;
|
|
||||||
goto Error_Invalid_Params;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
|
|
||||||
|
|
||||||
PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Build full path
|
|
||||||
//
|
|
||||||
if (*FileName == L'\\') {
|
|
||||||
StrCpyS (FilePath, UDF_PATH_LENGTH, FileName);
|
|
||||||
} else {
|
|
||||||
StrCpyS (FilePath, UDF_PATH_LENGTH, PrivFileData->AbsoluteFileName);
|
|
||||||
StrCatS (FilePath, UDF_PATH_LENGTH, L"\\");
|
|
||||||
StrCatS (FilePath, UDF_PATH_LENGTH, FileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
MangleFileName (FilePath);
|
|
||||||
if (FilePath[0] == L'\0') {
|
|
||||||
Status = EFI_NOT_FOUND;
|
|
||||||
goto Error_Bad_FileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = FindFile (
|
|
||||||
PrivFsData->BlockIo,
|
|
||||||
PrivFsData->DiskIo,
|
|
||||||
&PrivFsData->Volume,
|
|
||||||
FilePath,
|
|
||||||
_ROOT_FILE (PrivFileData),
|
|
||||||
_PARENT_FILE (PrivFileData),
|
|
||||||
&_PARENT_FILE(PrivFileData)->FileIdentifierDesc->Icb,
|
|
||||||
&File
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Find_File;
|
|
||||||
}
|
|
||||||
|
|
||||||
NewPrivFileData =
|
|
||||||
(PRIVATE_UDF_FILE_DATA *)AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA));
|
|
||||||
if (NewPrivFileData == NULL) {
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
goto Error_Alloc_New_Priv_File_Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
CopyMem ((VOID *)NewPrivFileData, (VOID *)PrivFileData,
|
|
||||||
sizeof (PRIVATE_UDF_FILE_DATA));
|
|
||||||
CopyMem ((VOID *)&NewPrivFileData->File, &File, sizeof (UDF_FILE_INFO));
|
|
||||||
|
|
||||||
NewPrivFileData->IsRootDirectory = FALSE;
|
|
||||||
|
|
||||||
StrCpyS (NewPrivFileData->AbsoluteFileName, UDF_PATH_LENGTH, FilePath);
|
|
||||||
FileName = NewPrivFileData->AbsoluteFileName;
|
|
||||||
|
|
||||||
while ((TempFileName = StrStr (FileName, L"\\")) != NULL) {
|
|
||||||
FileName = TempFileName + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
StrCpyS (NewPrivFileData->FileName, UDF_PATH_LENGTH, FileName);
|
|
||||||
|
|
||||||
Status = GetFileSize (
|
|
||||||
PrivFsData->BlockIo,
|
|
||||||
PrivFsData->DiskIo,
|
|
||||||
&PrivFsData->Volume,
|
|
||||||
&NewPrivFileData->File,
|
|
||||||
&NewPrivFileData->FileSize
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Get_File_Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
NewPrivFileData->FilePosition = 0;
|
|
||||||
ZeroMem ((VOID *)&NewPrivFileData->ReadDirInfo,
|
|
||||||
sizeof (UDF_READ_DIRECTORY_INFO));
|
|
||||||
|
|
||||||
*NewHandle = &NewPrivFileData->FileIo;
|
|
||||||
|
|
||||||
PrivFsData->OpenFiles++;
|
|
||||||
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
Error_Get_File_Size:
|
|
||||||
FreePool ((VOID *)NewPrivFileData);
|
|
||||||
|
|
||||||
Error_Alloc_New_Priv_File_Data:
|
|
||||||
CleanupFileInformation (&File);
|
|
||||||
|
|
||||||
Error_Find_File:
|
|
||||||
Error_Bad_FileName:
|
|
||||||
Error_Invalid_Params:
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Read data from the file.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
@param BufferSize On input size of buffer, on output amount of data in
|
|
||||||
buffer.
|
|
||||||
@param Buffer The buffer in which data is read.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Data was read.
|
|
||||||
@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_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains
|
|
||||||
required size.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfRead (
|
|
||||||
IN EFI_FILE_PROTOCOL *This,
|
|
||||||
IN OUT UINTN *BufferSize,
|
|
||||||
OUT VOID *Buffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_TPL OldTpl;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
|
||||||
PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
|
|
||||||
UDF_VOLUME_INFO *Volume;
|
|
||||||
UDF_FILE_INFO *Parent;
|
|
||||||
UDF_READ_DIRECTORY_INFO *ReadDirInfo;
|
|
||||||
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
|
||||||
EFI_DISK_IO_PROTOCOL *DiskIo;
|
|
||||||
UDF_FILE_INFO FoundFile;
|
|
||||||
UDF_FILE_IDENTIFIER_DESCRIPTOR *NewFileIdentifierDesc;
|
|
||||||
VOID *NewFileEntryData;
|
|
||||||
CHAR16 FileName[UDF_FILENAME_LENGTH];
|
|
||||||
UINT64 FileSize;
|
|
||||||
UINT64 BufferSizeUint64;
|
|
||||||
|
|
||||||
ZeroMem (FileName, sizeof FileName);
|
|
||||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
|
||||||
|
|
||||||
if (This == NULL || BufferSize == NULL || (*BufferSize != 0 &&
|
|
||||||
Buffer == NULL)) {
|
|
||||||
Status = EFI_INVALID_PARAMETER;
|
|
||||||
goto Error_Invalid_Params;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
|
|
||||||
PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);
|
|
||||||
|
|
||||||
BlockIo = PrivFsData->BlockIo;
|
|
||||||
DiskIo = PrivFsData->DiskIo;
|
|
||||||
Volume = &PrivFsData->Volume;
|
|
||||||
ReadDirInfo = &PrivFileData->ReadDirInfo;
|
|
||||||
NewFileIdentifierDesc = NULL;
|
|
||||||
NewFileEntryData = NULL;
|
|
||||||
|
|
||||||
Parent = _PARENT_FILE (PrivFileData);
|
|
||||||
|
|
||||||
Status = EFI_VOLUME_CORRUPTED;
|
|
||||||
|
|
||||||
if (IS_FID_NORMAL_FILE (Parent->FileIdentifierDesc)) {
|
|
||||||
if (PrivFileData->FilePosition > PrivFileData->FileSize) {
|
|
||||||
//
|
|
||||||
// File's position is beyond the EOF
|
|
||||||
//
|
|
||||||
Status = EFI_DEVICE_ERROR;
|
|
||||||
goto Error_File_Beyond_The_Eof;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PrivFileData->FilePosition == PrivFileData->FileSize) {
|
|
||||||
*BufferSize = 0;
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferSizeUint64 = *BufferSize;
|
|
||||||
|
|
||||||
Status = ReadFileData (
|
|
||||||
BlockIo,
|
|
||||||
DiskIo,
|
|
||||||
Volume,
|
|
||||||
Parent,
|
|
||||||
PrivFileData->FileSize,
|
|
||||||
&PrivFileData->FilePosition,
|
|
||||||
Buffer,
|
|
||||||
&BufferSizeUint64
|
|
||||||
);
|
|
||||||
ASSERT (BufferSizeUint64 <= MAX_UINTN);
|
|
||||||
*BufferSize = (UINTN)BufferSizeUint64;
|
|
||||||
} else if (IS_FID_DIRECTORY_FILE (Parent->FileIdentifierDesc)) {
|
|
||||||
if (ReadDirInfo->FidOffset == 0 && PrivFileData->FilePosition > 0) {
|
|
||||||
Status = EFI_DEVICE_ERROR;
|
|
||||||
*BufferSize = 0;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
Status = ReadDirectoryEntry (
|
|
||||||
BlockIo,
|
|
||||||
DiskIo,
|
|
||||||
Volume,
|
|
||||||
&Parent->FileIdentifierDesc->Icb,
|
|
||||||
Parent->FileEntry,
|
|
||||||
ReadDirInfo,
|
|
||||||
&NewFileIdentifierDesc
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
if (Status == EFI_DEVICE_ERROR) {
|
|
||||||
FreePool (ReadDirInfo->DirectoryData);
|
|
||||||
ZeroMem ((VOID *)ReadDirInfo, sizeof (UDF_READ_DIRECTORY_INFO));
|
|
||||||
|
|
||||||
*BufferSize = 0;
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IS_FID_PARENT_FILE (NewFileIdentifierDesc)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreePool ((VOID *)NewFileIdentifierDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = FindFileEntry (
|
|
||||||
BlockIo,
|
|
||||||
DiskIo,
|
|
||||||
Volume,
|
|
||||||
&NewFileIdentifierDesc->Icb,
|
|
||||||
&NewFileEntryData
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Find_Fe;
|
|
||||||
}
|
|
||||||
ASSERT (NewFileEntryData != NULL);
|
|
||||||
|
|
||||||
if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink) {
|
|
||||||
Status = ResolveSymlink (
|
|
||||||
BlockIo,
|
|
||||||
DiskIo,
|
|
||||||
Volume,
|
|
||||||
Parent,
|
|
||||||
NewFileEntryData,
|
|
||||||
&FoundFile
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Resolve_Symlink;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreePool ((VOID *)NewFileEntryData);
|
|
||||||
NewFileEntryData = FoundFile.FileEntry;
|
|
||||||
|
|
||||||
Status = GetFileNameFromFid (NewFileIdentifierDesc, FileName);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
FreePool ((VOID *)FoundFile.FileIdentifierDesc);
|
|
||||||
goto Error_Get_FileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreePool ((VOID *)NewFileIdentifierDesc);
|
|
||||||
NewFileIdentifierDesc = FoundFile.FileIdentifierDesc;
|
|
||||||
} else {
|
|
||||||
FoundFile.FileIdentifierDesc = NewFileIdentifierDesc;
|
|
||||||
FoundFile.FileEntry = NewFileEntryData;
|
|
||||||
|
|
||||||
Status = GetFileNameFromFid (FoundFile.FileIdentifierDesc, FileName);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Get_FileName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = GetFileSize (
|
|
||||||
BlockIo,
|
|
||||||
DiskIo,
|
|
||||||
Volume,
|
|
||||||
&FoundFile,
|
|
||||||
&FileSize
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Get_File_Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = SetFileInfo (
|
|
||||||
&FoundFile,
|
|
||||||
FileSize,
|
|
||||||
FileName,
|
|
||||||
BufferSize,
|
|
||||||
Buffer
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error_Set_File_Info;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData->FilePosition++;
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
} else if (IS_FID_DELETED_FILE (Parent->FileIdentifierDesc)) {
|
|
||||||
Status = EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error_Set_File_Info:
|
|
||||||
Error_Get_File_Size:
|
|
||||||
Error_Get_FileName:
|
|
||||||
Error_Resolve_Symlink:
|
|
||||||
if (NewFileEntryData != NULL) {
|
|
||||||
FreePool (NewFileEntryData);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error_Find_Fe:
|
|
||||||
if (NewFileIdentifierDesc != NULL) {
|
|
||||||
FreePool ((VOID *)NewFileIdentifierDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
Done:
|
|
||||||
Error_File_Beyond_The_Eof:
|
|
||||||
Error_Invalid_Params:
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Close the file handle.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The file was closed.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfClose (
|
|
||||||
IN EFI_FILE_PROTOCOL *This
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_TPL OldTpl;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
|
||||||
|
|
||||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
|
|
||||||
if (This == NULL) {
|
|
||||||
Status = EFI_INVALID_PARAMETER;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
|
|
||||||
|
|
||||||
if (!PrivFileData->IsRootDirectory) {
|
|
||||||
CleanupFileInformation (&PrivFileData->File);
|
|
||||||
|
|
||||||
if (PrivFileData->ReadDirInfo.DirectoryData != NULL) {
|
|
||||||
FreePool (PrivFileData->ReadDirInfo.DirectoryData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FreePool ((VOID *)PrivFileData);
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Close and delete the file handle.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The file was closed and deleted.
|
|
||||||
@retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not
|
|
||||||
deleted.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfDelete (
|
|
||||||
IN EFI_FILE_PROTOCOL *This
|
|
||||||
)
|
|
||||||
{
|
|
||||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
|
||||||
|
|
||||||
if (This == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
|
|
||||||
|
|
||||||
(VOID)PrivFileData->FileIo.Close(This);
|
|
||||||
|
|
||||||
return EFI_WARN_DELETE_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Write data to a file.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
@param BufferSize On input size of buffer, on output amount of data in
|
|
||||||
buffer.
|
|
||||||
@param Buffer The buffer in which data to write.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Data was written.
|
|
||||||
@retval EFI_UNSUPPORTED Writes to Open directory are not supported.
|
|
||||||
@retval EFI_NO_MEDIA The device has no media.
|
|
||||||
@retval EFI_DEVICE_ERROR The device reported an error.
|
|
||||||
@retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
|
|
||||||
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
|
|
||||||
@retval EFI_WRITE_PROTECTED The device is write protected.
|
|
||||||
@retval EFI_ACCESS_DENIED The file was open for read only.
|
|
||||||
@retval EFI_VOLUME_FULL The volume is full.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfWrite (
|
|
||||||
IN EFI_FILE_PROTOCOL *This,
|
|
||||||
IN OUT UINTN *BufferSize,
|
|
||||||
IN VOID *Buffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get file's current position.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
@param Position Byte position from the start of the file.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Position was updated.
|
|
||||||
@retval EFI_UNSUPPORTED Seek request for directories is not valid.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfGetPosition (
|
|
||||||
IN EFI_FILE_PROTOCOL *This,
|
|
||||||
OUT UINT64 *Position
|
|
||||||
)
|
|
||||||
{
|
|
||||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
|
||||||
|
|
||||||
if (This == NULL || Position == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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)) {
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// The file is not a directory. So, return its position.
|
|
||||||
//
|
|
||||||
*Position = PrivFileData->FilePosition;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set file's current position.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
@param Position Byte position from the start of the file.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Position was updated.
|
|
||||||
@retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfSetPosition (
|
|
||||||
IN EFI_FILE_PROTOCOL *This,
|
|
||||||
IN UINT64 Position
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
|
||||||
UDF_FILE_IDENTIFIER_DESCRIPTOR *FileIdentifierDesc;
|
|
||||||
|
|
||||||
if (This == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_UNSUPPORTED;
|
|
||||||
|
|
||||||
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
|
|
||||||
|
|
||||||
FileIdentifierDesc = _FILE (PrivFileData)->FileIdentifierDesc;
|
|
||||||
ASSERT (FileIdentifierDesc != NULL);
|
|
||||||
if (IS_FID_DIRECTORY_FILE (FileIdentifierDesc)) {
|
|
||||||
//
|
|
||||||
// If the file handle is a directory, the _only_ position that may be set is
|
|
||||||
// zero. This has no effect of starting the read proccess of the directory
|
|
||||||
// entries over.
|
|
||||||
//
|
|
||||||
if (Position == 0) {
|
|
||||||
PrivFileData->FilePosition = Position;
|
|
||||||
PrivFileData->ReadDirInfo.FidOffset = 0;
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
} else if (IS_FID_NORMAL_FILE (FileIdentifierDesc)) {
|
|
||||||
//
|
|
||||||
// Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to be
|
|
||||||
// set to the EOF.
|
|
||||||
//
|
|
||||||
if (Position == 0xFFFFFFFFFFFFFFFF) {
|
|
||||||
PrivFileData->FilePosition = PrivFileData->FileSize - 1;
|
|
||||||
} else {
|
|
||||||
PrivFileData->FilePosition = Position;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get information about a file.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
@param InformationType Type of information to return in Buffer.
|
|
||||||
@param BufferSize On input size of buffer, on output amount of data in
|
|
||||||
buffer.
|
|
||||||
@param Buffer The buffer to return data.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Data was returned.
|
|
||||||
@retval EFI_UNSUPPORTED InformationType is not supported.
|
|
||||||
@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_WRITE_PROTECTED The device is write protected.
|
|
||||||
@retval EFI_ACCESS_DENIED The file was open for read only.
|
|
||||||
@retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in
|
|
||||||
BufferSize.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfGetInfo (
|
|
||||||
IN EFI_FILE_PROTOCOL *This,
|
|
||||||
IN EFI_GUID *InformationType,
|
|
||||||
IN OUT UINTN *BufferSize,
|
|
||||||
OUT VOID *Buffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
PRIVATE_UDF_FILE_DATA *PrivFileData;
|
|
||||||
PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
|
|
||||||
EFI_FILE_SYSTEM_INFO *FileSystemInfo;
|
|
||||||
UINTN FileSystemInfoLength;
|
|
||||||
CHAR16 *String;
|
|
||||||
UDF_FILE_SET_DESCRIPTOR *FileSetDesc;
|
|
||||||
UINTN Index;
|
|
||||||
UINT8 *OstaCompressed;
|
|
||||||
UINT8 CompressionId;
|
|
||||||
UINT64 VolumeSize;
|
|
||||||
UINT64 FreeSpaceSize;
|
|
||||||
CHAR16 VolumeLabel[64];
|
|
||||||
|
|
||||||
if (This == NULL || InformationType == NULL || BufferSize == NULL ||
|
|
||||||
(*BufferSize != 0 && Buffer == NULL)) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
|
|
||||||
|
|
||||||
PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);
|
|
||||||
|
|
||||||
Status = EFI_UNSUPPORTED;
|
|
||||||
|
|
||||||
if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
|
|
||||||
Status = SetFileInfo (
|
|
||||||
_FILE (PrivFileData),
|
|
||||||
PrivFileData->FileSize,
|
|
||||||
PrivFileData->FileName,
|
|
||||||
BufferSize,
|
|
||||||
Buffer
|
|
||||||
);
|
|
||||||
} else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
|
|
||||||
String = VolumeLabel;
|
|
||||||
|
|
||||||
FileSetDesc = &PrivFsData->Volume.FileSetDesc;
|
|
||||||
|
|
||||||
OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
|
|
||||||
|
|
||||||
CompressionId = OstaCompressed[0];
|
|
||||||
if (!IS_VALID_COMPRESSION_ID (CompressionId)) {
|
|
||||||
return EFI_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Index = 1; Index < 128; Index++) {
|
|
||||||
if (CompressionId == 16) {
|
|
||||||
*String = *(UINT8 *)(OstaCompressed + Index) << 8;
|
|
||||||
Index++;
|
|
||||||
} else {
|
|
||||||
*String = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Index < 128) {
|
|
||||||
*String |= (CHAR16)(*(UINT8 *)(OstaCompressed + Index));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Unlike FID Identifiers, Logical Volume Identifier is stored in a
|
|
||||||
// NULL-terminated OSTA compressed format, so we must check for the NULL
|
|
||||||
// character.
|
|
||||||
//
|
|
||||||
if (*String == L'\0') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
String++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*String = L'\0';
|
|
||||||
|
|
||||||
FileSystemInfoLength = StrSize (VolumeLabel) +
|
|
||||||
sizeof (EFI_FILE_SYSTEM_INFO);
|
|
||||||
if (*BufferSize < FileSystemInfoLength) {
|
|
||||||
*BufferSize = FileSystemInfoLength;
|
|
||||||
return EFI_BUFFER_TOO_SMALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;
|
|
||||||
StrCpyS (FileSystemInfo->VolumeLabel, ARRAY_SIZE (VolumeLabel),
|
|
||||||
VolumeLabel);
|
|
||||||
Status = GetVolumeSize (
|
|
||||||
PrivFsData->BlockIo,
|
|
||||||
PrivFsData->DiskIo,
|
|
||||||
&PrivFsData->Volume,
|
|
||||||
&VolumeSize,
|
|
||||||
&FreeSpaceSize
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileSystemInfo->Size = FileSystemInfoLength;
|
|
||||||
FileSystemInfo->ReadOnly = TRUE;
|
|
||||||
FileSystemInfo->BlockSize =
|
|
||||||
PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
|
|
||||||
FileSystemInfo->VolumeSize = VolumeSize;
|
|
||||||
FileSystemInfo->FreeSpace = FreeSpaceSize;
|
|
||||||
|
|
||||||
*BufferSize = FileSystemInfoLength;
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set information about a file.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
@param InformationType Type of information in Buffer.
|
|
||||||
@param BufferSize Size of buffer.
|
|
||||||
@param Buffer The data to write.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Data was set.
|
|
||||||
@retval EFI_UNSUPPORTED InformationType is not supported.
|
|
||||||
@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_WRITE_PROTECTED The device is write protected.
|
|
||||||
@retval EFI_ACCESS_DENIED The file was open for read only.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfSetInfo (
|
|
||||||
IN EFI_FILE_PROTOCOL *This,
|
|
||||||
IN EFI_GUID *InformationType,
|
|
||||||
IN UINTN BufferSize,
|
|
||||||
IN VOID *Buffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return EFI_WRITE_PROTECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Flush data back for the file handle.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Data was flushed.
|
|
||||||
@retval EFI_UNSUPPORTED Writes to Open directory are not supported.
|
|
||||||
@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_WRITE_PROTECTED The device is write protected.
|
|
||||||
@retval EFI_ACCESS_DENIED The file was open for read only.
|
|
||||||
@retval EFI_VOLUME_FULL The volume is full.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfFlush (
|
|
||||||
IN EFI_FILE_PROTOCOL *This
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return EFI_WRITE_PROTECTED;
|
|
||||||
}
|
|
@@ -1,220 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Helper functions for mangling file names in UDF/ECMA-167 file systems.
|
|
||||||
|
|
||||||
Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
|
|
||||||
|
|
||||||
This program and the accompanying materials are licensed and made available
|
|
||||||
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, WITHOUT
|
|
||||||
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Udf.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Trim the leading and trailing spaces for a give Unicode string.
|
|
||||||
|
|
||||||
@param[in] String The Unicode string to trim.
|
|
||||||
|
|
||||||
@return A pointer to the trimmed string.
|
|
||||||
|
|
||||||
**/
|
|
||||||
CHAR16 *
|
|
||||||
TrimString (
|
|
||||||
IN CHAR16 *String
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CHAR16 *TempString;
|
|
||||||
|
|
||||||
for ( ; *String != L'\0' && *String == L' '; String++) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
TempString = String + StrLen (String) - 1;
|
|
||||||
while ((TempString >= String) && (*TempString == L' ')) {
|
|
||||||
TempString--;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(TempString + 1) = L'\0';
|
|
||||||
|
|
||||||
return String;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Replace the content of a Unicode string with the content of another Unicode
|
|
||||||
string.
|
|
||||||
|
|
||||||
@param[in] Destination A pointer to a Unicode string.
|
|
||||||
@param[in] Source A pointer to a Unicode string.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
ReplaceLeft (
|
|
||||||
IN CHAR16 *Destination,
|
|
||||||
IN CONST CHAR16 *Source
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CONST CHAR16 *EndString;
|
|
||||||
|
|
||||||
EndString = Source + StrLen (Source);
|
|
||||||
while (Source <= EndString) {
|
|
||||||
*Destination++ = *Source++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Remove one or more consecutive backslashes starting from the second character
|
|
||||||
of a given Unicode string.
|
|
||||||
|
|
||||||
@param[in] String A pointer to a Unicode string.
|
|
||||||
|
|
||||||
@return A pointer to the modified string.
|
|
||||||
|
|
||||||
**/
|
|
||||||
CHAR16 *
|
|
||||||
ExcludeTrailingBackslashes (
|
|
||||||
IN CHAR16 *String
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CHAR16 *TempString;
|
|
||||||
|
|
||||||
switch (*(String + 1)) {
|
|
||||||
case L'\\':
|
|
||||||
break;
|
|
||||||
case L'\0':
|
|
||||||
default:
|
|
||||||
String++;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
TempString = String;
|
|
||||||
while (*TempString != L'\0' && *TempString == L'\\') {
|
|
||||||
TempString++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TempString - 1 > String) {
|
|
||||||
ReplaceLeft (String + 1, TempString);
|
|
||||||
}
|
|
||||||
|
|
||||||
String++;
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
return String;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Mangle a filename by cutting off trailing whitespaces, "\\", "." and "..".
|
|
||||||
|
|
||||||
@param[in] FileName Filename.
|
|
||||||
|
|
||||||
@retval The mangled Filename.
|
|
||||||
|
|
||||||
**/
|
|
||||||
CHAR16 *
|
|
||||||
MangleFileName (
|
|
||||||
IN CHAR16 *FileName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CHAR16 *FileNameSavedPointer;
|
|
||||||
CHAR16 *TempFileName;
|
|
||||||
UINTN BackslashesNo;
|
|
||||||
|
|
||||||
if (FileName == NULL || *FileName == L'\0') {
|
|
||||||
FileName = NULL;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileName = TrimString (FileName);
|
|
||||||
if (*FileName == L'\0') {
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((StrLen (FileName) > 1) && (FileName[StrLen (FileName) - 1] == L'\\')) {
|
|
||||||
FileName[StrLen (FileName) - 1] = L'\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
FileNameSavedPointer = FileName;
|
|
||||||
|
|
||||||
if (FileName[0] == L'.') {
|
|
||||||
if (FileName[1] == L'.') {
|
|
||||||
if (FileName[2] == L'\0') {
|
|
||||||
goto Exit;
|
|
||||||
} else {
|
|
||||||
FileName += 2;
|
|
||||||
}
|
|
||||||
} else if (FileName[1] == L'\0') {
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*FileName != L'\0') {
|
|
||||||
if (*FileName == L'\\') {
|
|
||||||
FileName = ExcludeTrailingBackslashes (FileName);
|
|
||||||
} else if (*FileName == L'.') {
|
|
||||||
switch (*(FileName + 1)) {
|
|
||||||
case L'\0':
|
|
||||||
*FileName = L'\0';
|
|
||||||
break;
|
|
||||||
case L'\\':
|
|
||||||
TempFileName = FileName + 1;
|
|
||||||
TempFileName = ExcludeTrailingBackslashes (TempFileName);
|
|
||||||
ReplaceLeft (FileName, TempFileName);
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
if ((*(FileName - 1) != L'\\') && ((*(FileName + 2) != L'\\') ||
|
|
||||||
(*(FileName + 2) != L'\0'))) {
|
|
||||||
FileName++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BackslashesNo = 0;
|
|
||||||
TempFileName = FileName - 1;
|
|
||||||
while (TempFileName >= FileNameSavedPointer) {
|
|
||||||
if (*TempFileName == L'\\') {
|
|
||||||
if (++BackslashesNo == 2) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TempFileName--;
|
|
||||||
}
|
|
||||||
|
|
||||||
TempFileName++;
|
|
||||||
|
|
||||||
if ((*TempFileName == L'.') && (*(TempFileName + 1) == L'.')) {
|
|
||||||
FileName += 2;
|
|
||||||
} else {
|
|
||||||
if (*(FileName + 2) != L'\0') {
|
|
||||||
ReplaceLeft (TempFileName, FileName + 3);
|
|
||||||
if (*(TempFileName - 1) == L'\\') {
|
|
||||||
FileName = TempFileName;
|
|
||||||
ExcludeTrailingBackslashes (TempFileName - 1);
|
|
||||||
TempFileName = FileName;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*TempFileName = L'\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
FileName = TempFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FileName++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FileName++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileName = FileNameSavedPointer;
|
|
||||||
if ((StrLen (FileName) > 1) && (FileName [StrLen (FileName) - 1] == L'\\')) {
|
|
||||||
FileName [StrLen (FileName) - 1] = L'\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
return FileName;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@@ -1,337 +0,0 @@
|
|||||||
/** @file
|
|
||||||
UDF/ECMA-167 file system driver.
|
|
||||||
|
|
||||||
Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
|
|
||||||
|
|
||||||
This program and the accompanying materials are licensed and made available
|
|
||||||
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, WITHOUT
|
|
||||||
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "Udf.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// UDF filesystem driver's Global Variables.
|
|
||||||
//
|
|
||||||
EFI_DRIVER_BINDING_PROTOCOL gUdfDriverBinding = {
|
|
||||||
UdfDriverBindingSupported,
|
|
||||||
UdfDriverBindingStart,
|
|
||||||
UdfDriverBindingStop,
|
|
||||||
0x10,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gUdfSimpleFsTemplate = {
|
|
||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
|
|
||||||
UdfOpenVolume
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Test to see if this driver supports ControllerHandle. Any ControllerHandle
|
|
||||||
than contains a BlockIo and DiskIo protocol or a BlockIo2 protocol can be
|
|
||||||
supported.
|
|
||||||
|
|
||||||
@param[in] This Protocol instance pointer.
|
|
||||||
@param[in] ControllerHandle Handle of device to test.
|
|
||||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific
|
|
||||||
child device to start.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS This driver supports this device.
|
|
||||||
@retval EFI_ALREADY_STARTED This driver is already running on this device.
|
|
||||||
@retval other This driver does not support this device.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfDriverBindingSupported (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_DISK_IO_PROTOCOL *DiskIo;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Open DiskIo protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiDiskIoProtocolGuid,
|
|
||||||
(VOID **)&DiskIo,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Close DiskIo protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
gBS->CloseProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiDiskIoProtocolGuid,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Test whether ControllerHandle supports BlockIo protocol
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiBlockIoProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
|
||||||
);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start this driver on ControllerHandle by opening a Block IO or a Block IO2
|
|
||||||
or both, and Disk IO protocol, reading Device Path, and creating a child
|
|
||||||
handle with a Disk IO and device path protocol.
|
|
||||||
|
|
||||||
@param[in] This Protocol instance pointer.
|
|
||||||
@param[in] ControllerHandle Handle of device to bind driver to
|
|
||||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific
|
|
||||||
child device to start.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS This driver is added to ControllerHandle.
|
|
||||||
@retval EFI_ALREADY_STARTED This driver is already running on
|
|
||||||
ControllerHandle.
|
|
||||||
@retval other This driver does not support this device.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfDriverBindingStart (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_TPL OldTpl;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
|
||||||
EFI_DISK_IO_PROTOCOL *DiskIo;
|
|
||||||
PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
|
|
||||||
|
|
||||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Open BlockIo protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiBlockIoProtocolGuid,
|
|
||||||
(VOID **)&BlockIo,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Open DiskIo protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiDiskIoProtocolGuid,
|
|
||||||
(VOID **)&DiskIo,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if ControllerHandle supports an UDF file system
|
|
||||||
//
|
|
||||||
Status = SupportUdfFileSystem (This, ControllerHandle);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize private file system structure
|
|
||||||
//
|
|
||||||
PrivFsData =
|
|
||||||
(PRIVATE_UDF_SIMPLE_FS_DATA *)
|
|
||||||
AllocateZeroPool (sizeof (PRIVATE_UDF_SIMPLE_FS_DATA));
|
|
||||||
if (PrivFsData == NULL) {
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create new child handle
|
|
||||||
//
|
|
||||||
PrivFsData->Signature = PRIVATE_UDF_SIMPLE_FS_DATA_SIGNATURE;
|
|
||||||
PrivFsData->BlockIo = BlockIo;
|
|
||||||
PrivFsData->DiskIo = DiskIo;
|
|
||||||
PrivFsData->Handle = ControllerHandle;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set up SimpleFs protocol
|
|
||||||
//
|
|
||||||
CopyMem ((VOID *)&PrivFsData->SimpleFs, (VOID *)&gUdfSimpleFsTemplate,
|
|
||||||
sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Install child handle
|
|
||||||
//
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
||||||
&PrivFsData->Handle,
|
|
||||||
&gEfiSimpleFileSystemProtocolGuid,
|
|
||||||
&PrivFsData->SimpleFs,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
//
|
|
||||||
// Close DiskIo protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
gBS->CloseProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiDiskIoProtocolGuid,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle
|
|
||||||
);
|
|
||||||
//
|
|
||||||
// Close BlockIo protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
gBS->CloseProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiBlockIoProtocolGuid,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Stop this driver on ControllerHandle. Support stopping any child handles
|
|
||||||
created by this driver.
|
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
|
||||||
@param ControllerHandle Handle of device to stop driver on
|
|
||||||
@param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
|
|
||||||
children is zero stop the entire bus driver.
|
|
||||||
@param ChildHandleBuffer List of Child Handles to Stop.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS This driver is removed ControllerHandle
|
|
||||||
@retval other This driver was not removed from this device
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UdfDriverBindingStop (
|
|
||||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN UINTN NumberOfChildren,
|
|
||||||
IN EFI_HANDLE *ChildHandleBuffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Open SimpleFs protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
Status = gBS->OpenProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiSimpleFileSystemProtocolGuid,
|
|
||||||
(VOID **)&SimpleFs,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
||||||
);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (SimpleFs);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Uninstall child handle
|
|
||||||
//
|
|
||||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
|
||||||
PrivFsData->Handle,
|
|
||||||
&gEfiSimpleFileSystemProtocolGuid,
|
|
||||||
&PrivFsData->SimpleFs,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
FreePool ((VOID *)PrivFsData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
//
|
|
||||||
// Close DiskIo protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
gBS->CloseProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiDiskIoProtocolGuid,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle
|
|
||||||
);
|
|
||||||
//
|
|
||||||
// Close BlockIo protocol on ControllerHandle
|
|
||||||
//
|
|
||||||
gBS->CloseProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiBlockIoProtocolGuid,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
The user Entry Point for UDF file system driver. The user code starts with
|
|
||||||
this function.
|
|
||||||
|
|
||||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
|
||||||
@param[in] SystemTable A pointer to the EFI System Table.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The entry point is executed successfully.
|
|
||||||
@retval other Some error occurs when executing this entry point.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
InitializeUdf (
|
|
||||||
IN EFI_HANDLE ImageHandle,
|
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
Status = EfiLibInstallDriverBindingComponentName2 (
|
|
||||||
ImageHandle,
|
|
||||||
SystemTable,
|
|
||||||
&gUdfDriverBinding,
|
|
||||||
ImageHandle,
|
|
||||||
&gUdfComponentName,
|
|
||||||
&gUdfComponentName2
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@@ -1,66 +0,0 @@
|
|||||||
## @file
|
|
||||||
# UDF/ECMA-167 file system driver.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
|
|
||||||
#
|
|
||||||
# This program and the accompanying materials
|
|
||||||
# are licensed and made available 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,
|
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
##
|
|
||||||
|
|
||||||
[Defines]
|
|
||||||
INF_VERSION = 0x00010005
|
|
||||||
BASE_NAME = UdfDxe
|
|
||||||
FILE_GUID = 905f13b0-8f91-4b0a-bd76-e1e78f9422e4
|
|
||||||
MODULE_TYPE = UEFI_DRIVER
|
|
||||||
VERSION_STRING = 1.0
|
|
||||||
ENTRY_POINT = InitializeUdf
|
|
||||||
|
|
||||||
#
|
|
||||||
# The following information is for reference only and not required by the build tools.
|
|
||||||
#
|
|
||||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
|
||||||
#
|
|
||||||
# DRIVER_BINDING = gUdfDriverBinding
|
|
||||||
# COMPONENT_NAME = gUdfComponentName
|
|
||||||
# COMPONENT_NAME2 = gUdfComponentName2
|
|
||||||
#
|
|
||||||
|
|
||||||
[Sources]
|
|
||||||
ComponentName.c
|
|
||||||
FileSystemOperations.c
|
|
||||||
FileName.c
|
|
||||||
File.c
|
|
||||||
Udf.c
|
|
||||||
Udf.h
|
|
||||||
|
|
||||||
|
|
||||||
[Packages]
|
|
||||||
MdePkg/MdePkg.dec
|
|
||||||
|
|
||||||
|
|
||||||
[LibraryClasses]
|
|
||||||
DevicePathLib
|
|
||||||
UefiBootServicesTableLib
|
|
||||||
MemoryAllocationLib
|
|
||||||
BaseMemoryLib
|
|
||||||
UefiLib
|
|
||||||
BaseLib
|
|
||||||
UefiDriverEntryPoint
|
|
||||||
DebugLib
|
|
||||||
|
|
||||||
|
|
||||||
[Guids]
|
|
||||||
gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## Protocol
|
|
||||||
gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## Protocol
|
|
||||||
|
|
||||||
|
|
||||||
[Protocols]
|
|
||||||
gEfiSimpleFileSystemProtocolGuid ## BY_START
|
|
||||||
gEfiDevicePathProtocolGuid ## BY_START
|
|
||||||
gEfiBlockIoProtocolGuid ## TO_START
|
|
||||||
gEfiDiskIoProtocolGuid ## TO_START
|
|
Reference in New Issue
Block a user