/**\r
Get information about a file.\r
\r
- @attention This is boundary function that may receive untrusted input.\r
- @attention The input is from FileSystem.\r
-\r
- The File Set Descriptor is external input, so this routine will do basic\r
- validation for File Set Descriptor and report status.\r
-\r
@param This Protocol instance pointer.\r
@param InformationType Type of information to return in Buffer.\r
@param BufferSize On input size of buffer, on output amount of data in\r
OUT VOID *Buffer\r
)\r
{\r
- EFI_STATUS Status;\r
- PRIVATE_UDF_FILE_DATA *PrivFileData;\r
- PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;\r
- EFI_FILE_SYSTEM_INFO *FileSystemInfo;\r
- UINTN FileSystemInfoLength;\r
- CHAR16 *String;\r
- UDF_FILE_SET_DESCRIPTOR *FileSetDesc;\r
- UINTN Index;\r
- UINT8 *OstaCompressed;\r
- UINT8 CompressionId;\r
- UINT64 VolumeSize;\r
- UINT64 FreeSpaceSize;\r
- CHAR16 VolumeLabel[64];\r
+ EFI_STATUS Status;\r
+ PRIVATE_UDF_FILE_DATA *PrivFileData;\r
+ PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;\r
+ EFI_FILE_SYSTEM_INFO *FileSystemInfo;\r
+ UINTN FileSystemInfoLength;\r
+ UINT64 VolumeSize;\r
+ UINT64 FreeSpaceSize;\r
+ EFI_FILE_SYSTEM_VOLUME_LABEL *FileSystemVolumeLabel;\r
+ UINTN FileSystemVolumeLabelLength;\r
+ CHAR16 VolumeLabel[64];\r
\r
if (This == NULL || InformationType == NULL || BufferSize == NULL ||\r
(*BufferSize != 0 && Buffer == NULL)) {\r
Buffer\r
);\r
} else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
- String = VolumeLabel;\r
-\r
- FileSetDesc = &PrivFsData->Volume.FileSetDesc;\r
-\r
- OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];\r
-\r
- CompressionId = OstaCompressed[0];\r
- if (!IS_VALID_COMPRESSION_ID (CompressionId)) {\r
- return EFI_VOLUME_CORRUPTED;\r
- }\r
-\r
- for (Index = 1; Index < 128; Index++) {\r
- if (CompressionId == 16) {\r
- *String = *(UINT8 *)(OstaCompressed + Index) << 8;\r
- Index++;\r
- } else {\r
- if (Index > ARRAY_SIZE (VolumeLabel)) {\r
- return EFI_VOLUME_CORRUPTED;\r
- }\r
-\r
- *String = 0;\r
- }\r
-\r
- if (Index < 128) {\r
- *String |= (CHAR16)(*(UINT8 *)(OstaCompressed + Index));\r
- }\r
-\r
- //\r
- // Unlike FID Identifiers, Logical Volume Identifier is stored in a\r
- // NULL-terminated OSTA compressed format, so we must check for the NULL\r
- // character.\r
- //\r
- if (*String == L'\0') {\r
- break;\r
- }\r
-\r
- String++;\r
- }\r
-\r
- Index = ((UINTN)String - (UINTN)VolumeLabel) / sizeof (CHAR16);\r
- if (Index > ARRAY_SIZE (VolumeLabel) - 1) {\r
- Index = ARRAY_SIZE (VolumeLabel) - 1;\r
+ Status = GetVolumeLabel (&PrivFsData->Volume, ARRAY_SIZE (VolumeLabel), VolumeLabel);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
- VolumeLabel[Index] = L'\0';\r
\r
FileSystemInfoLength = StrSize (VolumeLabel) +\r
sizeof (EFI_FILE_SYSTEM_INFO);\r
FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;\r
StrCpyS (\r
FileSystemInfo->VolumeLabel,\r
- (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16),\r
+ (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16),\r
VolumeLabel\r
);\r
Status = GetVolumeSize (\r
\r
*BufferSize = FileSystemInfoLength;\r
Status = EFI_SUCCESS;\r
+ } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
+ Status = GetVolumeLabel (&PrivFsData->Volume, ARRAY_SIZE (VolumeLabel), VolumeLabel);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ FileSystemVolumeLabelLength = StrSize (VolumeLabel) +\r
+ sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL);\r
+ if (*BufferSize < FileSystemVolumeLabelLength) {\r
+ *BufferSize = FileSystemVolumeLabelLength;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ FileSystemVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer;\r
+ StrCpyS (\r
+ FileSystemVolumeLabel->VolumeLabel,\r
+ (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL) / sizeof (CHAR16),\r
+ VolumeLabel\r
+ );\r
+ Status = EFI_SUCCESS;\r
}\r
\r
return Status;\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Get volume label of an UDF volume.\r
+\r
+ @attention This is boundary function that may receive untrusted input.\r
+ @attention The input is from FileSystem.\r
+\r
+ The File Set Descriptor is external input, so this routine will do basic\r
+ validation for File Set Descriptor and report status.\r
+\r
+ @param[in] Volume Volume information pointer.\r
+ @param[in] CharMax The maximum number of Unicode char in String,\r
+ including terminating null char.\r
+ @param[out] String String buffer pointer to store the volume label.\r
+\r
+ @retval EFI_SUCCESS Volume label is returned.\r
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+ @retval EFI_BUFFER_TOO_SMALL The string buffer String cannot hold the\r
+ volume label.\r
+\r
+**/\r
+EFI_STATUS\r
+GetVolumeLabel (\r
+ IN UDF_VOLUME_INFO *Volume,\r
+ IN UINTN CharMax,\r
+ OUT CHAR16 *String\r
+ )\r
+{\r
+ UDF_FILE_SET_DESCRIPTOR *FileSetDesc;\r
+ UINTN Index;\r
+ UINT8 *OstaCompressed;\r
+ UINT8 CompressionId;\r
+ CHAR16 *StringBak;\r
+\r
+ FileSetDesc = &Volume->FileSetDesc;\r
+\r
+ OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];\r
+\r
+ CompressionId = OstaCompressed[0];\r
+ if (!IS_VALID_COMPRESSION_ID (CompressionId)) {\r
+ return EFI_VOLUME_CORRUPTED;\r
+ }\r
+\r
+ StringBak = String;\r
+ for (Index = 1; Index < 128; Index++) {\r
+ if (CompressionId == 16) {\r
+ if ((Index >> 1) > CharMax) {\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *String = *(UINT8 *)(OstaCompressed + Index) << 8;\r
+ Index++;\r
+ } else {\r
+ if (Index > CharMax) {\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *String = 0;\r
+ }\r
+\r
+ if (Index < 128) {\r
+ *String |= (CHAR16)(*(UINT8 *)(OstaCompressed + Index));\r
+ }\r
+\r
+ //\r
+ // Unlike FID Identifiers, Logical Volume Identifier is stored in a\r
+ // NULL-terminated OSTA compressed format, so we must check for the NULL\r
+ // character.\r
+ //\r
+ if (*String == L'\0') {\r
+ break;\r
+ }\r
+\r
+ String++;\r
+ }\r
+\r
+ Index = ((UINTN)String - (UINTN)StringBak) / sizeof (CHAR16);\r
+ if (Index > CharMax - 1) {\r
+ Index = CharMax - 1;\r
+ }\r
+ StringBak[Index] = L'\0';\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Get volume and free space size information of an UDF volume.\r
\r
OUT VOID *Buffer\r
);\r
\r
+/**\r
+ Get volume label of an UDF volume.\r
+\r
+ @attention This is boundary function that may receive untrusted input.\r
+ @attention The input is from FileSystem.\r
+\r
+ The File Set Descriptor is external input, so this routine will do basic\r
+ validation for File Set Descriptor and report status.\r
+\r
+ @param[in] Volume Volume information pointer.\r
+ @param[in] CharMax The maximum number of Unicode char in String,\r
+ including terminating null char.\r
+ @param[out] String String buffer pointer to store the volume label.\r
+\r
+ @retval EFI_SUCCESS Volume label is returned.\r
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+ @retval EFI_BUFFER_TOO_SMALL The string buffer String cannot hold the\r
+ volume label.\r
+\r
+**/\r
+EFI_STATUS\r
+GetVolumeLabel (\r
+ IN UDF_VOLUME_INFO *Volume,\r
+ IN UINTN CharMax,\r
+ OUT CHAR16 *String\r
+ );\r
+\r
/**\r
Get volume and free space size information of an UDF volume.\r
\r