]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolWrite.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / FirmwareVolume / FwVolDxe / FwVolWrite.c
index 5c7e8abf75aa5c35aebdfd96cafe44c81452df06..adb910e9602e6dd0a858495536dd9b614498b2a8 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implements write firmware file.\r
 \r
-  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions\r
@@ -17,9 +17,9 @@
 #include "FwVolDriver.h"\r
 \r
 /**\r
-  Caculate the checksum for the FFS header.\r
+  Calculate the checksum for the FFS header.\r
 \r
-  @param FfsHeader   FFS File Header which needs to caculate the checksum\r
+  @param FfsHeader   FFS File Header which needs to calculate the checksum\r
 \r
 **/\r
 VOID\r
@@ -28,7 +28,6 @@ SetHeaderChecksum (
   )\r
 {\r
   EFI_FFS_FILE_STATE  State;\r
-  UINT8               HeaderChecksum;\r
   UINT8               FileChecksum;\r
 \r
   //\r
@@ -42,12 +41,17 @@ SetHeaderChecksum (
 \r
   FfsHeader->IntegrityCheck.Checksum.Header = 0;\r
 \r
-  HeaderChecksum = CalculateSum8 (\r
-    (UINT8 *)FfsHeader,\r
-    sizeof (EFI_FFS_FILE_HEADER)\r
-    );\r
-\r
-  FfsHeader->IntegrityCheck.Checksum.Header = (UINT8) (~HeaderChecksum + 1);\r
+  if (IS_FFS_FILE2 (FfsHeader)) {\r
+    FfsHeader->IntegrityCheck.Checksum.Header = CalculateCheckSum8 (\r
+      (UINT8 *) FfsHeader,\r
+      sizeof (EFI_FFS_FILE_HEADER2)\r
+      );\r
+  } else {\r
+    FfsHeader->IntegrityCheck.Checksum.Header = CalculateCheckSum8 (\r
+      (UINT8 *) FfsHeader,\r
+      sizeof (EFI_FFS_FILE_HEADER)\r
+      );\r
+  }\r
 \r
   FfsHeader->State                          = State;\r
   FfsHeader->IntegrityCheck.Checksum.File   = FileChecksum;\r
@@ -56,9 +60,9 @@ SetHeaderChecksum (
 }\r
 \r
 /**\r
-  Caculate the checksum for the FFS File.\r
+  Calculate the checksum for the FFS File.\r
 \r
-  @param FfsHeader       FFS File Header which needs to caculate the checksum\r
+  @param FfsHeader       FFS File Header which needs to calculate the checksum\r
   @param ActualFileSize  The whole Ffs File Length.\r
 \r
 **/\r
@@ -68,29 +72,21 @@ SetFileChecksum (
   IN UINTN               ActualFileSize\r
   )\r
 {\r
-  EFI_FFS_FILE_STATE  State;\r
-  UINT8               FileChecksum;\r
-\r
   if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) != 0) {\r
-    //\r
-    // The file state is not included\r
-    //\r
-    State = FfsHeader->State;\r
-    FfsHeader->State = 0;\r
 \r
     FfsHeader->IntegrityCheck.Checksum.File = 0;\r
 \r
-    //\r
-    // File checksum \r
-    //\r
-    FileChecksum = CalculateSum8 (\r
-      (UINT8 *)(FfsHeader + 1),\r
-               ActualFileSize - sizeof (EFI_FFS_FILE_HEADER)\r
-      );\r
-\r
-    FfsHeader->IntegrityCheck.Checksum.File = (UINT8) (~FileChecksum + 1);\r
-\r
-    FfsHeader->State                        = State;\r
+    if (IS_FFS_FILE2 (FfsHeader)) {\r
+      FfsHeader->IntegrityCheck.Checksum.File = CalculateCheckSum8 (\r
+        (UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2),\r
+        ActualFileSize - sizeof (EFI_FFS_FILE_HEADER2)\r
+        );\r
+    } else {\r
+      FfsHeader->IntegrityCheck.Checksum.File = CalculateCheckSum8 (\r
+        (UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER),\r
+        ActualFileSize - sizeof (EFI_FFS_FILE_HEADER)\r
+        );\r
+    }\r
 \r
   } else {\r
 \r
@@ -134,19 +130,21 @@ GetRequiredAlignment (
 }\r
 \r
 /**\r
-  Caculate the leading Pad file size to meet the alignment requirement.\r
+  Calculate the leading Pad file size to meet the alignment requirement.\r
 \r
   @param FvDevice          Cached Firmware Volume.\r
   @param StartAddress      The starting address to write the FFS File.\r
+  @param BufferSize        The FFS File Buffer Size.\r
   @param RequiredAlignment FFS File Data alignment requirement.\r
 \r
   @return The required Pad File Size.\r
 \r
 **/\r
 UINTN\r
-CaculatePadFileSize (\r
+CalculatePadFileSize (\r
   IN FV_DEVICE            *FvDevice,\r
   IN EFI_PHYSICAL_ADDRESS StartAddress,\r
+  IN UINTN                BufferSize,\r
   IN UINTN                RequiredAlignment\r
   )\r
 {\r
@@ -154,7 +152,11 @@ CaculatePadFileSize (
   UINTN RelativePos;\r
   UINTN PadSize;\r
 \r
-  DataStartPos  = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER);\r
+  if (BufferSize > 0x00FFFFFF) {\r
+    DataStartPos  = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER2);\r
+  } else {\r
+    DataStartPos  = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER);\r
+  }\r
   RelativePos   = DataStartPos - (UINTN) FvDevice->CachedFv;\r
 \r
   PadSize       = 0;\r
@@ -200,9 +202,11 @@ FvFileAttrib2FfsFileAttrib (
 {\r
   UINT8 FvFileAlignment;\r
   UINT8 FfsFileAlignment;\r
+  UINT8 FfsFileAlignment2;\r
 \r
   FvFileAlignment   = (UINT8) (FvFileAttrib & EFI_FV_FILE_ATTRIB_ALIGNMENT);\r
   FfsFileAlignment  = 0;\r
+  FfsFileAlignment2 = 0;\r
 \r
   switch (FvFileAlignment) {\r
   case 0:\r
@@ -287,9 +291,42 @@ FvFileAttrib2FfsFileAttrib (
   case 16:\r
     FfsFileAlignment = 7;\r
     break;\r
+\r
+  case 17:\r
+    FfsFileAlignment = 0;\r
+    FfsFileAlignment2 = 1;\r
+    break;\r
+  case 18:\r
+    FfsFileAlignment = 1;\r
+    FfsFileAlignment2 = 1;\r
+    break;\r
+  case 19:\r
+    FfsFileAlignment = 2;\r
+    FfsFileAlignment2 = 1;\r
+    break;\r
+  case 20:\r
+    FfsFileAlignment = 3;\r
+    FfsFileAlignment2 = 1;\r
+    break;\r
+  case 21:\r
+    FfsFileAlignment = 4;\r
+    FfsFileAlignment2 = 1;\r
+    break;\r
+  case 22:\r
+    FfsFileAlignment = 5;\r
+    FfsFileAlignment2 = 1;\r
+    break;\r
+  case 23:\r
+    FfsFileAlignment = 6;\r
+    FfsFileAlignment2 = 1;\r
+    break;\r
+  case 24:\r
+    FfsFileAlignment = 7;\r
+    FfsFileAlignment2 = 1;\r
+    break;\r
   }\r
 \r
-  *FfsFileAttrib = (UINT8) (FfsFileAlignment << 3);\r
+  *FfsFileAttrib = (UINT8) ((FfsFileAlignment << 3) | (FfsFileAlignment2 << 1));\r
 \r
   return ;\r
 }\r
@@ -328,9 +365,10 @@ FvLocateFreeSpaceEntry (
   // required the file size\r
   //\r
   while ((LIST_ENTRY *) FreeSpaceListEntry != &FvDevice->FreeSpaceHeader) {\r
-    PadFileSize = CaculatePadFileSize (\r
+    PadFileSize = CalculatePadFileSize (\r
                     FvDevice,\r
                     (EFI_PHYSICAL_ADDRESS) (UINTN) FreeSpaceListEntry->StartingAddress,\r
+                    Size,\r
                     RequiredAlignment\r
                     );\r
     if (FreeSpaceListEntry->Length >= Size + PadFileSize) {\r
@@ -346,54 +384,6 @@ FvLocateFreeSpaceEntry (
 \r
 }\r
 \r
-/**\r
-  Locate a free space that can hold this file.\r
-\r
-  @param FvDevice           Cached Firmware Volume.\r
-  @param Size               On input, it is the required size.\r
-                            On output, it is the actual size of free space.\r
-  @param RequiredAlignment  FFS File Data alignment requirement.\r
-  @param PadSize            Pointer to the size of leading Pad File.\r
-  @param StartingAddress    The starting address of the Free Space Entry\r
-                            that meets the requirement.\r
-\r
-  @retval EFI_SUCCESS     The free space is found.\r
-  @retval EFI_NOT_FOUND   The free space can't be found.\r
-\r
-**/\r
-EFI_STATUS\r
-FvLocateFreeSpace (\r
-  IN  FV_DEVICE             *FvDevice,\r
-  IN  OUT UINTN             *Size,\r
-  IN  UINTN                 RequiredAlignment,\r
-  OUT UINTN                 *PadSize,\r
-  OUT EFI_PHYSICAL_ADDRESS  *StartingAddress\r
-  )\r
-{\r
-  EFI_STATUS        Status;\r
-  FREE_SPACE_ENTRY  *FreeSpaceEntry;\r
-\r
-  //\r
-  // First find the free space entry\r
-  //\r
-  Status = FvLocateFreeSpaceEntry (\r
-            FvDevice,\r
-            *Size,\r
-            RequiredAlignment,\r
-            PadSize,\r
-            &FreeSpaceEntry\r
-            );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  *Size             = FreeSpaceEntry->Length;\r
-  *StartingAddress  = (EFI_PHYSICAL_ADDRESS) (UINTN) FreeSpaceEntry->StartingAddress;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
 /**\r
   Locate Pad File for writing, this is got from FV Cache.\r
 \r
@@ -419,9 +409,9 @@ FvLocatePadFile (
   FFS_FILE_LIST_ENTRY *FileEntry;\r
   EFI_FFS_FILE_STATE  FileState;\r
   EFI_FFS_FILE_HEADER *FileHeader;\r
-  UINTN               FileLength;\r
   UINTN               PadAreaLength;\r
   UINTN               PadFileSize;\r
+  UINTN               HeaderSize;\r
 \r
   FileEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->FfsFileListHeader.ForwardLink;\r
 \r
@@ -437,12 +427,18 @@ FvLocatePadFile (
       //\r
       // we find one valid pad file, check its free area length\r
       //\r
-      FileLength    = *(UINT32 *) FileHeader->Size & 0x00FFFFFF;\r
-      PadAreaLength = FileLength - sizeof (EFI_FFS_FILE_HEADER);\r
+      if (IS_FFS_FILE2 (FileHeader)) {\r
+        HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);\r
+        PadAreaLength = FFS_FILE2_SIZE (FileHeader) - HeaderSize;\r
+      } else {\r
+        HeaderSize = sizeof (EFI_FFS_FILE_HEADER);\r
+        PadAreaLength = FFS_FILE_SIZE (FileHeader) - HeaderSize;\r
+      }\r
 \r
-      PadFileSize = CaculatePadFileSize (\r
+      PadFileSize = CalculatePadFileSize (\r
                       FvDevice,\r
-                      (EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER),\r
+                      (EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + HeaderSize,\r
+                      Size,\r
                       RequiredAlignment\r
                       );\r
       if (PadAreaLength >= (Size + PadFileSize)) {\r
@@ -487,10 +483,10 @@ FvSearchSuitablePadFile (
   FFS_FILE_LIST_ENTRY *FileEntry;\r
   EFI_FFS_FILE_STATE  FileState;\r
   EFI_FFS_FILE_HEADER *FileHeader;\r
-  UINTN               FileLength;\r
   UINTN               PadAreaLength;\r
   UINTN               TotalSize;\r
   UINTN               Index;\r
+  UINTN               HeaderSize;\r
 \r
   FileEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->FfsFileListHeader.ForwardLink;\r
 \r
@@ -506,14 +502,20 @@ FvSearchSuitablePadFile (
       //\r
       // we find one valid pad file, check its length\r
       //\r
-      FileLength    = *(UINT32 *) FileHeader->Size & 0x00FFFFFF;\r
-      PadAreaLength = FileLength - sizeof (EFI_FFS_FILE_HEADER);\r
+      if (IS_FFS_FILE2 (FileHeader)) {\r
+        HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);\r
+        PadAreaLength = FFS_FILE2_SIZE (FileHeader) - HeaderSize;\r
+      } else {\r
+        HeaderSize = sizeof (EFI_FFS_FILE_HEADER);\r
+        PadAreaLength = FFS_FILE_SIZE (FileHeader) - HeaderSize;\r
+      }\r
       TotalSize     = 0;\r
 \r
       for (Index = 0; Index < NumOfFiles; Index++) {\r
-        PadSize[Index] = CaculatePadFileSize (\r
+        PadSize[Index] = CalculatePadFileSize (\r
                       FvDevice,\r
-                      (EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER) + TotalSize,\r
+                      (EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + HeaderSize + TotalSize,\r
+                      BufferSize[Index],\r
                       RequiredAlignment[Index]\r
                       );\r
         TotalSize += PadSize[Index];\r
@@ -579,16 +581,17 @@ FvSearchSuitableFreeSpace (
     StartAddr = FreeSpaceListEntry->StartingAddress;\r
 \r
     //\r
-    // Caculate the totalsize we need\r
+    // Calculate the totalsize we need\r
     //\r
     for (Index = 0; Index < NumOfFiles; Index++) {\r
       //\r
       // Perhaps we don't need an EFI_FFS_FILE_HEADER, the first file\r
       // have had its leading pad file.\r
       //\r
-      PadSize[Index] = CaculatePadFileSize (\r
+      PadSize[Index] = CalculatePadFileSize (\r
                     FvDevice,\r
                     (EFI_PHYSICAL_ADDRESS) (UINTN) StartAddr + TotalSize,\r
+                    BufferSize[Index],\r
                     RequiredAlignment[Index]\r
                     );\r
 \r
@@ -707,7 +710,7 @@ FvcWrite (
   UINTN                               RemainingLength;\r
   UINTN                               WriteLength;\r
   UINT8                               *TmpBuffer;\r
-  \r
+\r
   LOffset = 0;\r
   RemainingLength = CalculateRemainingLength (FvDevice, Offset, &Lba, &LOffset);\r
   if ((UINTN) (*NumBytes) > RemainingLength) {\r
@@ -725,7 +728,7 @@ FvcWrite (
     return Status;\r
   }\r
 \r
-  if ((FvbAttributes & EFI_FV2_WRITE_STATUS) != 0) {\r
+  if ((FvbAttributes & EFI_FV2_WRITE_STATUS) == 0) {\r
     return EFI_ACCESS_DENIED;\r
   }\r
 \r
@@ -803,6 +806,7 @@ FvCreateNewFile (
   FFS_FILE_LIST_ENTRY                 *PadFileEntry;\r
   EFI_FFS_FILE_ATTRIBUTES             TmpFileAttribute;\r
   FFS_FILE_LIST_ENTRY                 *FfsFileEntry;\r
+  UINTN                               HeaderSize;\r
 \r
   //\r
   // File Type: 0x0E~0xE0 are reserved\r
@@ -813,7 +817,7 @@ FvCreateNewFile (
 \r
   //\r
   // First find a free space that can hold this image.\r
-  // Check alignment, FFS at least must be aligned at 8-byte boundry\r
+  // Check alignment, FFS at least must be aligned at 8-byte boundary\r
   //\r
   RequiredAlignment = GetRequiredAlignment (FileAttributes);\r
 \r
@@ -869,6 +873,11 @@ FvCreateNewFile (
   // Write Name, IntegrityCheck.Header, Type, Attributes, and Size\r
   //\r
   FileHeader = (EFI_FFS_FILE_HEADER *) FfsFileBuffer;\r
+  if (ActualFileSize > 0x00FFFFFF) {\r
+    HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);\r
+  } else {\r
+    HeaderSize = sizeof (EFI_FFS_FILE_HEADER);\r
+  }\r
   SetFileState (EFI_FILE_HEADER_CONSTRUCTION, FileHeader);\r
 \r
   Offset          = (UINTN) (BufferPtr - FvDevice->CachedFv);\r
@@ -890,14 +899,14 @@ FvCreateNewFile (
   CopyMem (\r
     (UINT8 *) (UINTN) BufferPtr,\r
     FileHeader,\r
-    sizeof (EFI_FFS_FILE_HEADER)\r
+    HeaderSize\r
     );\r
 \r
   //\r
-  // update Free Space Entry, now need to substract the EFI_FFS_FILE_HEADER\r
+  // update Free Space Entry, now need to substract the file header length\r
   //\r
-  FreeSpaceEntry->StartingAddress += sizeof (EFI_FFS_FILE_HEADER);\r
-  FreeSpaceEntry->Length -= sizeof (EFI_FFS_FILE_HEADER);\r
+  FreeSpaceEntry->StartingAddress += HeaderSize;\r
+  FreeSpaceEntry->Length -= HeaderSize;\r
 \r
   CopyGuid (&FileHeader->Name, FileName);\r
   FileHeader->Type = FileType;\r
@@ -912,14 +921,20 @@ FvCreateNewFile (
   //\r
   // File size is including the FFS File Header.\r
   //\r
-  *(UINT32 *) FileHeader->Size &= 0xFF000000;\r
-  *(UINT32 *) FileHeader->Size |= ActualFileSize;\r
+  if (ActualFileSize > 0x00FFFFFF) {\r
+    ((EFI_FFS_FILE_HEADER2 *) FileHeader)->ExtendedSize = (UINT32) ActualFileSize;\r
+    *(UINT32 *) FileHeader->Size &= 0xFF000000;\r
+    FileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE;\r
+  } else {\r
+    *(UINT32 *) FileHeader->Size &= 0xFF000000;\r
+    *(UINT32 *) FileHeader->Size |= ActualFileSize;\r
+  }\r
 \r
   SetHeaderChecksum (FileHeader);\r
 \r
   Offset          = (UINTN) (BufferPtr - FvDevice->CachedFv);\r
 \r
-  NumBytesWritten = sizeof (EFI_FFS_FILE_HEADER);\r
+  NumBytesWritten = HeaderSize;\r
   Status = FvcWrite (\r
             FvDevice,\r
             Offset,\r
@@ -935,7 +950,7 @@ FvCreateNewFile (
   CopyMem (\r
     (UINT8 *) (UINTN) BufferPtr,\r
     FileHeader,\r
-    sizeof (EFI_FFS_FILE_HEADER)\r
+    HeaderSize\r
     );\r
 \r
   //\r
@@ -966,17 +981,17 @@ FvCreateNewFile (
   CopyMem (\r
     (UINT8 *) (UINTN) BufferPtr,\r
     FileHeader,\r
-    sizeof (EFI_FFS_FILE_HEADER)\r
+    HeaderSize\r
     );\r
 \r
   //\r
   // update Free Space Entry, now need to substract the file data length\r
   //\r
-  FreeSpaceEntry->StartingAddress += (BufferSize - sizeof (EFI_FFS_FILE_HEADER));\r
-  FreeSpaceEntry->Length -= (BufferSize - sizeof (EFI_FFS_FILE_HEADER));\r
+  FreeSpaceEntry->StartingAddress += (BufferSize - HeaderSize);\r
+  FreeSpaceEntry->Length -= (BufferSize - HeaderSize);\r
 \r
   //\r
-  // Caculate File Checksum\r
+  // Calculate File Checksum\r
   //\r
   SetFileChecksum (FileHeader, ActualFileSize);\r
 \r
@@ -1025,7 +1040,7 @@ FvCreateNewFile (
   CopyMem (\r
     (UINT8 *) (UINTN) BufferPtr,\r
     FileHeader,\r
-    sizeof (EFI_FFS_FILE_HEADER)\r
+    HeaderSize\r
     );\r
 \r
   //\r
@@ -1381,6 +1396,7 @@ FvWriteFile (
   UINTN                               NumDelete;\r
   EFI_FV_ATTRIBUTES                   FvAttributes;\r
   UINT32                              AuthenticationStatus;\r
+  UINTN                               HeaderSize;\r
 \r
   if (NumberOfFiles > MAX_FILES) {\r
     return EFI_UNSUPPORTED;\r
@@ -1405,7 +1421,7 @@ FvWriteFile (
   //\r
   // Can we have write right?\r
   //\r
-  if ((FvAttributes & EFI_FV2_WRITE_STATUS) != 0) {\r
+  if ((FvAttributes & EFI_FV2_WRITE_STATUS) == 0) {\r
     return EFI_WRITE_PROTECTED;\r
   }\r
 \r
@@ -1416,6 +1432,15 @@ FvWriteFile (
   //\r
   NumDelete = 0;\r
   for (Index1 = 0; Index1 < NumberOfFiles; Index1++) {\r
+\r
+    if ((FileData[Index1].BufferSize + sizeof (EFI_FFS_FILE_HEADER) > 0x00FFFFFF) && !FvDevice->IsFfs3Fv) {\r
+      //\r
+      // Found a file needs a FFS3 formatted file to store it, but it is in a non-FFS3 formatted FV.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "FFS3 formatted file can't be written in a non-FFS3 formatted FV.\n"));\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
     if (FileData[Index1].BufferSize == 0) {\r
       //\r
       // Here we will delete this file\r
@@ -1438,8 +1463,8 @@ FvWriteFile (
 \r
     if (FileData[Index1].Type == EFI_FV_FILETYPE_FFS_PAD) {\r
       //\r
-      // According to PI spec, on EFI_FV_FILETYPE_FFS_PAD: \r
-      // "Standard firmware file system services will not return the handle of any pad files, \r
+      // According to PI spec, on EFI_FV_FILETYPE_FFS_PAD:\r
+      // "Standard firmware file system services will not return the handle of any pad files,\r
       // nor will they permit explicit creation of such files."\r
       //\r
       return EFI_INVALID_PARAMETER;\r
@@ -1523,9 +1548,14 @@ FvWriteFile (
 \r
   for (Index1 = 0; Index1 < NumberOfFiles; Index1++) {\r
     //\r
-    // Making Buffersize QWORD boundry, and add file tail.\r
+    // Making Buffersize QWORD boundary, and add file tail.\r
     //\r
-    ActualSize  = FileData[Index1].BufferSize + sizeof (EFI_FFS_FILE_HEADER);\r
+    HeaderSize = sizeof (EFI_FFS_FILE_HEADER);\r
+    ActualSize = FileData[Index1].BufferSize + HeaderSize;\r
+    if (ActualSize > 0x00FFFFFF) {\r
+      HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);\r
+      ActualSize = FileData[Index1].BufferSize + HeaderSize;\r
+    }\r
     BufferSize  = ActualSize;\r
 \r
     while ((BufferSize & 0x07) != 0) {\r
@@ -1540,7 +1570,7 @@ FvWriteFile (
     // Copy File Data into FileBuffer\r
     //\r
     CopyMem (\r
-      FileBuffer + sizeof (EFI_FFS_FILE_HEADER),\r
+      FileBuffer + HeaderSize,\r
       FileData[Index1].Buffer,\r
       FileData[Index1].BufferSize\r
       );\r
@@ -1549,7 +1579,7 @@ FvWriteFile (
       //\r
       // Fill the file header and padding byte with Erase Byte\r
       //\r
-      for (Index2 = 0; Index2 < sizeof (EFI_FFS_FILE_HEADER); Index2++) {\r
+      for (Index2 = 0; Index2 < HeaderSize; Index2++) {\r
         FileBuffer[Index2] = (UINT8)~FileBuffer[Index2];\r
       }\r
 \r