]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Disk/UdfDxe/File.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / UdfDxe / File.c
index 8b9339567f8e3070df04390a2940c05fa2a6f0cc..4ad7bb93da4a3458512a455f38b9221be54a3157 100644 (file)
@@ -2,14 +2,9 @@
   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
@@ -131,7 +126,6 @@ Error_Alloc_Priv_File_Data:
   CleanupFileInformation (&PrivFsData->Root);\r
 \r
 Error_Find_Root_Dir:\r
-  CleanupVolumeInformation (&PrivFsData->Volume);\r
 \r
 Error_Read_Udf_Volume:\r
 Error_Invalid_Params:\r
@@ -176,11 +170,12 @@ UdfOpen (
   EFI_STATUS                  Status;\r
   PRIVATE_UDF_FILE_DATA       *PrivFileData;\r
   PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;\r
-  CHAR16                      FilePath[UDF_PATH_LENGTH] = { 0 };\r
+  CHAR16                      FilePath[UDF_PATH_LENGTH];\r
   UDF_FILE_INFO               File;\r
   PRIVATE_UDF_FILE_DATA       *NewPrivFileData;\r
   CHAR16                      *TempFileName;\r
 \r
+  ZeroMem (FilePath, sizeof FilePath);\r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (This == NULL || NewHandle == NULL || FileName == NULL) {\r
@@ -248,7 +243,7 @@ UdfOpen (
     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
@@ -257,8 +252,12 @@ UdfOpen (
     &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
@@ -324,10 +323,11 @@ UdfRead (
   UDF_FILE_INFO                   FoundFile;\r
   UDF_FILE_IDENTIFIER_DESCRIPTOR  *NewFileIdentifierDesc;\r
   VOID                            *NewFileEntryData;\r
-  CHAR16                          FileName[UDF_FILENAME_LENGTH] = { 0 };\r
+  CHAR16                          FileName[UDF_FILENAME_LENGTH];\r
   UINT64                          FileSize;\r
   UINT64                          BufferSizeUint64;\r
 \r
+  ZeroMem (FileName, sizeof FileName);\r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (This == NULL || BufferSize == NULL || (*BufferSize != 0 &&\r
@@ -407,6 +407,15 @@ UdfRead (
 \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
@@ -425,8 +434,9 @@ UdfRead (
     if (EFI_ERROR (Status)) {\r
       goto Error_Find_Fe;\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
@@ -442,7 +452,7 @@ UdfRead (
       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
@@ -454,7 +464,7 @@ UdfRead (
       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
@@ -485,6 +495,10 @@ UdfRead (
     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
@@ -526,7 +540,6 @@ UdfClose (
   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
@@ -539,8 +552,6 @@ UdfClose (
 \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
@@ -549,10 +560,6 @@ UdfClose (
     }\r
   }\r
 \r
-  if (--PrivFsData->OpenFiles == 0) {\r
-    CleanupVolumeInformation (&PrivFsData->Volume);\r
-  }\r
-\r
   FreePool ((VOID *)PrivFileData);\r
 \r
 Exit:\r
@@ -649,7 +656,7 @@ UdfGetPosition (
   // 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
@@ -690,7 +697,8 @@ UdfSetPosition (
 \r
   PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);\r
 \r
-  FileIdentifierDesc = PrivFileData->File.FileIdentifierDesc;\r
+  FileIdentifierDesc = _FILE (PrivFileData)->FileIdentifierDesc;\r
+  ASSERT (FileIdentifierDesc != NULL);\r
   if (IS_FID_DIRECTORY_FILE (FileIdentifierDesc)) {\r
     //\r
     // If the file handle is a directory, the _only_ position that may be set is\r
@@ -708,7 +716,7 @@ UdfSetPosition (
     // 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
@@ -748,19 +756,16 @@ UdfGetInfo (
   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
@@ -782,43 +787,11 @@ UdfGetInfo (
       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 |= *(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
@@ -827,8 +800,11 @@ UdfGetInfo (
     }\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
@@ -843,12 +819,32 @@ UdfGetInfo (
     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
@@ -857,7 +853,7 @@ UdfGetInfo (
 /**\r
   Set information about a file.\r
 \r
-  @param  File            Protocol instance pointer.\r
+  @param  This            Protocol instance pointer.\r
   @param  InformationType Type of information in Buffer.\r
   @param  BufferSize      Size of buffer.\r
   @param  Buffer          The data to write.\r