Skip to content

Commit

Permalink
Ext4Pkg: Add handling of EFI_FILE_SYSTEM_VOLUME_LABEL GetInfo().
Browse files Browse the repository at this point in the history
This commit adds support for EFI_FILE_SYSTEM_VOLUME_LABEL requests
in GetInfo().

Cc: Leif Lindholm <[email protected]>
Cc: Michael D Kinney <[email protected]>
Cc: Bret Barkelew <[email protected]>
Signed-off-by: Pedro Falcato <[email protected]>
Reviewed-by: Michael D Kinney <[email protected]>
  • Loading branch information
heatd authored and mdkinney committed Aug 24, 2021
1 parent 21b1853 commit cfbbae5
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 35 deletions.
1 change: 0 additions & 1 deletion Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
**/

#include "Ext4Dxe.h"
#include "Uefi/UefiBaseType.h"

GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mExt4DriverNameTable[] = {
{
Expand Down
17 changes: 17 additions & 0 deletions Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
155 changes: 121 additions & 34 deletions Features/Ext4Pkg/Ext4Dxe/File.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit cfbbae5

Please sign in to comment.