This patch contains basic support to detect UDF volumes on available discs and then install new child handles that layer on devices that provide EFI_BLOCK_IO_PROTOCOL/EFI_DISK_IO_PROTOCOL in them.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Paulo Alcantara <pca...@zytor.com> --- MdeModulePkg/MdeModulePkg.dsc | 1 + MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c | 185 +++++ .../Universal/Disk/UdfDxe/FileSystemOperations.c | 763 ++++++++++++++++++ MdeModulePkg/Universal/Disk/UdfDxe/Udf.c | 349 ++++++++ MdeModulePkg/Universal/Disk/UdfDxe/Udf.h | 879 +++++++++++++++++++++ MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf | 63 ++ 6 files changed, 2240 insertions(+) create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 60edd99..411008d 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -270,6 +270,7 @@ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf + MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf MdeModulePkg/Universal/MemoryTest/GenericMemoryTestDxe/GenericMemoryTestDxe.inf diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c b/MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c new file mode 100644 index 0000000..32fd600 --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c @@ -0,0 +1,185 @@ +/** @file + UEFI Component Name protocol for UDF filesystem driver. + +Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR> +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 Filesystem 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; +} diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c new file mode 100644 index 0000000..5492494 --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c @@ -0,0 +1,763 @@ +/** @file + UDF filesystem driver. + +Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR> +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_STANDARD_IDENTIFIER gUdfStandardIdentifiers[STANDARD_IDENTIFIERS_NO] = { + { { 'B', 'E', 'A', '0', '1' } }, + { { 'N', 'S', 'R', '0', '2' } }, + { { 'N', 'S', 'R', '0', '3' } }, + { { 'T', 'E', 'A', '0', '1' } }, +}; + +/** + 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; + UDF_PARTITION_DESCRIPTOR PartitionDesc; + UDF_LOGICAL_VOLUME_DESCRIPTOR LogicalVolDesc; + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (This); + + PrivFileData = AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA)); + if (!PrivFileData) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + Status = FindRootDirectory ( + PrivFsData->BlockIo, + PrivFsData->DiskIo, + &PartitionDesc, + &LogicalVolDesc, + &PrivFileData->Root.FileEntry, + &PrivFileData->Root.FileIdentifierDesc + ); + if (EFI_ERROR (Status)) { + goto FreeExit; + } + + PrivFileData->Partition.StartingLocation = + PartitionDesc.PartitionStartingLocation; + PrivFileData->Partition.Length = + PartitionDesc.PartitionLength; + PrivFileData->Partition.AccessType = PartitionDesc.AccessType; + + CopyMem ( + (VOID *)&PrivFileData->Volume.Identifier, + (VOID *)&LogicalVolDesc.LogicalVolumeIdentifier, + LOGICAL_VOLUME_IDENTIFIER_LENGTH + ); + + PrivFileData->Signature = PRIVATE_UDF_FILE_DATA_SIGNATURE; + PrivFileData->SimpleFs = This; + PrivFileData->BlockIo = PrivFsData->BlockIo; + PrivFileData->DiskIo = PrivFsData->DiskIo; + + PrivFileData->FileIo.Revision = EFI_FILE_PROTOCOL_REVISION; + PrivFileData->FileIo.Open = UdfOpen; + PrivFileData->FileIo.Close = UdfClose; + PrivFileData->FileIo.Delete = UdfDelete; + PrivFileData->FileIo.Read = UdfRead; + PrivFileData->FileIo.Write = UdfWrite; + PrivFileData->FileIo.GetPosition = UdfGetPosition; + PrivFileData->FileIo.SetPosition = UdfSetPosition; + PrivFileData->FileIo.GetInfo = UdfGetInfo; + PrivFileData->FileIo.SetInfo = UdfSetInfo; + PrivFileData->FileIo.Flush = UdfFlush; + + PrivFileData->IsRootDirectory = TRUE; + PrivFileData->FilePosition = 0; + PrivFileData->NextEntryOffset = 0; + + *Root = &PrivFileData->FileIo; + +Exit: + gBS->RestoreTPL (OldTpl); + + return Status; + +FreeExit: + FreePool ((VOID *)PrivFileData); + + 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 + ) +{ + return EFI_DEVICE_ERROR; +} + +/** + 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 + ) +{ + return EFI_DEVICE_ERROR; +} + +/** + 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 + ) +{ + return EFI_SUCCESS; +} + +/** + 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 + ) +{ + 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 a 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 + ) +{ + return EFI_UNSUPPORTED; +} + +/** + 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 + ) +{ + return EFI_UNSUPPORTED; +} + +/** + 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 + ) +{ + return EFI_DEVICE_ERROR; +} + +/** + Set information about a file + + @param File 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; +} + +STATIC +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; + + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + FIRST_ANCHOR_POINT_LSN * LOGICAL_SECTOR_SIZE, + sizeof (UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER), + (VOID *)AnchorPoint + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + // + // TODO: In case of failure, look for the other AVDPs at N or N - 256 + // + if (!IS_AVDP (AnchorPoint)) { + Status = EFI_VOLUME_CORRUPTED; + goto Exit; + } + +Exit: + return Status; +} + +STATIC +EFI_STATUS +StartMainVolumeDescriptorSequence ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint, + OUT UDF_PARTITION_DESCRIPTOR *PartitionDesc, + OUT UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc + ) +{ + EFI_STATUS Status; + UDF_EXTENT_AD *ExtentAd; + UINT32 StartingLsn; + UINT32 EndingLsn; + UINT8 Buffer[LOGICAL_SECTOR_SIZE]; + + ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent; + + if (ExtentAd->ExtentLength / LOGICAL_SECTOR_SIZE < 16) { + Status = EFI_VOLUME_CORRUPTED; + goto Exit; + } + + // + // Start Main Volume Descriptor Sequence + // + // ==> Primary Volume Descriptor + // ==> Implementation Use Volume Descriptor + // ==> Partition Descriptor + // ==> Logical Volume Descriptor + // ==> Unallocated Space Descriptor + // ==> Terminating Descriptor + // ==> if any, Trailing Logical Sectors + // + StartingLsn = ExtentAd->ExtentLocation; + EndingLsn = StartingLsn + (ExtentAd->ExtentLength / LOGICAL_SECTOR_SIZE); + + while (StartingLsn <= EndingLsn) { + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + StartingLsn * LOGICAL_SECTOR_SIZE, + LOGICAL_SECTOR_SIZE, + (VOID *)&Buffer + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + // + // Stop VDS when found Terminating Descriptor + // + if (IS_TD (Buffer)) { + break; + } + + if (IS_PD (Buffer)) { + CopyMem ( + (VOID *)PartitionDesc, + (VOID *)&Buffer, + sizeof (UDF_PARTITION_DESCRIPTOR) + ); + } else if (IS_LVD (Buffer)) { + CopyMem ( + (VOID *)LogicalVolDesc, + (VOID *)&Buffer, + sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR) + ); + } + + StartingLsn++; + } + +Exit: + return Status; +} + +STATIC +EFI_STATUS +FindFileSetDescriptor ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN UDF_PARTITION_DESCRIPTOR *PartitionDesc, + IN UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc, + OUT UDF_FILE_SET_DESCRIPTOR *FileSetDesc + ) +{ + EFI_STATUS Status; + UDF_LONG_ALLOCATION_DESCRIPTOR *LongAd; + UINT64 Lsn; + + LongAd = &LogicalVolDesc->LogicalVolumeContentsUse; + + Lsn = (UINT64)(PartitionDesc->PartitionStartingLocation + + LongAd->ExtentLocation.LogicalBlockNumber); + + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + Lsn * LOGICAL_BLOCK_SIZE, + sizeof (UDF_FILE_SET_DESCRIPTOR), + (VOID *)FileSetDesc + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + if (!IS_FSD (FileSetDesc)) { + Status = EFI_VOLUME_CORRUPTED; + } + +Exit: + return Status; +} + +STATIC +EFI_STATUS +FindFileEntryRootDirectory ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN UDF_PARTITION_DESCRIPTOR *PartitionDesc, + IN UDF_FILE_SET_DESCRIPTOR *FileSetDesc, + OUT UDF_FILE_ENTRY *FileEntry + ) +{ + EFI_STATUS Status; + UDF_LONG_ALLOCATION_DESCRIPTOR *LongAd; + UINT64 Lsn; + + LongAd = &FileSetDesc->RootDirectoryIcb; + + Lsn = (UINT64)(PartitionDesc->PartitionStartingLocation + + LongAd->ExtentLocation.LogicalBlockNumber); + + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + Lsn * LOGICAL_BLOCK_SIZE, + sizeof (UDF_FILE_ENTRY), + (VOID *)FileEntry + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + if (!IS_FE (FileEntry)) { + Status = EFI_VOLUME_CORRUPTED; + goto Exit; + } + + // + // Root Directory cannot be file, obivously. Check its file type. + // + if (!IS_FE_DIRECTORY (FileEntry)) { + Status = EFI_VOLUME_CORRUPTED; + } + +Exit: + return Status; +} + +EFI_STATUS +FindFileIdentifierDescriptorRootDirectory ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN UDF_PARTITION_DESCRIPTOR *PartitionDesc, + IN UDF_FILE_SET_DESCRIPTOR *FileSetDesc, + OUT UDF_FILE_IDENTIFIER_DESCRIPTOR *FileIdentifierDesc + ) +{ + UDF_LONG_ALLOCATION_DESCRIPTOR *LongAd; + EFI_STATUS Status; + UINT64 Lsn; + + LongAd = &FileSetDesc->RootDirectoryIcb; + + // + // TODO: Handle strategy type of 4096 as well. + // + // For ICB strategy type of 4, the File Identifier Descriptor of the Root + // Directory immediately follows the File Entry (Root Directory). + // + Lsn = (UINT64)(PartitionDesc->PartitionStartingLocation + + LongAd->ExtentLocation.LogicalBlockNumber + 1); + + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + Lsn * LOGICAL_BLOCK_SIZE, + LOGICAL_BLOCK_SIZE, + (VOID *)FileIdentifierDesc + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + if (!IS_FID (FileIdentifierDesc)) { + Status = EFI_VOLUME_CORRUPTED; + } + +Exit: + return Status; +} + +EFI_STATUS +EFIAPI +FindRootDirectory ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + OUT UDF_PARTITION_DESCRIPTOR *PartitionDesc, + OUT UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc, + OUT UDF_FILE_ENTRY *FileEntry, + OUT UDF_FILE_IDENTIFIER_DESCRIPTOR *FileIdentifierDesc + ) +{ + EFI_STATUS Status; + UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER AnchorPoint; + UDF_FILE_SET_DESCRIPTOR FileSetDesc; + + Status = FindAnchorVolumeDescriptorPointer ( + BlockIo, + DiskIo, + &AnchorPoint + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + Status = StartMainVolumeDescriptorSequence ( + BlockIo, + DiskIo, + &AnchorPoint, + PartitionDesc, + LogicalVolDesc + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + Status = FindFileSetDescriptor ( + BlockIo, + DiskIo, + PartitionDesc, + LogicalVolDesc, + &FileSetDesc + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + Status = FindFileEntryRootDirectory ( + BlockIo, + DiskIo, + PartitionDesc, + &FileSetDesc, + FileEntry + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + Status = FindFileIdentifierDescriptorRootDirectory ( + BlockIo, + DiskIo, + PartitionDesc, + &FileSetDesc, + FileIdentifierDesc + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + +Exit: + return Status; +} + +EFI_STATUS +IsSupportedUdfVolume ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + OUT BOOLEAN *Supported + ) +{ + EFI_STATUS Status; + UDF_NSR_DESCRIPTOR NsrDescriptor; + + *Supported = FALSE; + + // + // Start Volume Recognition Sequence + // + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + BEA_DESCRIPTOR_LSN * LOGICAL_SECTOR_SIZE, + sizeof (UDF_NSR_DESCRIPTOR), + (VOID *)&NsrDescriptor + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + if (CompareMem ( + (VOID *)&NsrDescriptor.StandardIdentifier, + (VOID *)&gUdfStandardIdentifiers[BEA_IDENTIFIER], + UDF_STANDARD_IDENTIFIER_LENGTH + ) + ) { + goto Exit; + } + + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + (BEA_DESCRIPTOR_LSN + 1) * LOGICAL_SECTOR_SIZE, + sizeof (UDF_NSR_DESCRIPTOR), + (VOID *)&NsrDescriptor + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + if ((CompareMem ( + (VOID *)&NsrDescriptor.StandardIdentifier, + (VOID *)&gUdfStandardIdentifiers[VSD_IDENTIFIER_0], + UDF_STANDARD_IDENTIFIER_LENGTH + ) + ) && + (CompareMem ( + (VOID *)&NsrDescriptor.StandardIdentifier, + (VOID *)&gUdfStandardIdentifiers[VSD_IDENTIFIER_1], + UDF_STANDARD_IDENTIFIER_LENGTH + ) + ) + ) { + goto Exit; + } + + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + (BEA_DESCRIPTOR_LSN + 2) * LOGICAL_SECTOR_SIZE, + sizeof (UDF_NSR_DESCRIPTOR), + (VOID *)&NsrDescriptor + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + if (CompareMem ( + (VOID *)&NsrDescriptor.StandardIdentifier, + (VOID *)&gUdfStandardIdentifiers[TEA_IDENTIFIER], + UDF_STANDARD_IDENTIFIER_LENGTH + ) + ) { + goto Exit; + } + + *Supported = TRUE; + +Exit: + return Status; +} diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c new file mode 100644 index 0000000..99fada0 --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c @@ -0,0 +1,349 @@ +/** @file + UDF filesystem driver. + +Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR> +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, + 0x0000000BUL, + NULL, + NULL +}; + +UDF_DEVICE_PATH gUdfDriverDevicePath = { + { + { 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 + } + } +}; + +/** + 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; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + (VOID **)&DiskIo, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + Status = EFI_SUCCESS; + goto Exit; + } + + if (EFI_ERROR (Status)) { + goto Exit; + } + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + NULL, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + +Exit: + 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; + BOOLEAN IsUdfVolume; + PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData; + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + (VOID **)&BlockIo, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + (VOID **)&DiskIo, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status == EFI_ALREADY_STARTED) { + goto Exit; + } + + // + // Check if media contains a valid UDF volume + // + Status = IsSupportedUdfVolume ( + BlockIo, + DiskIo, + &IsUdfVolume + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + if (!IsUdfVolume) { + Status = EFI_UNSUPPORTED; + goto Exit; + } + + PrivFsData = AllocateZeroPool (sizeof (PRIVATE_UDF_SIMPLE_FS_DATA)); + if (!PrivFsData) { + 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->SimpleFs.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + PrivFsData->SimpleFs.OpenVolume = UdfOpenVolume; + + PrivFsData->DevicePath = + DuplicateDevicePath ( + (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDriverDevicePath + ); + PrivFsData->Handle = NULL; + + // + // Install new child handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &PrivFsData->Handle, + &gEfiSimpleFileSystemProtocolGuid, + &PrivFsData->SimpleFs, + &gEfiDevicePathProtocolGuid, + PrivFsData->DevicePath, + NULL + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + +Exit: + 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 + ) +{ + UINTN Index; + PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData; + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs; + EFI_DISK_IO_PROTOCOL *DiskIo; + BOOLEAN Done; + + Status = EFI_SUCCESS; + + if (!NumberOfChildren) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + goto Exit; + } + + Done = TRUE; + + for (Index = 0; Index < NumberOfChildren; Index++) { + gBS->OpenProtocol ( + ChildHandleBuffer[Index], + &gEfiSimpleFileSystemProtocolGuid, + (VOID **)&SimpleFs, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (This); + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + ChildHandleBuffer[Index], + &gEfiDevicePathProtocolGuid, + PrivFsData->DevicePath, + &gEfiSimpleFileSystemProtocolGuid, + &PrivFsData->SimpleFs, + NULL, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + (VOID **)&DiskIo, + This->DriverBindingHandle, + ChildHandleBuffer[Index], + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + } else { + FreePool ((VOID *)PrivFsData->DevicePath); + FreePool ((VOID *)PrivFsData); + } + + if (EFI_ERROR (Status)) { + Done = FALSE; + } + } + + if (!Done) { + Status = EFI_DEVICE_ERROR; + } + +Exit: + return Status; +} + +/** + The user Entry Point for UDF filesystem 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; +} diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h new file mode 100644 index 0000000..7986445 --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h @@ -0,0 +1,879 @@ +/** @file + UDF filesystem driver. + +Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR> +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. + +**/ + +#ifndef _UDF_H_ +#define _UDF_H_ + +#include <Uefi.h> + +#include <Protocol/BlockIo.h> +#include <Protocol/ComponentName.h> +#include <Protocol/DevicePath.h> +#include <Protocol/DriverBinding.h> +#include <Protocol/DiskIo.h> +#include <Protocol/SimpleFileSystem.h> + +#include <Guid/FileInfo.h> +#include <Guid/FileSystemInfo.h> +#include <Guid/FileSystemVolumeLabelInfo.h> + +#include <Library/DebugLib.h> +#include <Library/UefiDriverEntryPoint.h> +#include <Library/BaseLib.h> +#include <Library/UefiLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DevicePathLib.h> + +// +// As specified in ECMA-167 specification, the logical sector size and logical +// block size shall be 2048 bytes. +// +#define LOGICAL_SECTOR_SIZE ((UINT64)0x800ULL) +#define LOGICAL_BLOCK_SIZE ((UINT64)0x800ULL) + +#define FIRST_ANCHOR_POINT_LSN ((UINT64)0x0000000000000100ULL) +#define BEA_DESCRIPTOR_LSN ((UINT64)0x0000000000000013ULL) + +#define LOGICAL_VOLUME_IDENTIFIER_LENGTH 128 + +#define IS_PVD(_Pointer) \ + (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 1) +#define IS_AVDP(_Pointer) \ + (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 2) +#define IS_PD(_Pointer) \ + (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 5) +#define IS_LVD(_Pointer) \ + (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 6) +#define IS_TD(_Pointer) \ + (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 8) +#define IS_FSD(_Pointer) \ + (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 256) +#define IS_FE(_Pointer) \ + (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 261) +#define IS_FID(_Pointer) \ + (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 257) + +#define IS_FE_DIRECTORY(_Pointer) \ + (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType == 4) +#define IS_FE_STANDARD_FILE(_Pointer) \ + (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType == 5) + +#define HIDDEN_FILE (1 << 0) +#define DIRECTORY_FILE (1 << 1) +#define DELETED_FILE (1 << 2) +#define PARENT_FILE (1 << 3) + +#define IS_FID_HIDDEN_FILE(_Pointer) \ + (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics & \ + HIDDEN_FILE) +#define IS_FID_DIRECTORY_FILE(_Pointer) \ + (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics & \ + DIRECTORY_FILE) +#define IS_FID_DELETED_FILE(_Pointer) \ + (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics & \ + DELETED_FILE) +#define IS_FID_PARENT_FILE(_Pointer) \ + (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics & \ + PARENT_FILE) +#define IS_FID_NORMAL_FILE(_Pointer) \ + ((!IS_FID_DIRECTORY_FILE (_Pointer)) && (!IS_FID_PARENT_FILE (_Pointer))) + +#pragma pack(1) + +#define UDF_STANDARD_IDENTIFIER_LENGTH 5 + +typedef struct { + UINT8 StandardIdentifier[UDF_STANDARD_IDENTIFIER_LENGTH]; +} UDF_STANDARD_IDENTIFIER; + +#pragma pack() + +enum { + BEA_IDENTIFIER = 0, + VSD_IDENTIFIER_0, + VSD_IDENTIFIER_1, + TEA_IDENTIFIER, + STANDARD_IDENTIFIERS_NO, +}; + +#pragma pack(1) + +// +// UDF's Volume Structures +// +typedef struct { + UINT16 TagIdentifier; + UINT16 DescriptorVersion; + UINT8 TagChecksum; + UINT8 Reserved; + UINT16 TagSerialNumber; // Ignored. Intended for disaster recovery. + UINT16 DescriptorCRC; + UINT16 DescriptorCRCLength; + UINT32 TagLocation; +} UDF_DESCRIPTOR_TAG; + +// +// ECMA 167 1/7.2.1 +// +typedef struct { + UINT8 CharacterSetType; + UINT8 CharacterSetInfo[63]; +} UDF_CHAR_SPEC; + +// +// ECMA 167 1/7.4 +// +typedef struct { + UINT8 Flags; + UINT8 Identifier[23]; + UINT8 IdentifierSuffix[8]; +} UDF_ENTITY_ID; + +// +// ECMA 167 1/7.3 +// +typedef struct { + UINT16 TypeAndTimezone; + INT16 Year; + UINT8 Month; + UINT8 Day; + UINT8 Hour; + UINT8 Minute; + UINT8 Second; + UINT8 Centiseconds; + UINT8 HundredsOfMicroseconds; + UINT8 Microseconds; +} UDF_TIMESTAMP; + +// +// ECMA 167 3/7.1 +// +typedef struct { + UINT32 ExtentLength; + UINT32 ExtentLocation; +} UDF_EXTENT_AD; + +// +// ECMA 167 4/7.1 +// +typedef struct { + UINT32 LogicalBlockNumber; + UINT16 PartitionReferenceNumber; +} UDF_LB_ADDR; + +// +// ECMA 167 4/14.14.2 +// +typedef struct { + UINT32 ExtentLength; + UDF_LB_ADDR ExtentLocation; + UINT8 ImplementationUse[6]; +} UDF_LONG_ALLOCATION_DESCRIPTOR; + +// +// ECMA 167 3/9.1 +// +typedef struct { + UINT8 StructureType; + UINT8 StandardIdentifier[5]; + UINT8 StructureVersion; + UINT8 Reserved; + UINT8 StructureData[2040]; +} UDF_NSR_DESCRIPTOR; + +typedef struct { + UDF_DESCRIPTOR_TAG DescriptorTag; + UDF_EXTENT_AD MainVolumeDescriptorSequenceExtent; + UDF_EXTENT_AD ReserveVolumeDescriptorSequenceExtent; + UINT8 Reserved[480]; +} UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER; + +// +// ECMA 167 3/10.5 +// +typedef struct { + UDF_DESCRIPTOR_TAG DescriptorTag; + UINT32 VolumeDescriptorSequenceNumber; + UINT16 PartitionFlags; + UINT16 PartitionNumber; + UDF_ENTITY_ID PartitionContents; + UINT8 PartitionContentsUse[128]; + UINT32 AccessType; + UINT32 PartitionStartingLocation; + UINT32 PartitionLength; + UDF_ENTITY_ID ImplementationIdentifier; + UINT8 ImplementationUse[128]; + UINT8 Reserved[156]; +} UDF_PARTITION_DESCRIPTOR; + +// +// ECMA 167 3/10.6 +// +typedef struct { + UDF_DESCRIPTOR_TAG DescriptorTag; + UINT32 VolumeDescriptorSequenceNumber; + UDF_CHAR_SPEC DescriptorCharacterSet; + UINT8 LogicalVolumeIdentifier[LOGICAL_VOLUME_IDENTIFIER_LENGTH]; + UINT32 LogicalBlockSize; + UDF_ENTITY_ID DomainIdentifier; + UDF_LONG_ALLOCATION_DESCRIPTOR LogicalVolumeContentsUse; + UINT32 MapTableLength; + UINT32 NumberOfPartitionMaps; + UDF_ENTITY_ID ImplementationIdentifier; + UINT8 ImplementationUse[128]; + UDF_EXTENT_AD IntegritySequenceExtent; + UINT8 PartitionMaps[6]; +} UDF_LOGICAL_VOLUME_DESCRIPTOR; + +// +// ECMA 167 4/14.1 +// +typedef struct { + UDF_DESCRIPTOR_TAG DescriptorTag; + UDF_TIMESTAMP RecordingDateAndTime; + UINT16 InterchangeLevel; + UINT16 MaximumInterchangeLevel; + UINT32 CharacterSetList; + UINT32 MaximumCharacterSetList; + UINT32 FileSetNumber; + UINT32 FileSetDescriptorNumber; + UDF_CHAR_SPEC LogicalVolumeIdentifierCharacterSet; + UINT8 LogicalVolumeIdentifier[128]; + UDF_CHAR_SPEC FileSetCharacterSet; + UINT8 FileSetIdentifier[32]; + UINT8 CopyrightFileIdentifier[32]; + UINT8 AbstractFileIdentifier[32]; + UDF_LONG_ALLOCATION_DESCRIPTOR RootDirectoryIcb; + UDF_ENTITY_ID DomainIdentifier; + UDF_LONG_ALLOCATION_DESCRIPTOR NextExtent; + UDF_LONG_ALLOCATION_DESCRIPTOR SystemStreamDirectoryIcb; + UINT8 Reserved[32]; +} UDF_FILE_SET_DESCRIPTOR; + +// +// ECMA 167 4/14.14.1 +// +typedef struct { + UINT32 ExtentLength; + UINT32 ExtentPosition; +} UDF_SHORT_ALLOCATION_DESCRIPTOR; + +// +// ECMA 167 4/14.3 +// +typedef struct { + UDF_DESCRIPTOR_TAG DescriptorTag; + UINT16 FileVersionNumber; + UINT8 FileCharacteristics; + UINT8 LengthOfFileIdentifier; + UDF_LONG_ALLOCATION_DESCRIPTOR Icb; + UINT16 LengthOfImplementationUse; + UINT8 Data[2010]; +} UDF_FILE_IDENTIFIER_DESCRIPTOR; + +// +// ECMA 167 4/14.6 +// +typedef struct { + UINT32 PriorRecordNumberOfDirectEntries; + UINT16 StrategyType; + UINT16 StrategyParameter; + UINT16 MaximumNumberOfEntries; + UINT8 Reserved; + UINT8 FileType; + UDF_LB_ADDR ParentIcbLocation; + UINT16 Flags; +} UDF_ICB_TAG; + +// +// ECMA 167 4/14.9 +// +// NOTE: The total length of a FE shall not exceed the size of one logical block +// (2048 bytes). +// +typedef struct { + UDF_DESCRIPTOR_TAG DescriptorTag; + UDF_ICB_TAG IcbTag; + UINT32 Uid; + UINT32 Gid; + UINT32 Permissions; + UINT16 FileLinkCount; + UINT8 RecordFormat; + UINT8 RecordDisplayAttributes; + UINT32 RecordLength; + UINT64 InformationLength; + UINT64 LogicalBlocksRecorded; + UDF_TIMESTAMP AccessTime; + UDF_TIMESTAMP ModificationTime; + UDF_TIMESTAMP AttributeTime; + UINT32 CheckPoint; + UDF_LONG_ALLOCATION_DESCRIPTOR ExtendedAttributeIcb; + UDF_ENTITY_ID ImplementationIdentifier; + UINT64 UniqueId; + UINT32 LengthOfExtendedAttributes; + UINT32 LengthOfAllocationDescriptors; + UINT8 Data[1872]; // L_EAs and L_ADs +} UDF_FILE_ENTRY; + +#pragma pack() + +// +// UDF filesystem driver's private data +// +#define PRIVATE_UDF_FILE_DATA_SIGNATURE SIGNATURE_32 ('U', 'd', 'f', 'f') + +#define PRIVATE_UDF_FILE_DATA_FROM_THIS(a) \ + CR ( \ + a, \ + PRIVATE_UDF_FILE_DATA, \ + FileIo, \ + PRIVATE_UDF_FILE_DATA_SIGNATURE \ + ) + +typedef struct { + UINTN Signature; + + struct { + UINT32 StartingLocation; + UINT32 Length; + UINT32 AccessType; + } Partition; + struct { + UINT8 Identifier[LOGICAL_VOLUME_IDENTIFIER_LENGTH]; + } Volume; + struct { + UDF_FILE_ENTRY FileEntry; + UDF_FILE_IDENTIFIER_DESCRIPTOR FileIdentifierDesc; + } Root; + struct { + UDF_FILE_IDENTIFIER_DESCRIPTOR ParentFileIdentifierDesc; + UDF_FILE_ENTRY FileEntry; + UDF_FILE_IDENTIFIER_DESCRIPTOR FileIdentifierDesc; + } File; + + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_FILE_PROTOCOL FileIo; + UINT64 FilePosition; + UINT64 NextEntryOffset; + CHAR16 *AbsoluteFileName; + CHAR16 *FileName; + BOOLEAN IsRootDirectory; +} PRIVATE_UDF_FILE_DATA; + +#define PRIVATE_UDF_SIMPLE_FS_DATA_SIGNATURE SIGNATURE_32 ('U', 'd', 'f', 's') + +#define PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS(a) \ + CR ( \ + a, \ + PRIVATE_UDF_SIMPLE_FS_DATA, \ + SimpleFs, \ + PRIVATE_UDF_SIMPLE_FS_DATA_SIGNATURE \ + ) + +typedef struct { + UINTN Signature; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_HANDLE Handle; +} PRIVATE_UDF_SIMPLE_FS_DATA; + +typedef struct { + VENDOR_DEVICE_PATH DevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} UDF_DEVICE_PATH; + +// C5BD4D42-1A76-4996-8956-73CDA326CD0A +#define EFI_UDF_DEVICE_PATH_GUID \ + { 0xC5BD4D42, 0x1A76, 0x4996, \ + { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A } \ + } + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gUdfDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gUdfComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gUdfComponentName2; + +// +// Function Prototypes +// + +/** + 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 + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + Get a 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 +UdfGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + Set information about a file + + @param File 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 + ); + +/** + 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 + ); + +EFI_STATUS +EFIAPI +FindRootDirectory ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + OUT UDF_PARTITION_DESCRIPTOR *PartitionDesc, + OUT UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc, + OUT UDF_FILE_ENTRY *FileEntry, + OUT UDF_FILE_IDENTIFIER_DESCRIPTOR *FileIdentifierDesc + ); + +EFI_STATUS +IsSupportedUdfVolume ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + OUT BOOLEAN *Supported + ); + +EFI_STATUS +FindFileIdentifierDescriptorRootDir ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN UDF_PARTITION_DESCRIPTOR *PartitionDesc, + IN UDF_FILE_SET_DESCRIPTOR *FileSetDesc, + OUT UDF_FILE_IDENTIFIER_DESCRIPTOR *FileIdentifierDesc + ); + +/** + Test to see if this driver supports ControllerHandle. Any ControllerHandle + than contains a BlockIo and DiskIo protocol can be supported. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to test + @param 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 + ); + +/** + Start this driver on ControllerHandle by opening a Block IO and Disk IO + protocol, reading Device Path, and creating a child handle with a + Disk IO and device path protocol. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to bind driver to + @param 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 + ); + +/** + 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 + ); + +// +// EFI Component Name Functions +// +/** + 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 + ); + +/** + 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 not a valid EFI_HANDLE. + + @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 + ); + +#endif // _UDF_H_ diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf b/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf new file mode 100644 index 0000000..538a618 --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf @@ -0,0 +1,63 @@ +## @file +# UDF filesystem driver. +# +# Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR> +# 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 + 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 -- 1.9.3 ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel