]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/Common/FvLib.c
Sync BaseTool trunk (version r2610) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / C / Common / FvLib.c
index 1b289d83cd62a921497968abd10f713201399689..4758749dc363d9885613120f2f4fc4c2b31d4bcb 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -181,7 +181,7 @@ Returns:
       //\r
       // Verify file is in this FV.\r
       //\r
-      if ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength) {\r
+      if ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength) {\r
         *NextFile = NULL;\r
         return EFI_SUCCESS;\r
       }\r
@@ -194,20 +194,20 @@ Returns:
   // Verify current file is in range\r
   //\r
   if (((UINTN) CurrentFile < (UINTN) mFvHeader + mFvHeader->HeaderLength) ||\r
-      ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength)\r
+      ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength)\r
      ) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   //\r
   // Get next file, compensate for 8 byte alignment if necessary.\r
   //\r
-  *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3)) + (UINT8 *) mFvHeader);\r
+  *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetFfsFileLength(CurrentFile) + 0x07) & (-1 << 3)) + (UINT8 *) mFvHeader);\r
 \r
   //\r
   // Verify file is in this FV.\r
   //\r
-  if (((UINTN) *NextFile + sizeof (EFI_FFS_FILE_HEADER) >= (UINTN) mFvHeader + mFvLength) ||\r
-      ((UINTN) *NextFile + GetLength ((*NextFile)->Size) > (UINTN) mFvHeader + mFvLength)\r
+  if (((UINTN) *NextFile + GetFfsHeaderLength(*NextFile) >= (UINTN) mFvHeader + mFvLength) ||\r
+      ((UINTN) *NextFile + GetFfsFileLength (*NextFile) > (UINTN) mFvHeader + mFvLength)\r
      ) {\r
     *NextFile = NULL;\r
     return EFI_SUCCESS;\r
@@ -434,7 +434,11 @@ Returns:
   EFI_FILE_SECTION_POINTER  InnerSection;\r
   EFI_STATUS                Status;\r
   UINTN                     SectionSize;\r
+  UINT16                    GuidSecAttr;\r
+  UINT16                    GuidDataOffset;\r
 \r
+  GuidSecAttr = 0;\r
+  GuidDataOffset = 0;\r
   CurrentSection = FirstSection;\r
 \r
   while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {\r
@@ -452,14 +456,21 @@ Returns:
     // special processing, go ahead to search the requesting\r
     // section inside the GUID-defined section.\r
     //\r
+    if (CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED) {\r
+      if (GetLength(CurrentSection.CommonHeader->Size) == 0xffffff) {\r
+        GuidSecAttr = CurrentSection.GuidDefinedSection2->Attributes;\r
+        GuidDataOffset = CurrentSection.GuidDefinedSection2->DataOffset;\r
+      } else {\r
+        GuidSecAttr = CurrentSection.GuidDefinedSection->Attributes;\r
+        GuidDataOffset = CurrentSection.GuidDefinedSection->DataOffset;\r
+      }\r
+    }\r
     if (SectionType != EFI_SECTION_GUID_DEFINED &&\r
         CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&\r
-        !(CurrentSection.GuidDefinedSection->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {\r
+        !(GuidSecAttr & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {\r
       InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)\r
-        ((UINTN) CurrentSection.CommonHeader + CurrentSection.GuidDefinedSection->DataOffset);\r
-      SectionSize = CurrentSection.CommonHeader->Size[0] +\r
-        (CurrentSection.CommonHeader->Size[1] << 8) + \r
-        (CurrentSection.CommonHeader->Size[2] << 16);\r
+        ((UINTN) CurrentSection.CommonHeader + GuidDataOffset);\r
+      SectionSize = GetSectionFileLength(CurrentSection.CommonHeader);\r
       Status = SearchSectionByType (\r
                  InnerSection,\r
                  (UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),\r
@@ -475,7 +486,7 @@ Returns:
     //\r
     // Find next section (including compensating for alignment issues.\r
     //\r
-    CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));\r
+    CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetSectionFileLength(CurrentSection.CommonHeader) + 0x03) & (-1 << 2));\r
   }\r
 \r
   return EFI_NOT_FOUND;\r
@@ -538,14 +549,14 @@ Returns:
   //\r
   // Get the first section\r
   //\r
-  CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER));\r
+  CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + GetFfsHeaderLength(File));\r
   \r
   //\r
   // Depth-first manner to find section file.\r
   //\r
   Status = SearchSectionByType (\r
              CurrentSection,\r
-             (UINT8 *) ((UINTN) File + GetLength (File->Size)),\r
+             (UINT8 *) ((UINTN) File + GetFfsFileLength (File)),\r
              SectionType,\r
              &SectionCount,\r
              Instance,\r
@@ -639,12 +650,14 @@ Returns:
 {\r
   BOOLEAN             ErasePolarity;\r
   EFI_STATUS          Status;\r
-  EFI_FFS_FILE_HEADER BlankHeader;\r
+  EFI_FFS_FILE_HEADER2 BlankHeader;\r
   UINT8               Checksum;\r
   UINT32              FileLength;\r
   UINT8               SavedChecksum;\r
   UINT8               SavedState;\r
   UINT8               FileGuidString[80];\r
+  UINT32              FfsHeaderSize;\r
+\r
   //\r
   // Verify library has been initialized.\r
   //\r
@@ -665,16 +678,18 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return EFI_ABORTED;\r
   }\r
+\r
+  FfsHeaderSize = GetFfsHeaderLength(FfsHeader);\r
   //\r
   // Check if we have free space\r
   //\r
   if (ErasePolarity) {\r
-    memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER));\r
+    memset (&BlankHeader, -1, FfsHeaderSize);\r
   } else {\r
-    memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER));\r
+    memset (&BlankHeader, 0, FfsHeaderSize);\r
   }\r
 \r
-  if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) {\r
+  if (memcmp (&BlankHeader, FfsHeader, FfsHeaderSize) == 0) {\r
     return EFI_NOT_FOUND;\r
   }\r
   //\r
@@ -689,7 +704,7 @@ Returns:
   FfsHeader->State = 0;\r
   SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File;\r
   FfsHeader->IntegrityCheck.Checksum.File = 0;\r
-  Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));\r
+  Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FfsHeaderSize);\r
   FfsHeader->State = SavedState;\r
   FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum;\r
   if (Checksum != 0) {\r
@@ -703,8 +718,8 @@ Returns:
     //\r
     // Verify file data checksum\r
     //\r
-    FileLength          = GetLength (FfsHeader->Size);\r
-    Checksum            = CalculateSum8 ((UINT8 *) (FfsHeader + 1), FileLength - sizeof (EFI_FFS_FILE_HEADER));\r
+    FileLength          = GetFfsFileLength (FfsHeader);\r
+    Checksum            = CalculateSum8 ((UINT8 *) ((UINT8 *)FfsHeader + FfsHeaderSize), FileLength - FfsHeaderSize);\r
     Checksum            = Checksum + FfsHeader->IntegrityCheck.Checksum.File;\r
     if (Checksum != 0) {\r
       Error (NULL, 0, 0006, "invalid FFS file checksum", "Ffs file with Guid %s", FileGuidString);\r
@@ -724,6 +739,80 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+UINT32\r
+GetFfsHeaderLength(\r
+   IN EFI_FFS_FILE_HEADER *FfsHeader\r
+   )\r
+{\r
+  if (FfsHeader == NULL) {\r
+    return 0;\r
+  }\r
+  if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {\r
+    return sizeof(EFI_FFS_FILE_HEADER2);\r
+  }\r
+  return sizeof(EFI_FFS_FILE_HEADER);\r
+}\r
+\r
+UINT32\r
+GetSectionHeaderLength(\r
+   IN EFI_COMMON_SECTION_HEADER *SectionHeader\r
+   )\r
+{\r
+  if (SectionHeader == NULL) {\r
+    return 0;\r
+  }\r
+  if (GetLength(SectionHeader->Size) == 0xffffff) {\r
+    return sizeof(EFI_COMMON_SECTION_HEADER2);\r
+  }\r
+  return sizeof(EFI_COMMON_SECTION_HEADER);\r
+}\r
+\r
+UINT32\r
+GetFfsFileLength (\r
+  EFI_FFS_FILE_HEADER *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get FFS file length including FFS header.\r
+\r
+Arguments:\r
+\r
+  FfsHeader   Pointer to EFI_FFS_FILE_HEADER.\r
+\r
+Returns:\r
+\r
+  UINT32      Length of FFS file header.\r
+\r
+--*/\r
+{\r
+  if (FfsHeader == NULL) {\r
+    return 0;\r
+  }\r
+  if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {\r
+    return ((EFI_FFS_FILE_HEADER2 *)FfsHeader)->ExtendedSize;\r
+  } else {\r
+    return GetLength(FfsHeader->Size);\r
+  }\r
+}\r
+\r
+UINT32\r
+GetSectionFileLength (\r
+  EFI_COMMON_SECTION_HEADER *SectionHeader\r
+  )\r
+{\r
+  UINT32 Length;\r
+  if (SectionHeader == NULL) {\r
+    return 0;\r
+  }\r
+  Length = GetLength(SectionHeader->Size);\r
+  if (Length == 0xffffff) {\r
+    Length = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;\r
+  }\r
+  return Length;\r
+}\r
+\r
 UINT32\r
 GetLength (\r
   UINT8     *ThreeByteLength\r