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