MdeModulePkg/UdfDxe: Update GetInfo() for FS VolumeLabel info request

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1175

This commit will update the UdfGetInfo() function with the support of
EFI_FILE_SYSTEM_VOLUME_LABEL data information request.

Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
Acked-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
Hao Wu 2018-10-12 14:49:41 +08:00
parent 6a926aaed7
commit 32698a8f01
4 changed files with 146 additions and 63 deletions

View File

@ -736,12 +736,6 @@ UdfSetPosition (
/** /**
Get information about a file. Get information about a file.
@attention This is boundary function that may receive untrusted input.
@attention The input is from FileSystem.
The File Set Descriptor is external input, so this routine will do basic
validation for File Set Descriptor and report status.
@param This Protocol instance pointer. @param This Protocol instance pointer.
@param InformationType Type of information to return in Buffer. @param InformationType Type of information to return in Buffer.
@param BufferSize On input size of buffer, on output amount of data in @param BufferSize On input size of buffer, on output amount of data in
@ -773,13 +767,10 @@ UdfGetInfo (
PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData; PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;
EFI_FILE_SYSTEM_INFO *FileSystemInfo; EFI_FILE_SYSTEM_INFO *FileSystemInfo;
UINTN FileSystemInfoLength; UINTN FileSystemInfoLength;
CHAR16 *String;
UDF_FILE_SET_DESCRIPTOR *FileSetDesc;
UINTN Index;
UINT8 *OstaCompressed;
UINT8 CompressionId;
UINT64 VolumeSize; UINT64 VolumeSize;
UINT64 FreeSpaceSize; UINT64 FreeSpaceSize;
EFI_FILE_SYSTEM_VOLUME_LABEL *FileSystemVolumeLabel;
UINTN FileSystemVolumeLabelLength;
CHAR16 VolumeLabel[64]; CHAR16 VolumeLabel[64];
if (This == NULL || InformationType == NULL || BufferSize == NULL || if (This == NULL || InformationType == NULL || BufferSize == NULL ||
@ -802,51 +793,11 @@ UdfGetInfo (
Buffer Buffer
); );
} else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
String = VolumeLabel; Status = GetVolumeLabel (&PrivFsData->Volume, ARRAY_SIZE (VolumeLabel), VolumeLabel);
if (EFI_ERROR (Status)) {
FileSetDesc = &PrivFsData->Volume.FileSetDesc; return Status;
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 {
if (Index > ARRAY_SIZE (VolumeLabel)) {
return EFI_VOLUME_CORRUPTED;
}
*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++;
}
Index = ((UINTN)String - (UINTN)VolumeLabel) / sizeof (CHAR16);
if (Index > ARRAY_SIZE (VolumeLabel) - 1) {
Index = ARRAY_SIZE (VolumeLabel) - 1;
}
VolumeLabel[Index] = L'\0';
FileSystemInfoLength = StrSize (VolumeLabel) + FileSystemInfoLength = StrSize (VolumeLabel) +
sizeof (EFI_FILE_SYSTEM_INFO); sizeof (EFI_FILE_SYSTEM_INFO);
if (*BufferSize < FileSystemInfoLength) { if (*BufferSize < FileSystemInfoLength) {
@ -857,7 +808,7 @@ UdfGetInfo (
FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer; FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;
StrCpyS ( StrCpyS (
FileSystemInfo->VolumeLabel, FileSystemInfo->VolumeLabel,
(*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16), (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16),
VolumeLabel VolumeLabel
); );
Status = GetVolumeSize ( Status = GetVolumeSize (
@ -880,6 +831,26 @@ UdfGetInfo (
*BufferSize = FileSystemInfoLength; *BufferSize = FileSystemInfoLength;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
} else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
Status = GetVolumeLabel (&PrivFsData->Volume, ARRAY_SIZE (VolumeLabel), VolumeLabel);
if (EFI_ERROR (Status)) {
return Status;
}
FileSystemVolumeLabelLength = StrSize (VolumeLabel) +
sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL);
if (*BufferSize < FileSystemVolumeLabelLength) {
*BufferSize = FileSystemVolumeLabelLength;
return EFI_BUFFER_TOO_SMALL;
}
FileSystemVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer;
StrCpyS (
FileSystemVolumeLabel->VolumeLabel,
(*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL) / sizeof (CHAR16),
VolumeLabel
);
Status = EFI_SUCCESS;
} }
return Status; return Status;

View File

@ -2530,6 +2530,90 @@ SetFileInfo (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Get volume label of an UDF volume.
@attention This is boundary function that may receive untrusted input.
@attention The input is from FileSystem.
The File Set Descriptor is external input, so this routine will do basic
validation for File Set Descriptor and report status.
@param[in] Volume Volume information pointer.
@param[in] CharMax The maximum number of Unicode char in String,
including terminating null char.
@param[out] String String buffer pointer to store the volume label.
@retval EFI_SUCCESS Volume label is returned.
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
@retval EFI_BUFFER_TOO_SMALL The string buffer String cannot hold the
volume label.
**/
EFI_STATUS
GetVolumeLabel (
IN UDF_VOLUME_INFO *Volume,
IN UINTN CharMax,
OUT CHAR16 *String
)
{
UDF_FILE_SET_DESCRIPTOR *FileSetDesc;
UINTN Index;
UINT8 *OstaCompressed;
UINT8 CompressionId;
CHAR16 *StringBak;
FileSetDesc = &Volume->FileSetDesc;
OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];
CompressionId = OstaCompressed[0];
if (!IS_VALID_COMPRESSION_ID (CompressionId)) {
return EFI_VOLUME_CORRUPTED;
}
StringBak = String;
for (Index = 1; Index < 128; Index++) {
if (CompressionId == 16) {
if ((Index >> 1) > CharMax) {
return EFI_BUFFER_TOO_SMALL;
}
*String = *(UINT8 *)(OstaCompressed + Index) << 8;
Index++;
} else {
if (Index > CharMax) {
return EFI_BUFFER_TOO_SMALL;
}
*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++;
}
Index = ((UINTN)String - (UINTN)StringBak) / sizeof (CHAR16);
if (Index > CharMax - 1) {
Index = CharMax - 1;
}
StringBak[Index] = L'\0';
return EFI_SUCCESS;
}
/** /**
Get volume and free space size information of an UDF volume. Get volume and free space size information of an UDF volume.

View File

@ -900,6 +900,33 @@ SetFileInfo (
OUT VOID *Buffer OUT VOID *Buffer
); );
/**
Get volume label of an UDF volume.
@attention This is boundary function that may receive untrusted input.
@attention The input is from FileSystem.
The File Set Descriptor is external input, so this routine will do basic
validation for File Set Descriptor and report status.
@param[in] Volume Volume information pointer.
@param[in] CharMax The maximum number of Unicode char in String,
including terminating null char.
@param[out] String String buffer pointer to store the volume label.
@retval EFI_SUCCESS Volume label is returned.
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
@retval EFI_BUFFER_TOO_SMALL The string buffer String cannot hold the
volume label.
**/
EFI_STATUS
GetVolumeLabel (
IN UDF_VOLUME_INFO *Volume,
IN UINTN CharMax,
OUT CHAR16 *String
);
/** /**
Get volume and free space size information of an UDF volume. Get volume and free space size information of an UDF volume.

View File

@ -58,6 +58,7 @@
[Guids] [Guids]
gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## Protocol gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## Protocol
gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## Protocol gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## Protocol
gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## Protocol
[Protocols] [Protocols]