/** @file
  Implements functions to pad firmware file.

  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions
  of the BSD License which accompanies this distribution.  The
  full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "FwVolDriver.h"

/**
  Calculate the checksum for a PAD file.

  @param PadFileHeader   The Pad File to be caculeted the checksum.

**/
VOID
SetPadFileChecksum (
  IN EFI_FFS_FILE_HEADER *PadFileHeader
  )
{
  if ((PadFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) != 0) {

    if (IS_FFS_FILE2 (PadFileHeader)) {
      //
      // Calculate checksum of Pad File Data
      //
      PadFileHeader->IntegrityCheck.Checksum.File =
        CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (PadFileHeader) - sizeof (EFI_FFS_FILE_HEADER2));

      } else {
      //
      // Calculate checksum of Pad File Data
      //
      PadFileHeader->IntegrityCheck.Checksum.File =
        CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (PadFileHeader) - sizeof (EFI_FFS_FILE_HEADER));
    }

  } else {

    PadFileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

  }

  return ;
}

/**
  Create a PAD File in the Free Space.

  @param FvDevice        Firmware Volume Device.
  @param FreeSpaceEntry  Indicating in which Free Space(Cache) the Pad file will be inserted.
  @param Size            Pad file Size, not include the header.
  @param PadFileEntry    The Ffs File Entry that points to this Pad File.

  @retval EFI_SUCCESS            Successfully create a PAD file.
  @retval EFI_OUT_OF_RESOURCES   No enough free space to create a PAD file.
  @retval EFI_INVALID_PARAMETER  Size is not 8 byte alignment.
  @retval EFI_DEVICE_ERROR       Free space is not erased.
**/
EFI_STATUS
FvCreatePadFileInFreeSpace (
  IN  FV_DEVICE           *FvDevice,
  IN  FREE_SPACE_ENTRY    *FreeSpaceEntry,
  IN  UINTN               Size,
  OUT FFS_FILE_LIST_ENTRY **PadFileEntry
  )
{
  EFI_STATUS                          Status;
  EFI_FFS_FILE_HEADER                 *PadFileHeader;
  UINTN                               Offset;
  UINTN                               NumBytesWritten;
  UINTN                               StateOffset;
  UINT8                               *StartPos;
  FFS_FILE_LIST_ENTRY                 *FfsFileEntry;
  UINTN                               HeaderSize;
  UINTN                               FileSize;

  HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
  FileSize = Size + HeaderSize;
  if (FileSize > 0x00FFFFFF) {
    HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
    FileSize = Size + HeaderSize;
  }

  if (FreeSpaceEntry->Length < FileSize) {
    return EFI_OUT_OF_RESOURCES;
  }

  if ((Size & 0x07) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  StartPos = FreeSpaceEntry->StartingAddress;

  //
  // First double check the space
  //
  if (!IsBufferErased (
        FvDevice->ErasePolarity,
        StartPos,
        FileSize
        )) {
    return EFI_DEVICE_ERROR;
  }

  PadFileHeader = (EFI_FFS_FILE_HEADER *) StartPos;

  //
  // Create File Step 1
  //
  SetFileState (EFI_FILE_HEADER_CONSTRUCTION, PadFileHeader);

  Offset          = (UINTN) (StartPos - FvDevice->CachedFv);
  StateOffset     = Offset + (UINT8 *) &PadFileHeader->State - (UINT8 *) PadFileHeader;

  NumBytesWritten = sizeof (EFI_FFS_FILE_STATE);
  Status = FvcWrite (
            FvDevice,
            StateOffset,
            &NumBytesWritten,
            &PadFileHeader->State
            );
  if (EFI_ERROR (Status)) {
    SetFileState (EFI_FILE_HEADER_CONSTRUCTION, PadFileHeader);
    return Status;
  }
  //
  // Update Free Space Entry, since header is allocated
  //
  FreeSpaceEntry->Length -= HeaderSize;
  FreeSpaceEntry->StartingAddress += HeaderSize;

  //
  // Fill File Name Guid, here we assign a NULL-GUID to Pad files
  //
  ZeroMem (&PadFileHeader->Name, sizeof (EFI_GUID));

  //
  // Fill File Type, checksum(0), Attributes(0), Size
  //
  PadFileHeader->Type       = EFI_FV_FILETYPE_FFS_PAD;
  PadFileHeader->Attributes = 0;
  if ((FileSize) > 0x00FFFFFF) {
    ((EFI_FFS_FILE_HEADER2 *) PadFileHeader)->ExtendedSize = (UINT32) FileSize;
    *(UINT32 *) PadFileHeader->Size &= 0xFF000000;
    PadFileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE;
  } else {
    *(UINT32 *) PadFileHeader->Size &= 0xFF000000;
    *(UINT32 *) PadFileHeader->Size |= FileSize;
  }

  SetHeaderChecksum (PadFileHeader);
  SetPadFileChecksum (PadFileHeader);

  Offset          = (UINTN) (StartPos - FvDevice->CachedFv);

  NumBytesWritten = HeaderSize;
  Status = FvcWrite (
            FvDevice,
            Offset,
            &NumBytesWritten,
            (UINT8 *) PadFileHeader
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Step 2, then Mark header valid, since no data write,
  // mark the data valid at the same time.
  //
  SetFileState (EFI_FILE_HEADER_VALID, PadFileHeader);
  SetFileState (EFI_FILE_DATA_VALID, PadFileHeader);

  Offset          = (UINTN) (StartPos - FvDevice->CachedFv);
  StateOffset     = Offset + (UINT8 *) &PadFileHeader->State - (UINT8 *) PadFileHeader;

  NumBytesWritten = sizeof (EFI_FFS_FILE_STATE);
  Status = FvcWrite (
            FvDevice,
            StateOffset,
            &NumBytesWritten,
            &PadFileHeader->State
            );
  if (EFI_ERROR (Status)) {
    SetFileState (EFI_FILE_HEADER_VALID, PadFileHeader);
    SetFileState (EFI_FILE_DATA_VALID, PadFileHeader);
    return Status;
  }
  //
  // Update Free Space Entry, since header is allocated
  //
  FreeSpaceEntry->Length -= Size;
  FreeSpaceEntry->StartingAddress += Size;

  //
  // If successfully, insert an FfsFileEntry at the end of ffs file list
  //
  FfsFileEntry = AllocateZeroPool (sizeof (FFS_FILE_LIST_ENTRY));
  ASSERT (FfsFileEntry != NULL);

  FfsFileEntry->FfsHeader = (UINT8 *) (UINTN) StartPos;
  InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);

  *PadFileEntry             = FfsFileEntry;
  FvDevice->CurrentFfsFile  = FfsFileEntry;

  return EFI_SUCCESS;
}

/**
  Fill pad file header within firmware cache.
  
  @param PadFileHeader    The start of the Pad File Buffer.
  @param PadFileLength    The length of the pad file including the header.

**/
VOID
FvFillPadFile (
  IN EFI_FFS_FILE_HEADER  *PadFileHeader,
  IN UINTN                PadFileLength
  )
{
  //
  // Fill File Name Guid, here we assign a NULL-GUID to Pad files
  //
  ZeroMem (&PadFileHeader->Name, sizeof (EFI_GUID));

  //
  // Fill File Type, checksum(0), Attributes(0), Size
  //
  PadFileHeader->Type       = EFI_FV_FILETYPE_FFS_PAD;
  PadFileHeader->Attributes = 0;
  if (PadFileLength > 0x00FFFFFF) {
    ((EFI_FFS_FILE_HEADER2 *) PadFileHeader)->ExtendedSize = (UINT32) PadFileLength;
    *(UINT32 *) PadFileHeader->Size &= 0xFF000000;
    PadFileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE;
  } else {
    *(UINT32 *) PadFileHeader->Size &= 0xFF000000;
    *(UINT32 *) PadFileHeader->Size |= PadFileLength;
  }

  SetHeaderChecksum (PadFileHeader);
  SetPadFileChecksum (PadFileHeader);

  //
  // Set File State to 0x00000111
  //
  SetFileState (EFI_FILE_HEADER_CONSTRUCTION, PadFileHeader);
  SetFileState (EFI_FILE_HEADER_VALID, PadFileHeader);
  SetFileState (EFI_FILE_DATA_VALID, PadFileHeader);

  return ;
}

/**
  Create entire FFS file.
  
  @param FileHeader      Starting Address of a Buffer that hold the FFS File image.
  @param FfsFileBuffer   The source buffer that contains the File Data.
  @param BufferSize      The length of FfsFileBuffer.
  @param ActualFileSize  Size of FFS file.
  @param FileName        The Guid of Ffs File.
  @param FileType        The type of the written Ffs File.
  @param FileAttributes  The attributes of the written Ffs File.

  @retval EFI_INVALID_PARAMETER  File type is not valid.
  @retval EFI_SUCCESS            FFS file is successfully created.

**/
EFI_STATUS
FvFillFfsFile (
  OUT EFI_FFS_FILE_HEADER   *FileHeader,
  IN UINT8                  *FfsFileBuffer,
  IN UINTN                  BufferSize,
  IN UINTN                  ActualFileSize,
  IN EFI_GUID               *FileName,
  IN EFI_FV_FILETYPE        FileType,
  IN EFI_FV_FILE_ATTRIBUTES FileAttributes
  )
{
  EFI_FFS_FILE_ATTRIBUTES TmpFileAttribute;
  EFI_FFS_FILE_HEADER     *TmpFileHeader;

  //
  // File Type value 0x0E~0xE0 are reserved
  //
  if ((FileType > EFI_FV_FILETYPE_SMM_CORE) && (FileType < 0xE0)) {
    return EFI_INVALID_PARAMETER;
  }

  TmpFileHeader = (EFI_FFS_FILE_HEADER *) FfsFileBuffer;
  //
  // First fill all fields ready in FfsFileBuffer
  //
  CopyGuid (&TmpFileHeader->Name, FileName);
  TmpFileHeader->Type = FileType;

  //
  // Convert the FileAttributes to FFSFileAttributes
  //
  FvFileAttrib2FfsFileAttrib (FileAttributes, &TmpFileAttribute);

  TmpFileHeader->Attributes = TmpFileAttribute;

  if (ActualFileSize > 0x00FFFFFF) {
    ((EFI_FFS_FILE_HEADER2 *) FileHeader)->ExtendedSize = (UINT32) ActualFileSize;
    *(UINT32 *) FileHeader->Size &= 0xFF000000;
    FileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE;
  } else {
    *(UINT32 *) FileHeader->Size &= 0xFF000000;
    *(UINT32 *) FileHeader->Size |= ActualFileSize;
  }

  SetHeaderChecksum (TmpFileHeader);
  SetFileChecksum (TmpFileHeader, ActualFileSize);

  SetFileState (EFI_FILE_HEADER_CONSTRUCTION, TmpFileHeader);
  SetFileState (EFI_FILE_HEADER_VALID, TmpFileHeader);
  SetFileState (EFI_FILE_DATA_VALID, TmpFileHeader);

  //
  // Copy data from FfsFileBuffer to FileHeader(cache)
  //
  CopyMem (FileHeader, FfsFileBuffer, BufferSize);

  return EFI_SUCCESS;
}

/**
  Fill some other extra space using 0xFF(Erase Value).

  @param  ErasePolarity  Fv erase value.
  @param  FileHeader     Point to the start of FFS File.
  @param  ExtraLength    The pading length.

**/
VOID
FvAdjustFfsFile (
  IN  UINT8                 ErasePolarity,
  IN  EFI_FFS_FILE_HEADER   *FileHeader,
  IN  UINTN                 ExtraLength
  )
{
  UINT8 *Ptr;
  UINT8 PadingByte;

  if (IS_FFS_FILE2 (FileHeader)) {
    Ptr         = (UINT8 *) FileHeader + FFS_FILE2_SIZE (FileHeader);
  } else {
    Ptr         = (UINT8 *) FileHeader + FFS_FILE_SIZE (FileHeader);
  }

  if (ErasePolarity == 0) {
    PadingByte = 0;
  } else {
    PadingByte = 0xFF;
  }
  //
  // Fill the non-used space with Padding Byte
  //
  SetMem (Ptr, ExtraLength, PadingByte);

  return ;
}

/**
  Free File List entry pointed by FileListHead.

  @param FileListHeader   FileListEntry Header.

**/
VOID
FreeFileList (
  IN  LIST_ENTRY  *FileListHead
  )
{
  FFS_FILE_LIST_ENTRY *FfsFileEntry;
  LIST_ENTRY      *NextEntry;

  FfsFileEntry = (FFS_FILE_LIST_ENTRY *) (FileListHead->ForwardLink);

  //
  // Loop the whole list entry to free resources
  //
  while (&FfsFileEntry->Link != FileListHead) {
    NextEntry = (&FfsFileEntry->Link)->ForwardLink;
    FreePool (FfsFileEntry);
    FfsFileEntry = (FFS_FILE_LIST_ENTRY *) NextEntry;
  }

  return ;
}

/**
  Create a new file within a PAD file area.

  @param FvDevice        Firmware Volume Device.
  @param FfsFileBuffer   A buffer that holds an FFS file,(it contains a File Header which is in init state).
  @param BufferSize      The size of FfsFileBuffer.
  @param ActualFileSize  The actual file length, it may not be multiples of 8.
  @param FileName        The FFS File Name.
  @param FileType        The FFS File Type.
  @param FileAttributes  The Attributes of the FFS File to be created.

  @retval EFI_SUCCESS           Successfully create a new file within the found PAD file area.
  @retval EFI_OUT_OF_RESOURCES  No suitable PAD file is found.
  @retval other errors          New file is created failed.

**/
EFI_STATUS
FvCreateNewFileInsidePadFile (
  IN  FV_DEVICE               *FvDevice,
  IN  UINT8                   *FfsFileBuffer,
  IN  UINTN                   BufferSize,
  IN  UINTN                   ActualFileSize,
  IN  EFI_GUID                *FileName,
  IN  EFI_FV_FILETYPE         FileType,
  IN  EFI_FV_FILE_ATTRIBUTES  FileAttributes
  )
{
  UINTN                               RequiredAlignment;
  FFS_FILE_LIST_ENTRY                 *PadFileEntry;
  EFI_STATUS                          Status;
  UINTN                               PadAreaLength;
  UINTN                               PadSize;
  EFI_FFS_FILE_HEADER                 *FileHeader;
  EFI_FFS_FILE_HEADER                 *OldPadFileHeader;
  EFI_FFS_FILE_HEADER                 *PadFileHeader;
  EFI_FFS_FILE_HEADER                 *TailPadFileHeader;
  UINTN                               StateOffset;
  UINTN                               Offset;
  UINTN                               NumBytesWritten;
  UINT8                               *StartPos;
  LIST_ENTRY                          NewFileList;
  FFS_FILE_LIST_ENTRY                 *NewFileListEntry;
  FFS_FILE_LIST_ENTRY                 *FfsEntry;
  FFS_FILE_LIST_ENTRY                 *NextFfsEntry;

  //
  // First get the required alignment from the File Attributes
  //
  RequiredAlignment = GetRequiredAlignment (FileAttributes);

  //
  // Find a suitable PAD File
  //
  Status = FvLocatePadFile (
            FvDevice,
            BufferSize,
            RequiredAlignment,
            &PadSize,
            &PadFileEntry
            );

  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  OldPadFileHeader = (EFI_FFS_FILE_HEADER *) PadFileEntry->FfsHeader;

  //
  // Step 1: Update Pad File Header
  //
  SetFileState (EFI_FILE_MARKED_FOR_UPDATE, OldPadFileHeader);

  StartPos = PadFileEntry->FfsHeader;

  Offset          = (UINTN) (StartPos - FvDevice->CachedFv);
  StateOffset     = Offset + (UINT8 *) &OldPadFileHeader->State - (UINT8 *) OldPadFileHeader;

  NumBytesWritten = sizeof (EFI_FFS_FILE_STATE);
  Status = FvcWrite (
            FvDevice,
            StateOffset,
            &NumBytesWritten,
            &OldPadFileHeader->State
            );
  if (EFI_ERROR (Status)) {
    SetFileState (EFI_FILE_HEADER_CONSTRUCTION, OldPadFileHeader);
    return Status;
  }

  //
  // Step 2: Update Pad area
  //
  InitializeListHead (&NewFileList);

  if (IS_FFS_FILE2 (OldPadFileHeader)) {
    PadAreaLength = FFS_FILE2_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
    PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
  } else {
    PadAreaLength = FFS_FILE_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
    PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER));
  }

  if (PadSize != 0) {
    //
    // Insert a PAD file before to achieve required alignment
    //
    FvFillPadFile (PadFileHeader, PadSize);
    NewFileListEntry            = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
    ASSERT (NewFileListEntry   != NULL);
    NewFileListEntry->FfsHeader = (UINT8 *) PadFileHeader;
    InsertTailList (&NewFileList, &NewFileListEntry->Link);
  }

  FileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) PadFileHeader + PadSize);

  Status = FvFillFfsFile (
            FileHeader,
            FfsFileBuffer,
            BufferSize,
            ActualFileSize,
            FileName,
            FileType,
            FileAttributes
            );
  if (EFI_ERROR (Status)) {
    FreeFileList (&NewFileList);
    return Status;
  }

  NewFileListEntry            = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
  ASSERT (NewFileListEntry   != NULL);

  NewFileListEntry->FfsHeader = (UINT8 *) FileHeader;
  InsertTailList (&NewFileList, &NewFileListEntry->Link);

  FvDevice->CurrentFfsFile = NewFileListEntry;

  if (PadAreaLength > (BufferSize + PadSize)) {
    if ((PadAreaLength - BufferSize - PadSize) >= sizeof (EFI_FFS_FILE_HEADER)) {
      //
      // we can insert another PAD file
      //
      TailPadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FileHeader + BufferSize);
      FvFillPadFile (TailPadFileHeader, PadAreaLength - BufferSize - PadSize);

      NewFileListEntry            = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
      ASSERT (NewFileListEntry   != NULL);

      NewFileListEntry->FfsHeader = (UINT8 *) TailPadFileHeader;
      InsertTailList (&NewFileList, &NewFileListEntry->Link);
    } else {
      //
      // because left size cannot hold another PAD file header,
      // adjust the writing file size (just in cache)
      //
      FvAdjustFfsFile (
        FvDevice->ErasePolarity,
        FileHeader,
        PadAreaLength - BufferSize - PadSize
        );
    }
  }
  //
  // Start writing to FV
  //
  if (IS_FFS_FILE2 (OldPadFileHeader)) {
    StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2);
  } else {
    StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER);
  }

  Offset          = (UINTN) (StartPos - FvDevice->CachedFv);

  NumBytesWritten = PadAreaLength;
  Status = FvcWrite (
            FvDevice,
            Offset,
            &NumBytesWritten,
            StartPos
            );
  if (EFI_ERROR (Status)) {
    FreeFileList (&NewFileList);
    FvDevice->CurrentFfsFile = NULL;
    return Status;
  }

  //
  // Step 3: Mark Pad file header as EFI_FILE_HEADER_INVALID
  //
  SetFileState (EFI_FILE_HEADER_INVALID, OldPadFileHeader);

  StartPos = PadFileEntry->FfsHeader;

  Offset          = (UINTN) (StartPos - FvDevice->CachedFv);
  StateOffset     = Offset + (UINT8 *) &OldPadFileHeader->State - (UINT8 *) OldPadFileHeader;

  NumBytesWritten = sizeof (EFI_FFS_FILE_STATE);
  Status = FvcWrite (
            FvDevice,
            StateOffset,
            &NumBytesWritten,
            &OldPadFileHeader->State
            );
  if (EFI_ERROR (Status)) {
    SetFileState (EFI_FILE_HEADER_INVALID, OldPadFileHeader);
    FreeFileList (&NewFileList);
    FvDevice->CurrentFfsFile = NULL;
    return Status;
  }

  //
  // If all successfully, update FFS_FILE_LIST
  //

  //
  // Delete old pad file entry
  //
  FfsEntry      = (FFS_FILE_LIST_ENTRY *) PadFileEntry->Link.BackLink;
  NextFfsEntry  = (FFS_FILE_LIST_ENTRY *) PadFileEntry->Link.ForwardLink;

  FreePool (PadFileEntry);

  FfsEntry->Link.ForwardLink          = NewFileList.ForwardLink;
  (NewFileList.ForwardLink)->BackLink = &FfsEntry->Link;
  NextFfsEntry->Link.BackLink         = NewFileList.BackLink;
  (NewFileList.BackLink)->ForwardLink = &NextFfsEntry->Link;

  return EFI_SUCCESS;
}

/**
  Free all FfsBuffer.

  @param NumOfFiles      Number of FfsBuffer.
  @param FfsBuffer       An array of pointer to an FFS File Buffer

**/
VOID
FreeFfsBuffer (
  IN UINTN    NumOfFiles,
  IN UINT8    **FfsBuffer
  )
{
  UINTN Index;
  for (Index = 0; Index < NumOfFiles; Index++) {
    if (FfsBuffer[Index] != NULL) {
      FreePool (FfsBuffer[Index]);
    }
  }
}

/**
  Create multiple files within a PAD File area.

  @param FvDevice        Firmware Volume Device.
  @param PadFileEntry    The pad file entry to be written in.
  @param NumOfFiles      Total File number to be written.
  @param BufferSize      The array of buffer size of each FfsBuffer.
  @param ActualFileSize  The array of actual file size.
  @param PadSize         The array of leading pad file size for each FFS File
  @param FfsBuffer       The array of Ffs Buffer pointer.
  @param FileData        The array of EFI_FV_WRITE_FILE_DATA structure, 
                         used to get name, attributes, type, etc.

  @retval EFI_SUCCESS           Add the input multiple files into PAD file area.
  @retval EFI_OUT_OF_RESOURCES  No enough memory is allocated.
  @retval other error           Files can't be added into PAD file area.

**/
EFI_STATUS
FvCreateMultipleFilesInsidePadFile (
  IN FV_DEVICE              *FvDevice,
  IN FFS_FILE_LIST_ENTRY    *PadFileEntry,
  IN UINTN                  NumOfFiles,
  IN UINTN                  *BufferSize,
  IN UINTN                  *ActualFileSize,
  IN UINTN                  *PadSize,
  IN UINT8                  **FfsBuffer,
  IN EFI_FV_WRITE_FILE_DATA *FileData
  )
{
  EFI_STATUS                          Status;
  EFI_FFS_FILE_HEADER                 *OldPadFileHeader;
  UINTN                               Index;
  EFI_FFS_FILE_HEADER                 *PadFileHeader;
  EFI_FFS_FILE_HEADER                 *FileHeader;
  EFI_FFS_FILE_HEADER                 *TailPadFileHeader;
  UINTN                               TotalSize;
  UINTN                               PadAreaLength;
  LIST_ENTRY                          NewFileList;
  FFS_FILE_LIST_ENTRY                 *NewFileListEntry;
  UINTN                               Offset;
  UINTN                               NumBytesWritten;
  UINT8                               *StartPos;
  FFS_FILE_LIST_ENTRY                 *FfsEntry;
  FFS_FILE_LIST_ENTRY                 *NextFfsEntry;

  InitializeListHead (&NewFileList);

  NewFileListEntry  = NULL;

  OldPadFileHeader  = (EFI_FFS_FILE_HEADER *) PadFileEntry->FfsHeader;
  if (IS_FFS_FILE2 (OldPadFileHeader)) {
    PadAreaLength = FFS_FILE2_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
  } else {
    PadAreaLength = FFS_FILE_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
  }

  Status = UpdateHeaderBit (
            FvDevice,
            OldPadFileHeader,
            EFI_FILE_MARKED_FOR_UPDATE
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Update PAD area
  //
  TotalSize     = 0;
  if (IS_FFS_FILE2 (OldPadFileHeader)) {
    PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
  } else {
    PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER));
  }
  FileHeader    = PadFileHeader;

  for (Index = 0; Index < NumOfFiles; Index++) {
    if (PadSize[Index] != 0) {
      FvFillPadFile (PadFileHeader, PadSize[Index]);
      NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
      if (NewFileListEntry == NULL) {
        FreeFileList (&NewFileList);
        return EFI_OUT_OF_RESOURCES;
      }

      NewFileListEntry->FfsHeader = (UINT8 *) PadFileHeader;
      InsertTailList (&NewFileList, &NewFileListEntry->Link);
    }

    FileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) PadFileHeader + PadSize[Index]);
    Status = FvFillFfsFile (
              FileHeader,
              FfsBuffer[Index],
              BufferSize[Index],
              ActualFileSize[Index],
              FileData[Index].NameGuid,
              FileData[Index].Type,
              FileData[Index].FileAttributes
              );
    if (EFI_ERROR (Status)) {
      FreeFileList (&NewFileList);
      return Status;
    }

    NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
    if (NewFileListEntry == NULL) {
      FreeFileList (&NewFileList);
      return EFI_OUT_OF_RESOURCES;
    }

    NewFileListEntry->FfsHeader = (UINT8 *) FileHeader;
    InsertTailList (&NewFileList, &NewFileListEntry->Link);

    PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FileHeader + BufferSize[Index]);
    TotalSize += PadSize[Index];
    TotalSize += BufferSize[Index];
  }

  FvDevice->CurrentFfsFile = NewFileListEntry;
  //
  // Maybe we need a tail pad file
  //
  if (PadAreaLength > TotalSize) {
    if ((PadAreaLength - TotalSize) >= sizeof (EFI_FFS_FILE_HEADER)) {
      //
      // we can insert another PAD file
      //
      TailPadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FileHeader + BufferSize[NumOfFiles - 1]);
      FvFillPadFile (TailPadFileHeader, PadAreaLength - TotalSize);

      NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
      if (NewFileListEntry == NULL) {
        FreeFileList (&NewFileList);
        FvDevice->CurrentFfsFile = NULL;
        return EFI_OUT_OF_RESOURCES;
      }

      NewFileListEntry->FfsHeader = (UINT8 *) TailPadFileHeader;
      InsertTailList (&NewFileList, &NewFileListEntry->Link);
    } else {
      //
      // because left size cannot hold another PAD file header,
      // adjust the writing file size (just in cache)
      //
      FvAdjustFfsFile (
        FvDevice->ErasePolarity,
        FileHeader,
        PadAreaLength - TotalSize
        );
    }
  }
  //
  // Start writing to FV
  //
  if (IS_FFS_FILE2 (OldPadFileHeader)) {
    StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2);
  } else {
    StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER);
  }

  Offset          = (UINTN) (StartPos - FvDevice->CachedFv);

  NumBytesWritten = PadAreaLength;
  Status = FvcWrite (
            FvDevice,
            Offset,
            &NumBytesWritten,
            StartPos
            );
  if (EFI_ERROR (Status)) {
    FreeFileList (&NewFileList);
    FvDevice->CurrentFfsFile = NULL;
    return Status;
  }

  Status = UpdateHeaderBit (
            FvDevice,
            OldPadFileHeader,
            EFI_FILE_HEADER_INVALID
            );
  if (EFI_ERROR (Status)) {
    FreeFileList (&NewFileList);
    FvDevice->CurrentFfsFile = NULL;
    return Status;
  }

  //
  // Update File List Link
  //

  //
  // First delete old pad file entry
  //
  FfsEntry      = (FFS_FILE_LIST_ENTRY *) PadFileEntry->Link.BackLink;
  NextFfsEntry  = (FFS_FILE_LIST_ENTRY *) PadFileEntry->Link.ForwardLink;

  FreePool (PadFileEntry);

  FfsEntry->Link.ForwardLink          = NewFileList.ForwardLink;
  (NewFileList.ForwardLink)->BackLink = &FfsEntry->Link;
  NextFfsEntry->Link.BackLink         = NewFileList.BackLink;
  (NewFileList.BackLink)->ForwardLink = &NextFfsEntry->Link;

  return EFI_SUCCESS;
}

/**
  Create multiple files within the Free Space.

  @param FvDevice        Firmware Volume Device.
  @param FreeSpaceEntry  Indicating in which Free Space(Cache) the multiple files will be inserted.
  @param NumOfFiles      Total File number to be written.
  @param BufferSize      The array of buffer size of each FfsBuffer.
  @param ActualFileSize  The array of actual file size.
  @param PadSize         The array of leading pad file size for each FFS File
  @param FfsBuffer       The array of Ffs Buffer pointer.
  @param FileData        The array of EFI_FV_WRITE_FILE_DATA structure, 
                         used to get name, attributes, type, etc.

  @retval EFI_SUCCESS           Add the input multiple files into PAD file area.
  @retval EFI_OUT_OF_RESOURCES  No enough memory is allocated.
  @retval other error           Files can't be added into PAD file area.

**/
EFI_STATUS
FvCreateMultipleFilesInsideFreeSpace (
  IN FV_DEVICE              *FvDevice,
  IN FREE_SPACE_ENTRY       *FreeSpaceEntry,
  IN UINTN                  NumOfFiles,
  IN UINTN                  *BufferSize,
  IN UINTN                  *ActualFileSize,
  IN UINTN                  *PadSize,
  IN UINT8                  **FfsBuffer,
  IN EFI_FV_WRITE_FILE_DATA *FileData
  )
{
  EFI_STATUS                          Status;
  UINTN                               Index;
  EFI_FFS_FILE_HEADER                 *PadFileHeader;
  EFI_FFS_FILE_HEADER                 *FileHeader;
  UINTN                               TotalSize;
  LIST_ENTRY                          NewFileList;
  FFS_FILE_LIST_ENTRY                 *NewFileListEntry;
  UINTN                               Offset;
  UINTN                               NumBytesWritten;
  UINT8                               *StartPos;

  InitializeListHead (&NewFileList);

  NewFileListEntry  = NULL;

  TotalSize     = 0;
  StartPos      = FreeSpaceEntry->StartingAddress;
  PadFileHeader = (EFI_FFS_FILE_HEADER *) StartPos;
  FileHeader    = PadFileHeader;

  for (Index = 0; Index < NumOfFiles; Index++) {
    if (PadSize[Index] != 0) {
      FvFillPadFile (PadFileHeader, PadSize[Index]);
      NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
      if (NewFileListEntry == NULL) {
        FreeFileList (&NewFileList);
        return EFI_OUT_OF_RESOURCES;
      }

      NewFileListEntry->FfsHeader = (UINT8 *) PadFileHeader;
      InsertTailList (&NewFileList, &NewFileListEntry->Link);
    }

    FileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) PadFileHeader + PadSize[Index]);
    Status = FvFillFfsFile (
              FileHeader,
              FfsBuffer[Index],
              BufferSize[Index],
              ActualFileSize[Index],
              FileData[Index].NameGuid,
              FileData[Index].Type,
              FileData[Index].FileAttributes
              );
    if (EFI_ERROR (Status)) {
      FreeFileList (&NewFileList);
      return Status;
    }

    NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
    if (NewFileListEntry == NULL) {
      FreeFileList (&NewFileList);
      return EFI_OUT_OF_RESOURCES;
    }

    NewFileListEntry->FfsHeader = (UINT8 *) FileHeader;
    InsertTailList (&NewFileList, &NewFileListEntry->Link);

    PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FileHeader + BufferSize[Index]);
    TotalSize += PadSize[Index];
    TotalSize += BufferSize[Index];
  }

  if (FreeSpaceEntry->Length < TotalSize) {
    FreeFileList (&NewFileList);
    return EFI_OUT_OF_RESOURCES;
  }

  FvDevice->CurrentFfsFile = NewFileListEntry;

  //
  // Start writing to FV
  //
  Offset          = (UINTN) (StartPos - FvDevice->CachedFv);

  NumBytesWritten = TotalSize;
  Status = FvcWrite (
            FvDevice,
            Offset,
            &NumBytesWritten,
            StartPos
            );
  if (EFI_ERROR (Status)) {
    FreeFileList (&NewFileList);
    FvDevice->CurrentFfsFile = NULL;
    return Status;
  }

  FreeSpaceEntry->Length -= TotalSize;
  FreeSpaceEntry->StartingAddress += TotalSize;

  NewFileListEntry = (FFS_FILE_LIST_ENTRY *) (NewFileList.ForwardLink);

  while (NewFileListEntry != (FFS_FILE_LIST_ENTRY *) &NewFileList) {
    InsertTailList (&FvDevice->FfsFileListHeader, &NewFileListEntry->Link);
    NewFileListEntry = (FFS_FILE_LIST_ENTRY *) (NewFileListEntry->Link.ForwardLink);
  }

  return EFI_SUCCESS;
}

/**
  Write multiple files into FV in reliable method.

  @param FvDevice        Firmware Volume Device.
  @param NumOfFiles      Total File number to be written.
  @param FileData        The array of EFI_FV_WRITE_FILE_DATA structure, 
                         used to get name, attributes, type, etc
  @param FileOperation   The array of operation for each file.

  @retval EFI_SUCCESS            Files are added into FV.
  @retval EFI_OUT_OF_RESOURCES   No enough free PAD files to add the input files.
  @retval EFI_INVALID_PARAMETER  File number is less than or equal to 1.
  @retval EFI_UNSUPPORTED        File number exceeds the supported max numbers of files.

**/
EFI_STATUS
FvCreateMultipleFiles (
  IN  FV_DEVICE               *FvDevice,
  IN  UINTN                   NumOfFiles,
  IN  EFI_FV_WRITE_FILE_DATA  *FileData,
  IN  BOOLEAN                 *FileOperation
  )
{
  EFI_STATUS                    Status;
  UINT8                         *FfsBuffer[MAX_FILES];
  UINTN                         Index1;
  UINTN                         Index2;
  UINTN                         BufferSize[MAX_FILES];
  UINTN                         ActualFileSize[MAX_FILES];
  UINTN                         RequiredAlignment[MAX_FILES];
  UINTN                         PadSize[MAX_FILES];
  FFS_FILE_LIST_ENTRY           *PadFileEntry;
  UINTN                         TotalSizeNeeded;
  FREE_SPACE_ENTRY              *FreeSpaceEntry;
  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
  UINTN                         Key;
  EFI_GUID                      FileNameGuid;
  EFI_FV_FILETYPE               OldFileType;
  EFI_FV_FILE_ATTRIBUTES        OldFileAttributes;
  UINTN                         OldFileSize;
  FFS_FILE_LIST_ENTRY           *OldFfsFileEntry[MAX_FILES];
  EFI_FFS_FILE_HEADER           *OldFileHeader[MAX_FILES];
  BOOLEAN                       IsCreateFile;
  UINTN                         HeaderSize;

  //
  // To use this function, we must ensure that the NumOfFiles is great
  // than 1
  //
  if (NumOfFiles <= 1) {
    return EFI_INVALID_PARAMETER;
  }

  if (NumOfFiles > MAX_FILES) {
    return EFI_UNSUPPORTED;
  }

  Fv = &FvDevice->Fv;

  SetMem (FfsBuffer, NumOfFiles, 0);
  SetMem (RequiredAlignment, NumOfFiles, 8);
  SetMem (PadSize, NumOfFiles, 0);
  ZeroMem (OldFfsFileEntry, sizeof (OldFfsFileEntry));
  ZeroMem (OldFileHeader, sizeof (OldFileHeader));

  //
  // Adjust file size
  //
  for (Index1 = 0; Index1 < NumOfFiles; Index1++) {
    HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
    ActualFileSize[Index1] = FileData[Index1].BufferSize + HeaderSize;
    if (ActualFileSize[Index1] > 0x00FFFFFF) {
      HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
      ActualFileSize[Index1] = FileData[Index1].BufferSize + HeaderSize;
    }
    BufferSize[Index1]     = ActualFileSize[Index1];

    if (BufferSize[Index1] == HeaderSize) {
      //
      // clear file attributes, zero-length file does not have any attributes
      //
      FileData[Index1].FileAttributes = 0;
    }

    while ((BufferSize[Index1] & 0x07) != 0) {
      BufferSize[Index1]++;
    }

    FfsBuffer[Index1] = AllocateZeroPool (BufferSize[Index1]);

    //
    // Copy File Data into FileBuffer
    //
    CopyMem (
      FfsBuffer[Index1] + HeaderSize,
      FileData[Index1].Buffer,
      FileData[Index1].BufferSize
      );

    if (FvDevice->ErasePolarity == 1) {
      for (Index2 = 0; Index2 < HeaderSize; Index2++) {
        FfsBuffer[Index1][Index2] = (UINT8)~FfsBuffer[Index1][Index2];
      }
    }

    if ((FileData[Index1].FileAttributes & EFI_FV_FILE_ATTRIB_ALIGNMENT) != 0) {
      RequiredAlignment[Index1] = GetRequiredAlignment (FileData[Index1].FileAttributes);
    }
    //
    // If update file, mark the original file header to
    // EFI_FILE_MARKED_FOR_UPDATE
    //
    IsCreateFile = FileOperation[Index1];
    if (!IsCreateFile) {

      Key = 0;
      do {
        OldFileType = 0;
        Status = Fv->GetNextFile (
                      Fv,
                      &Key,
                      &OldFileType,
                      &FileNameGuid,
                      &OldFileAttributes,
                      &OldFileSize
                      );
        if (EFI_ERROR (Status)) {
          FreeFfsBuffer (NumOfFiles, FfsBuffer);
          return Status;
        }
      } while (!CompareGuid (&FileNameGuid, FileData[Index1].NameGuid));

      //
      // Get FfsFileEntry from the search key
      //
      OldFfsFileEntry[Index1]  = (FFS_FILE_LIST_ENTRY *) Key;
      OldFileHeader[Index1]    = (EFI_FFS_FILE_HEADER *) OldFfsFileEntry[Index1]->FfsHeader;
      Status = UpdateHeaderBit (
                FvDevice,
                OldFileHeader[Index1],
                EFI_FILE_MARKED_FOR_UPDATE
                );
      if (EFI_ERROR (Status)) {
        FreeFfsBuffer (NumOfFiles, FfsBuffer);
        return Status;
      }
    }
  }
  //
  // First to search a suitable pad file that can hold so
  // many files
  //
  Status = FvSearchSuitablePadFile (
            FvDevice,
            NumOfFiles,
            BufferSize,
            RequiredAlignment,
            PadSize,
            &TotalSizeNeeded,
            &PadFileEntry
            );

  if (Status == EFI_NOT_FOUND) {
    //
    // Try to find a free space that can hold these files
    //
    Status = FvSearchSuitableFreeSpace (
              FvDevice,
              NumOfFiles,
              BufferSize,
              RequiredAlignment,
              PadSize,
              &TotalSizeNeeded,
              &FreeSpaceEntry
              );
    if (EFI_ERROR (Status)) {
      FreeFfsBuffer (NumOfFiles, FfsBuffer);
      return EFI_OUT_OF_RESOURCES;
    }
    Status = FvCreateMultipleFilesInsideFreeSpace (
              FvDevice,
              FreeSpaceEntry,
              NumOfFiles,
              BufferSize,
              ActualFileSize,
              PadSize,
              FfsBuffer,
              FileData
              );

  } else {
    //
    // Create multiple files inside such a pad file
    // to achieve lock-step update
    //
    Status = FvCreateMultipleFilesInsidePadFile (
              FvDevice,
              PadFileEntry,
              NumOfFiles,
              BufferSize,
              ActualFileSize,
              PadSize,
              FfsBuffer,
              FileData
              );
  }

  FreeFfsBuffer (NumOfFiles, FfsBuffer);

  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Delete those updated files
  //
  for (Index1 = 0; Index1 < NumOfFiles; Index1++) {
    IsCreateFile = FileOperation[Index1];
    if (!IsCreateFile && OldFfsFileEntry[Index1] != NULL) {
      (OldFfsFileEntry[Index1]->Link.BackLink)->ForwardLink  = OldFfsFileEntry[Index1]->Link.ForwardLink;
      (OldFfsFileEntry[Index1]->Link.ForwardLink)->BackLink  = OldFfsFileEntry[Index1]->Link.BackLink;
      FreePool (OldFfsFileEntry[Index1]);
    }
  }
  //
  // Set those files' state to EFI_FILE_DELETED
  //
  for (Index1 = 0; Index1 < NumOfFiles; Index1++) {
    IsCreateFile = FileOperation[Index1];
    if (!IsCreateFile && OldFileHeader[Index1] != NULL) {
      Status = UpdateHeaderBit (FvDevice, OldFileHeader[Index1], EFI_FILE_DELETED);
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
  }

  return EFI_SUCCESS;
}
