Handle operations in files and directories from UDF/ECMA-167 file systems.\r
\r
Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>\r
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
\r
- This program and the accompanying materials are licensed and made available\r
- under the terms and conditions of the BSD License which accompanies this\r
- distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
- WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
**/\r
\r
#include "Udf.h"\r
CleanupFileInformation (&PrivFsData->Root);\r
\r
Error_Find_Root_Dir:\r
- CleanupVolumeInformation (&PrivFsData->Volume);\r
\r
Error_Read_Udf_Volume:\r
Error_Invalid_Params:\r
FileName = TempFileName + 1;\r
}\r
\r
- StrCpyS (NewPrivFileData->FileName, UDF_PATH_LENGTH, FileName);\r
+ StrCpyS (NewPrivFileData->FileName, UDF_FILENAME_LENGTH, FileName);\r
\r
Status = GetFileSize (\r
PrivFsData->BlockIo,\r
&NewPrivFileData->File,\r
&NewPrivFileData->FileSize\r
);\r
- ASSERT_EFI_ERROR (Status);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: GetFileSize() fails with status - %r.\n",\r
+ __FUNCTION__, Status\r
+ ));\r
goto Error_Get_File_Size;\r
}\r
\r
\r
goto Done;\r
}\r
+ //\r
+ // After calling function ReadDirectoryEntry(), if 'NewFileIdentifierDesc'\r
+ // is NULL, then the 'Status' must be EFI_OUT_OF_RESOURCES. Hence, if the\r
+ // code reaches here, 'NewFileIdentifierDesc' must be not NULL.\r
+ //\r
+ // The ASSERT here is for addressing a false positive NULL pointer\r
+ // dereference issue raised from static analysis.\r
+ //\r
+ ASSERT (NewFileIdentifierDesc != NULL);\r
\r
if (!IS_FID_PARENT_FILE (NewFileIdentifierDesc)) {\r
break;\r
}\r
ASSERT (NewFileEntryData != NULL);\r
\r
- if (IS_FE_SYMLINK (NewFileEntryData)) {\r
+ if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink) {\r
Status = ResolveSymlink (\r
BlockIo,\r
DiskIo,\r
FreePool ((VOID *)NewFileEntryData);\r
NewFileEntryData = FoundFile.FileEntry;\r
\r
- Status = GetFileNameFromFid (NewFileIdentifierDesc, FileName);\r
+ Status = GetFileNameFromFid (NewFileIdentifierDesc, ARRAY_SIZE (FileName), FileName);\r
if (EFI_ERROR (Status)) {\r
FreePool ((VOID *)FoundFile.FileIdentifierDesc);\r
goto Error_Get_FileName;\r
FoundFile.FileIdentifierDesc = NewFileIdentifierDesc;\r
FoundFile.FileEntry = NewFileEntryData;\r
\r
- Status = GetFileNameFromFid (FoundFile.FileIdentifierDesc, FileName);\r
+ Status = GetFileNameFromFid (FoundFile.FileIdentifierDesc, ARRAY_SIZE (FileName), FileName);\r
if (EFI_ERROR (Status)) {\r
goto Error_Get_FileName;\r
}\r
PrivFileData->FilePosition++;\r
Status = EFI_SUCCESS;\r
} else if (IS_FID_DELETED_FILE (Parent->FileIdentifierDesc)) {\r
+ //\r
+ // Code should never reach here.\r
+ //\r
+ ASSERT (FALSE);\r
Status = EFI_DEVICE_ERROR;\r
}\r
\r
EFI_TPL OldTpl;\r
EFI_STATUS Status;\r
PRIVATE_UDF_FILE_DATA *PrivFileData;\r
- PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData;\r
\r
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
\r
\r
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);\r
\r
- PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);\r
-\r
if (!PrivFileData->IsRootDirectory) {\r
CleanupFileInformation (&PrivFileData->File);\r
\r
}\r
}\r
\r
- if (--PrivFsData->OpenFiles == 0) {\r
- CleanupVolumeInformation (&PrivFsData->Volume);\r
- }\r
-\r
FreePool ((VOID *)PrivFileData);\r
\r
Exit:\r
// As per UEFI spec, if the file handle is a directory, then the current file\r
// position has no meaning and the operation is not supported.\r
//\r
- if (IS_FID_DIRECTORY_FILE (&PrivFileData->File.FileIdentifierDesc)) {\r
+ if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
// set to the EOF.\r
//\r
if (Position == 0xFFFFFFFFFFFFFFFF) {\r
- PrivFileData->FilePosition = PrivFileData->FileSize - 1;\r
+ PrivFileData->FilePosition = PrivFileData->FileSize;\r
} else {\r
PrivFileData->FilePosition = Position;\r
}\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.FileSetDescs[0];\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
- *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
+ Status = GetVolumeLabel (&PrivFsData->Volume, ARRAY_SIZE (VolumeLabel), VolumeLabel);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
\r
- *String = L'\0';\r
-\r
FileSystemInfoLength = StrSize (VolumeLabel) +\r
sizeof (EFI_FILE_SYSTEM_INFO);\r
if (*BufferSize < FileSystemInfoLength) {\r
}\r
\r
FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;\r
- StrCpyS (FileSystemInfo->VolumeLabel, ARRAY_SIZE (VolumeLabel),\r
- VolumeLabel);\r
+ StrCpyS (\r
+ FileSystemInfo->VolumeLabel,\r
+ (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16),\r
+ VolumeLabel\r
+ );\r
Status = GetVolumeSize (\r
PrivFsData->BlockIo,\r
PrivFsData->DiskIo,\r
FileSystemInfo->Size = FileSystemInfoLength;\r
FileSystemInfo->ReadOnly = TRUE;\r
FileSystemInfo->BlockSize =\r
- LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);\r
+ PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;\r
FileSystemInfo->VolumeSize = VolumeSize;\r
FileSystemInfo->FreeSpace = FreeSpaceSize;\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