From cfbbae595eec2b7df57a50f277d250dd302d2e9e Mon Sep 17 00:00:00 2001 From: Pedro Falcato Date: Sat, 21 Aug 2021 07:47:09 -0700 Subject: [PATCH] Ext4Pkg: Add handling of EFI_FILE_SYSTEM_VOLUME_LABEL GetInfo(). This commit adds support for EFI_FILE_SYSTEM_VOLUME_LABEL requests in GetInfo(). Cc: Leif Lindholm Cc: Michael D Kinney Cc: Bret Barkelew Signed-off-by: Pedro Falcato Reviewed-by: Michael D Kinney --- Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c | 1 - Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h | 17 ++++ Features/Ext4Pkg/Ext4Dxe/File.c | 155 ++++++++++++++++++++++------- 3 files changed, 138 insertions(+), 35 deletions(-) diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c index 71360ea894d..ea2e048d776 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c +++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c @@ -6,7 +6,6 @@ **/ #include "Ext4Dxe.h" -#include "Uefi/UefiBaseType.h" GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mExt4DriverNameTable[] = { { diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h index db938c25244..64eab455db4 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h +++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h @@ -1100,4 +1100,21 @@ Ext4CalculateBlockGroupDescChecksum ( #define EXT4_HAS_GDT_CSUM(Partition) \ EXT4_HAS_RO_COMPAT (Partition, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) +/** + Retrieves the volume name. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a CHAR16*. + @param[out] BufferSize Pointer to a UINTN, where the string length + of the name will be put. + + @return Status of the volume name request. +**/ +EFI_STATUS +Ext4GetVolumeName ( + IN EXT4_PARTITION *Partition, + OUT CHAR16 **OutVolName, + OUT UINTN *VolNameLen + ); + #endif diff --git a/Features/Ext4Pkg/Ext4Dxe/File.c b/Features/Ext4Pkg/Ext4Dxe/File.c index 021d10b1edf..4ad7cad8dcf 100644 --- a/Features/Ext4Pkg/Ext4Dxe/File.c +++ b/Features/Ext4Pkg/Ext4Dxe/File.c @@ -35,7 +35,9 @@ Ext4DuplicateFile ( STATIC EFI_STATUS GetPathSegment ( - IN CONST CHAR16 *Path, OUT CHAR16 *PathSegment, OUT UINTN *Length + IN CONST CHAR16 *Path, + OUT CHAR16 *PathSegment, + OUT UINTN *Length ) { CONST CHAR16 *Start; @@ -514,7 +516,9 @@ Ext4SetPosition ( **/ EFI_STATUS Ext4GetFileInfo ( - IN EXT4_FILE *File, OUT EFI_FILE_INFO *Info, IN OUT UINTN *BufferSize + IN EXT4_FILE *File, + OUT EFI_FILE_INFO *Info, + IN OUT UINTN *BufferSize ) { UINTN FileNameLen; @@ -557,35 +561,33 @@ Ext4GetFileInfo ( } /** - Retrieves information about the filesystem and stores it in the EFI_FILE_SYSTEM_INFO format. + Retrieves the volume name. @param[in] Part Pointer to the opened partition. - @param[out] Info Pointer to a EFI_FILE_SYSTEM_INFO. - @param[in out] BufferSize Pointer to the buffer size + @param[out] Info Pointer to a CHAR16*. + @param[out] BufferSize Pointer to a UINTN, where the string length + of the name will be put. - @return Status of the file information request. + @return Status of the volume name request. **/ -STATIC EFI_STATUS -Ext4GetFilesystemInfo ( - IN EXT4_PARTITION *Part, OUT EFI_FILE_SYSTEM_INFO *Info, IN OUT UINTN *BufferSize +Ext4GetVolumeName ( + IN EXT4_PARTITION *Partition, + OUT CHAR16 **OutVolName, + OUT UINTN *VolNameLen ) { - // Length of s_volume_name + null terminator - CHAR8 TempVolName[16 + 1]; - CHAR16 *VolumeName; - UINTN VolNameLength; - EFI_STATUS Status; - UINTN NeededLength; - EXT4_BLOCK_NR TotalBlocks; - EXT4_BLOCK_NR FreeBlocks; + CHAR8 TempVolName[16 + 1]; + CHAR16 *VolumeName; + UINTN VolNameLength; + EFI_STATUS Status; VolNameLength = 0; VolumeName = NULL; // s_volume_name is only valid on dynamic revision; old filesystems don't support this - if (Part->SuperBlock.s_rev_level == EXT4_DYNAMIC_REV) { - CopyMem (TempVolName, (CONST CHAR8 *)Part->SuperBlock.s_volume_name, 16); + if (Partition->SuperBlock.s_rev_level == EXT4_DYNAMIC_REV) { + CopyMem (TempVolName, (CONST CHAR8 *)Partition->SuperBlock.s_volume_name, 16); TempVolName[16] = '\0'; Status = UTF8StrToUCS2 (TempVolName, &VolumeName); @@ -595,23 +597,56 @@ Ext4GetFilesystemInfo ( } VolNameLength = StrLen (VolumeName); + } else { + VolumeName = AllocateZeroPool (sizeof (CHAR16)); + VolNameLength = 0; } - NeededLength = SIZE_OF_EFI_FILE_SYSTEM_INFO; + *OutVolName = VolumeName; + *VolNameLen = VolNameLength; - if (VolumeName != NULL) { - NeededLength += StrSize (VolumeName); - } else { - // If we don't have a volume name, we set VolumeLabel to a single null terminator - NeededLength += sizeof (CHAR16); + return EFI_SUCCESS; +} + +/** + Retrieves information about the filesystem and stores it in the EFI_FILE_SYSTEM_INFO format. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a EFI_FILE_SYSTEM_INFO. + @param[in out] BufferSize Pointer to the buffer size + + @return Status of the file information request. +**/ +STATIC +EFI_STATUS +Ext4GetFilesystemInfo ( + IN EXT4_PARTITION *Part, + OUT EFI_FILE_SYSTEM_INFO *Info, + IN OUT UINTN *BufferSize + ) +{ + // Length of s_volume_name + null terminator + EFI_STATUS Status; + UINTN NeededLength; + EXT4_BLOCK_NR TotalBlocks; + EXT4_BLOCK_NR FreeBlocks; + CHAR16 *VolumeName; + UINTN VolNameLength; + + Status = Ext4GetVolumeName (Part, &VolumeName, &VolNameLength); + + if (EFI_ERROR (Status)) { + return Status; } + NeededLength = SIZE_OF_EFI_FILE_SYSTEM_INFO; + + NeededLength += StrSize (VolumeName); + if (*BufferSize < NeededLength) { *BufferSize = NeededLength; - if (VolumeName != NULL) { - FreePool (VolumeName); - } + FreePool (VolumeName); return EFI_BUFFER_TOO_SMALL; } @@ -630,16 +665,60 @@ Ext4GetFilesystemInfo ( Info->VolumeSize = MultU64x32 (TotalBlocks, Part->BlockSize); Info->FreeSpace = MultU64x32 (FreeBlocks, Part->BlockSize); - if (VolumeName != NULL) { - StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName); - } else { - Info->VolumeLabel[0] = L'\0'; + StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName); + + FreePool (VolumeName); + + *BufferSize = NeededLength; + + return EFI_SUCCESS; +} + +/** + Retrieves the volume label and stores it in the EFI_FILE_SYSTEM_VOLUME_LABEL format. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a EFI_FILE_SYSTEM_VOLUME_LABEL. + @param[in out] BufferSize Pointer to the buffer size + + @return Status of the file information request. +**/ +STATIC +EFI_STATUS +Ext4GetVolumeLabelInfo ( + IN EXT4_PARTITION *Part, + OUT EFI_FILE_SYSTEM_VOLUME_LABEL *Info, + IN OUT UINTN *BufferSize + ) +{ + // Length of s_volume_name + null terminator + CHAR16 *VolumeName; + UINTN VolNameLength; + EFI_STATUS Status; + UINTN NeededLength; + + Status = Ext4GetVolumeName (Part, &VolumeName, &VolNameLength); + + if (EFI_ERROR (Status)) { + return Status; } - if (VolumeName != NULL) { + NeededLength = (VolNameLength + 1) * sizeof (CHAR16); + + if (NeededLength > *BufferSize) { + *BufferSize = NeededLength; + FreePool (VolumeName); + + return EFI_BUFFER_TOO_SMALL; } + Status = StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName); + + ASSERT_EFI_ERROR (Status); + + FreePool (VolumeName); + *BufferSize = NeededLength; return EFI_SUCCESS; @@ -674,12 +753,20 @@ Ext4GetInfo ( OUT VOID *Buffer ) { + EXT4_PARTITION *Partition; + + Partition = ((EXT4_FILE *)This)->Partition; + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { return Ext4GetFileInfo ((EXT4_FILE *)This, Buffer, BufferSize); } if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { - return Ext4GetFilesystemInfo (((EXT4_FILE *)This)->Partition, Buffer, BufferSize); + return Ext4GetFilesystemInfo (Partition, Buffer, BufferSize); + } + + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + return Ext4GetVolumeLabelInfo (Partition, Buffer, BufferSize); } return EFI_UNSUPPORTED;