Check in DxeCore for Nt32 platform. Currently, it does not follow PI/UEFI2.1.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3045 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
266
MdeModulePkg/Core/Dxe/FwVol/Ffs.c
Normal file
266
MdeModulePkg/Core/Dxe/FwVol/Ffs.c
Normal file
@@ -0,0 +1,266 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
Ffs.c
|
||||
|
||||
Abstract:
|
||||
|
||||
FFS file access utilities.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
#define PHYSICAL_ADDRESS_TO_POINTER(Address) ((VOID *)((UINTN)(Address)))
|
||||
|
||||
|
||||
EFI_FFS_FILE_STATE
|
||||
GetFileState (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get the FFS file state by checking the highest bit set in the header's state field
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file header
|
||||
|
||||
Returns:
|
||||
FFS File state
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FFS_FILE_STATE FileState;
|
||||
UINT8 HighestBit;
|
||||
|
||||
FileState = FfsHeader->State;
|
||||
|
||||
if (ErasePolarity != 0) {
|
||||
FileState = (EFI_FFS_FILE_STATE)~FileState;
|
||||
}
|
||||
|
||||
HighestBit = 0x80;
|
||||
while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {
|
||||
HighestBit >>= 1;
|
||||
}
|
||||
|
||||
return (EFI_FFS_FILE_STATE)HighestBit;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IsBufferErased (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN VOID *InBuffer,
|
||||
IN UINTN BufferSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if a block of buffer is erased
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
InBuffer - The buffer to be checked
|
||||
BufferSize - Size of the buffer in bytes
|
||||
|
||||
Returns:
|
||||
TRUE - The block of buffer is erased
|
||||
FALSE - The block of buffer is not erased
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Count;
|
||||
UINT8 EraseByte;
|
||||
UINT8 *Buffer;
|
||||
|
||||
if(ErasePolarity == 1) {
|
||||
EraseByte = 0xFF;
|
||||
} else {
|
||||
EraseByte = 0;
|
||||
}
|
||||
|
||||
Buffer = InBuffer;
|
||||
for (Count = 0; Count < BufferSize; Count++) {
|
||||
if (Buffer[Count] != EraseByte) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
VerifyFvHeaderChecksum (
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Verify checksum of the firmware volume header
|
||||
|
||||
Arguments:
|
||||
FvHeader - Points to the firmware volume header to be checked
|
||||
|
||||
Returns:
|
||||
TRUE - Checksum verification passed
|
||||
FALSE - Checksum verification failed
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT32 HeaderLength;
|
||||
UINT16 Checksum;
|
||||
UINT16 *ptr;
|
||||
|
||||
HeaderLength = FvHeader->HeaderLength;
|
||||
ptr = (UINT16 *)FvHeader;
|
||||
Checksum = 0;
|
||||
|
||||
for (Index = 0; Index < HeaderLength / sizeof (UINT16); Index++) {
|
||||
Checksum = (UINT16)(Checksum + ptr[Index]);
|
||||
}
|
||||
|
||||
if (Checksum == 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
BOOLEAN
|
||||
VerifyHeaderChecksum (
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Verify checksum of the FFS file header
|
||||
|
||||
Arguments:
|
||||
FfsHeader - Points to the FFS file header to be checked
|
||||
|
||||
Returns:
|
||||
TRUE - Checksum verification passed
|
||||
FALSE - Checksum verification failed
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT8 *ptr;
|
||||
UINT8 HeaderChecksum;
|
||||
|
||||
ptr = (UINT8 *)FfsHeader;
|
||||
HeaderChecksum = 0;
|
||||
for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
|
||||
HeaderChecksum = (UINT8)(HeaderChecksum + ptr[Index]);
|
||||
}
|
||||
|
||||
HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);
|
||||
|
||||
if (HeaderChecksum == 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IsValidFfsHeader (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader,
|
||||
OUT EFI_FFS_FILE_STATE *FileState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if it's a valid FFS file header
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file header to be checked
|
||||
FileState - FFS file state to be returned
|
||||
|
||||
Returns:
|
||||
TRUE - Valid FFS file header
|
||||
FALSE - Invalid FFS file header
|
||||
|
||||
--*/
|
||||
{
|
||||
*FileState = GetFileState (ErasePolarity, FfsHeader);
|
||||
|
||||
switch (*FileState) {
|
||||
case EFI_FILE_HEADER_VALID:
|
||||
case EFI_FILE_DATA_VALID:
|
||||
case EFI_FILE_MARKED_FOR_UPDATE:
|
||||
case EFI_FILE_DELETED:
|
||||
//
|
||||
// Here we need to verify header checksum
|
||||
//
|
||||
return VerifyHeaderChecksum (FfsHeader);
|
||||
|
||||
case EFI_FILE_HEADER_CONSTRUCTION:
|
||||
case EFI_FILE_HEADER_INVALID:
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IsValidFfsFile (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if it's a valid FFS file.
|
||||
Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file to be checked
|
||||
|
||||
Returns:
|
||||
TRUE - Valid FFS file
|
||||
FALSE - Invalid FFS file
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FFS_FILE_STATE FileState;
|
||||
|
||||
FileState = GetFileState (ErasePolarity, FfsHeader);
|
||||
switch (FileState) {
|
||||
|
||||
case EFI_FILE_DELETED:
|
||||
case EFI_FILE_DATA_VALID:
|
||||
case EFI_FILE_MARKED_FOR_UPDATE:
|
||||
//
|
||||
// Some other vliadation like file content checksum might be done here.
|
||||
// For performance issue, Tiano only do FileState check.
|
||||
//
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
547
MdeModulePkg/Core/Dxe/FwVol/FwVol.c
Normal file
547
MdeModulePkg/Core/Dxe/FwVol/FwVol.c
Normal file
@@ -0,0 +1,547 @@
|
||||
/**@file
|
||||
Firmware File System driver that produce Firmware Volume protocol.
|
||||
Layers on top of Firmware Block protocol to produce a file abstraction
|
||||
of FV based files.
|
||||
|
||||
Copyright (c) 2006 - 2007 Intel Corporation. <BR>
|
||||
All rights reserved. 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 <DxeMain.h>
|
||||
|
||||
#define KEYSIZE sizeof (UINTN)
|
||||
|
||||
//
|
||||
// Protocol notify related globals
|
||||
//
|
||||
VOID *gEfiFwVolBlockNotifyReg;
|
||||
EFI_EVENT gEfiFwVolBlockEvent;
|
||||
|
||||
FV_DEVICE mFvDevice = {
|
||||
FV_DEVICE_SIGNATURE,
|
||||
NULL,
|
||||
NULL,
|
||||
{
|
||||
FvGetVolumeAttributes,
|
||||
FvSetVolumeAttributes,
|
||||
FvReadFile,
|
||||
FvReadFileSection,
|
||||
FvWriteFile,
|
||||
FvGetNextFile,
|
||||
KEYSIZE
|
||||
},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
{ NULL, NULL },
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// FFS helper functions
|
||||
//
|
||||
|
||||
EFI_STATUS
|
||||
GetFwVolHeader (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,
|
||||
OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and
|
||||
copy the volume header into it.
|
||||
|
||||
Arguments:
|
||||
Fvb - The FW_VOL_BLOCK_PROTOCOL instance from which to read the volume
|
||||
header
|
||||
FwVolHeader - Pointer to pointer to allocated buffer in which the volume
|
||||
header is returned.
|
||||
|
||||
Returns:
|
||||
EFI_OUT_OF_RESOURCES - No enough buffer could be allocated.
|
||||
EFI_SUCCESS - Successfully read volume header to the allocated buffer.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME_HEADER TempFvh;
|
||||
UINTN FvhLength;
|
||||
UINT8 *Buffer;
|
||||
|
||||
|
||||
//
|
||||
//Determine the real length of FV header
|
||||
//
|
||||
FvhLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
|
||||
Status = Fvb->Read (Fvb, 0, 0, &FvhLength, (UINT8 *)&TempFvh);
|
||||
|
||||
//
|
||||
// Allocate a buffer for the caller
|
||||
//
|
||||
*FwVolHeader = CoreAllocateBootServicesPool (TempFvh.HeaderLength);
|
||||
if (*FwVolHeader == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy the standard header into the buffer
|
||||
//
|
||||
CopyMem (*FwVolHeader, &TempFvh, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
|
||||
|
||||
//
|
||||
// Read the rest of the header
|
||||
//
|
||||
FvhLength = TempFvh.HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER);
|
||||
Buffer = (UINT8 *)*FwVolHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER);
|
||||
Status = Fvb->Read (Fvb, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER), &FvhLength, Buffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Read failed so free buffer
|
||||
//
|
||||
CoreFreePool (*FwVolHeader);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
FreeFvDeviceResource (
|
||||
IN FV_DEVICE *FvDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Free FvDevice resource when error happens
|
||||
|
||||
Arguments:
|
||||
FvDevice - pointer to the FvDevice to be freed.
|
||||
|
||||
Returns:
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
FFS_FILE_LIST_ENTRY *FfsFileEntry;
|
||||
LIST_ENTRY *NextEntry;
|
||||
|
||||
//
|
||||
// Free File List Entry
|
||||
//
|
||||
FfsFileEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->FfsFileListHeader.ForwardLink;
|
||||
while (&FfsFileEntry->Link != &FvDevice->FfsFileListHeader) {
|
||||
NextEntry = (&FfsFileEntry->Link)->ForwardLink;
|
||||
|
||||
if (FfsFileEntry->StreamHandle != 0) {
|
||||
//
|
||||
// Close stream and free resources from SEP
|
||||
//
|
||||
FfsFileEntry->Sep->CloseSectionStream (FfsFileEntry->Sep, FfsFileEntry->StreamHandle);
|
||||
}
|
||||
|
||||
CoreFreePool (FfsFileEntry);
|
||||
|
||||
FfsFileEntry = (FFS_FILE_LIST_ENTRY *)NextEntry;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Free the cache
|
||||
//
|
||||
CoreFreePool (FvDevice->CachedFv);
|
||||
|
||||
//
|
||||
// Free Volume Header
|
||||
//
|
||||
CoreFreePool (FvDevice->FwVolHeader);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
FvCheck (
|
||||
IN OUT FV_DEVICE *FvDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if a FV is consistent and allocate cache
|
||||
|
||||
Arguments:
|
||||
FvDevice - pointer to the FvDevice to be checked.
|
||||
|
||||
Returns:
|
||||
EFI_OUT_OF_RESOURCES - No enough buffer could be allocated.
|
||||
EFI_SUCCESS - FV is consistent and cache is allocated.
|
||||
EFI_VOLUME_CORRUPTED - File system is corrupted.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
EFI_FVB_ATTRIBUTES FvbAttributes;
|
||||
EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
|
||||
FFS_FILE_LIST_ENTRY *FfsFileEntry;
|
||||
EFI_FFS_FILE_HEADER *FfsHeader;
|
||||
UINT8 *CacheLocation;
|
||||
UINTN LbaOffset;
|
||||
UINTN Index;
|
||||
EFI_LBA LbaIndex;
|
||||
UINTN Size;
|
||||
UINTN FileLength;
|
||||
EFI_FFS_FILE_STATE FileState;
|
||||
UINT8 *TopFvAddress;
|
||||
UINTN TestLength;
|
||||
|
||||
|
||||
Fvb = FvDevice->Fvb;
|
||||
FwVolHeader = FvDevice->FwVolHeader;
|
||||
|
||||
Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Size is the size of the FV minus the head. We have already allocated
|
||||
// the header to check to make sure the volume is valid
|
||||
//
|
||||
Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);
|
||||
FvDevice->CachedFv = CoreAllocateBootServicesPool (Size);
|
||||
|
||||
if (FvDevice->CachedFv == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Remember a pointer to the end fo the CachedFv
|
||||
//
|
||||
FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;
|
||||
|
||||
//
|
||||
// Copy FV minus header into memory using the block map we have all ready
|
||||
// read into memory.
|
||||
//
|
||||
BlockMap = FwVolHeader->BlockMap;
|
||||
CacheLocation = FvDevice->CachedFv;
|
||||
LbaIndex = 0;
|
||||
LbaOffset = FwVolHeader->HeaderLength;
|
||||
while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
|
||||
|
||||
for (Index = 0; Index < BlockMap->NumBlocks; Index ++) {
|
||||
|
||||
Size = BlockMap->Length;
|
||||
if (Index == 0) {
|
||||
//
|
||||
// Cache does not include FV Header
|
||||
//
|
||||
Size -= LbaOffset;
|
||||
}
|
||||
Status = Fvb->Read (Fvb,
|
||||
LbaIndex,
|
||||
LbaOffset,
|
||||
&Size,
|
||||
CacheLocation
|
||||
);
|
||||
//
|
||||
// Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->Length
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// After we skip Fv Header always read from start of block
|
||||
//
|
||||
LbaOffset = 0;
|
||||
|
||||
LbaIndex++;
|
||||
CacheLocation += Size;
|
||||
}
|
||||
BlockMap++;
|
||||
}
|
||||
|
||||
//
|
||||
// Scan to check the free space & File list
|
||||
//
|
||||
if (FvbAttributes & EFI_FVB_ERASE_POLARITY) {
|
||||
FvDevice->ErasePolarity = 1;
|
||||
} else {
|
||||
FvDevice->ErasePolarity = 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// go through the whole FV cache, check the consistence of the FV.
|
||||
// Make a linked list off all the Ffs file headers
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
InitializeListHead (&FvDevice->FfsFileListHeader);
|
||||
|
||||
//
|
||||
// Build FFS list
|
||||
//
|
||||
FfsHeader = (EFI_FFS_FILE_HEADER *)FvDevice->CachedFv;
|
||||
TopFvAddress = FvDevice->EndOfCachedFv;
|
||||
while ((UINT8 *)FfsHeader < TopFvAddress) {
|
||||
|
||||
TestLength = TopFvAddress - ((UINT8 *)FfsHeader);
|
||||
if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
|
||||
TestLength = sizeof (EFI_FFS_FILE_HEADER);
|
||||
}
|
||||
|
||||
if (IsBufferErased (FvDevice->ErasePolarity, FfsHeader, TestLength)) {
|
||||
//
|
||||
// We have found the free space so we are done!
|
||||
//
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (!IsValidFfsHeader (FvDevice->ErasePolarity, FfsHeader, &FileState)) {
|
||||
if ((FileState == EFI_FILE_HEADER_INVALID) ||
|
||||
(FileState == EFI_FILE_HEADER_CONSTRUCTION)) {
|
||||
FfsHeader++;
|
||||
|
||||
continue;
|
||||
|
||||
} else {
|
||||
//
|
||||
// File system is corrputed
|
||||
//
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsValidFfsFile (FvDevice->ErasePolarity, FfsHeader)) {
|
||||
//
|
||||
// File system is corrupted
|
||||
//
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Size[3] is a three byte array, read 4 bytes and throw one away
|
||||
//
|
||||
FileLength = *(UINT32 *)&FfsHeader->Size[0] & 0x00FFFFFF;
|
||||
|
||||
FileState = GetFileState (FvDevice->ErasePolarity, FfsHeader);
|
||||
|
||||
//
|
||||
// check for non-deleted file
|
||||
//
|
||||
if (FileState != EFI_FILE_DELETED) {
|
||||
//
|
||||
// Create a FFS list entry for each non-deleted file
|
||||
//
|
||||
FfsFileEntry = CoreAllocateZeroBootServicesPool (sizeof (FFS_FILE_LIST_ENTRY));
|
||||
if (FfsFileEntry == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
FfsFileEntry->FfsHeader = FfsHeader;
|
||||
InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);
|
||||
}
|
||||
|
||||
FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FfsHeader) + FileLength);
|
||||
|
||||
//
|
||||
// Adjust pointer to the next 8-byte aligned boundry.
|
||||
//
|
||||
FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINTN)FfsHeader + 7) & ~0x07);
|
||||
|
||||
}
|
||||
|
||||
Done:
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreeFvDeviceResource (FvDevice);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
NotifyFwVolBlock (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This notification function is invoked when an instance of the
|
||||
EFI_FW_VOLUME_BLOCK_PROTOCOL is produced. It layers an instance of the
|
||||
EFI_FIRMWARE_VOLUME_PROTOCOL on the same handle. This is the function where
|
||||
the actual initialization of the EFI_FIRMWARE_VOLUME_PROTOCOL is done.
|
||||
|
||||
Arguments:
|
||||
Event - The event that occured
|
||||
Context - For EFI compatiblity. Not used.
|
||||
|
||||
Returns:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
//
|
||||
// Examine all new handles
|
||||
//
|
||||
for (;;) {
|
||||
//
|
||||
// Get the next handle
|
||||
//
|
||||
BufferSize = sizeof (Handle);
|
||||
Status = CoreLocateHandle (
|
||||
ByRegisterNotify,
|
||||
NULL,
|
||||
gEfiFwVolBlockNotifyReg,
|
||||
&BufferSize,
|
||||
&Handle
|
||||
);
|
||||
|
||||
//
|
||||
// If not found, we're done
|
||||
//
|
||||
if (EFI_NOT_FOUND == Status) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the FirmwareVolumeBlock protocol on that handle
|
||||
//
|
||||
Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
|
||||
//
|
||||
// Make sure the Fv Header is O.K.
|
||||
//
|
||||
Status = GetFwVolHeader (Fvb, &FwVolHeader);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VerifyFvHeaderChecksum (FwVolHeader)) {
|
||||
CoreFreePool (FwVolHeader);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Check to see that the file system is indeed formatted in a way we can
|
||||
// understand it...
|
||||
//
|
||||
if (!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystemGuid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if there is an FV protocol already installed in that handle
|
||||
//
|
||||
Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Fv);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Update Fv to use a new Fvb
|
||||
//
|
||||
FvDevice = _CR (Fv, FV_DEVICE, Fv);
|
||||
if (FvDevice->Signature == FV_DEVICE_SIGNATURE) {
|
||||
//
|
||||
// Only write into our device structure if it's our device structure
|
||||
//
|
||||
FvDevice->Fvb = Fvb;
|
||||
}
|
||||
|
||||
} else {
|
||||
//
|
||||
// No FwVol protocol on the handle so create a new one
|
||||
//
|
||||
FvDevice = CoreAllocateCopyPool (sizeof (FV_DEVICE), &mFvDevice);
|
||||
if (FvDevice == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
FvDevice->Fvb = Fvb;
|
||||
FvDevice->Handle = Handle;
|
||||
FvDevice->FwVolHeader = FwVolHeader;
|
||||
FvDevice->Fv.ParentHandle = Fvb->ParentHandle;
|
||||
|
||||
//
|
||||
// Install an New FV protocol on the existing handle
|
||||
//
|
||||
Status = CoreInstallProtocolInterface (
|
||||
&Handle,
|
||||
&gEfiFirmwareVolumeProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&FvDevice->Fv
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolDriverInit (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine is the driver initialization entry point. It initializes the
|
||||
libraries, and registers two notification functions. These notification
|
||||
functions are responsible for building the FV stack dynamically.
|
||||
|
||||
Arguments:
|
||||
ImageHandle - The image handle.
|
||||
SystemTable - The system table.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Function successfully returned.
|
||||
|
||||
--*/
|
||||
{
|
||||
gEfiFwVolBlockEvent = CoreCreateProtocolNotifyEvent (
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
TPL_CALLBACK,
|
||||
NotifyFwVolBlock,
|
||||
NULL,
|
||||
&gEfiFwVolBlockNotifyReg,
|
||||
TRUE
|
||||
);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
99
MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c
Normal file
99
MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
FwVolAttrib.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implements get/set firmware volume attributes
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvGetVolumeAttributes (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
OUT EFI_FV_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves attributes, insures positive polarity of attribute bits, returns
|
||||
resulting attributes in output parameter
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - output buffer which contains attributes
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully got volume attributes
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_FVB_ATTRIBUTES FvbAttributes;
|
||||
|
||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||
Fvb = FvDevice->Fvb;
|
||||
|
||||
if (FvDevice->CachedFv == NULL) {
|
||||
Status = FvCheck (FvDevice);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// First get the Firmware Volume Block Attributes
|
||||
//
|
||||
Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
|
||||
|
||||
//
|
||||
// Mask out Fvb bits that are not defined in FV
|
||||
//
|
||||
FvbAttributes &= 0xfffff0ff;
|
||||
|
||||
*Attributes = (EFI_FV_ATTRIBUTES)FvbAttributes;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvSetVolumeAttributes (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN OUT EFI_FV_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Sets current attributes for volume
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - At input, contains attributes to be set. At output contains
|
||||
new value of FV
|
||||
|
||||
Returns:
|
||||
EFI_UNSUPPORTED - Could not be set.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
516
MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
Normal file
516
MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
Normal file
@@ -0,0 +1,516 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
FwVolRead.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implements read firmware file
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
/*++
|
||||
|
||||
Required Alignment Alignment Value in FFS Alignment Value in
|
||||
(bytes) Attributes Field Firmware Volume Interfaces
|
||||
1 0 0
|
||||
2 0 1
|
||||
4 0 2
|
||||
8 0 3
|
||||
16 1 4
|
||||
128 2 7
|
||||
512 3 9
|
||||
1 KB 4 10
|
||||
4 KB 5 12
|
||||
32 KB 6 15
|
||||
64 KB 7 16
|
||||
|
||||
--*/
|
||||
|
||||
UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_FV_FILE_ATTRIBUTES
|
||||
FfsAttributes2FvFileAttributes (
|
||||
IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Convert the FFS File Attributes to FV File Attributes
|
||||
|
||||
Arguments:
|
||||
FfsAttributes - The attributes of UINT8 type.
|
||||
|
||||
Returns:
|
||||
The attributes of EFI_FV_FILE_ATTRIBUTES
|
||||
|
||||
--*/
|
||||
{
|
||||
FfsAttributes = (EFI_FFS_FILE_ATTRIBUTES)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
|
||||
ASSERT (FfsAttributes < 8);
|
||||
|
||||
return (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[FfsAttributes];
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvGetNextFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN OUT VOID *Key,
|
||||
IN OUT EFI_FV_FILETYPE *FileType,
|
||||
OUT EFI_GUID *NameGuid,
|
||||
OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Given the input key, search for the next matching file in the volume.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
FileType - FileType is a pointer to a caller allocated
|
||||
EFI_FV_FILETYPE. The GetNextFile() API can filter it's
|
||||
search for files based on the value of *FileType input.
|
||||
A *FileType input of 0 causes GetNextFile() to search for
|
||||
files of all types. If a file is found, the file's type
|
||||
is returned in *FileType. *FileType is not modified if
|
||||
no file is found.
|
||||
Key - Key is a pointer to a caller allocated buffer that
|
||||
contains implementation specific data that is used to
|
||||
track where to begin the search for the next file.
|
||||
The size of the buffer must be at least This->KeySize
|
||||
bytes long. To reinitialize the search and begin from
|
||||
the beginning of the firmware volume, the entire buffer
|
||||
must be cleared to zero. Other than clearing the buffer
|
||||
to initiate a new search, the caller must not modify the
|
||||
data in the buffer between calls to GetNextFile().
|
||||
NameGuid - NameGuid is a pointer to a caller allocated EFI_GUID.
|
||||
If a file is found, the file's name is returned in
|
||||
*NameGuid. *NameGuid is not modified if no file is
|
||||
found.
|
||||
Attributes - Attributes is a pointer to a caller allocated
|
||||
EFI_FV_FILE_ATTRIBUTES. If a file is found, the file's
|
||||
attributes are returned in *Attributes. *Attributes is
|
||||
not modified if no file is found.
|
||||
Size - Size is a pointer to a caller allocated UINTN.
|
||||
If a file is found, the file's size is returned in *Size.
|
||||
*Size is not modified if no file is found.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully find the file.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Fv could not read.
|
||||
EFI_NOT_FOUND - No matching file found.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_FV_ATTRIBUTES FvAttributes;
|
||||
EFI_FFS_FILE_HEADER *FfsFileHeader;
|
||||
UINTN *KeyValue;
|
||||
LIST_ENTRY *Link;
|
||||
FFS_FILE_LIST_ENTRY *FfsFileEntry;
|
||||
UINTN FileLength;
|
||||
|
||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||
|
||||
Status = FvGetVolumeAttributes (This, &FvAttributes);
|
||||
if (EFI_ERROR (Status)){
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if read operation is enabled
|
||||
//
|
||||
if ((FvAttributes & EFI_FV_READ_STATUS) == 0) {
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (*FileType > EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
|
||||
//
|
||||
// File type needs to be in 0 - 0x0B
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
KeyValue = (UINTN *)Key;
|
||||
for (;;) {
|
||||
if (*KeyValue == 0) {
|
||||
//
|
||||
// Search for 1st matching file
|
||||
//
|
||||
Link = &FvDevice->FfsFileListHeader;
|
||||
} else {
|
||||
//
|
||||
// Key is pointer to FFsFileEntry, so get next one
|
||||
//
|
||||
Link = (LIST_ENTRY *)(*KeyValue);
|
||||
}
|
||||
|
||||
if (Link->ForwardLink == &FvDevice->FfsFileListHeader) {
|
||||
//
|
||||
// Next is end of list so we did not find data
|
||||
//
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;
|
||||
|
||||
//
|
||||
// remember the key
|
||||
//
|
||||
*KeyValue = (UINTN)FfsFileEntry;
|
||||
|
||||
if (FfsFileHeader->Type == EFI_FV_FILETYPE_FFS_PAD) {
|
||||
//
|
||||
// we ignore pad files
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*FileType == 0) {
|
||||
//
|
||||
// Process all file types so we have a match
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
if (*FileType == FfsFileHeader->Type) {
|
||||
//
|
||||
// Found a matching file type
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Return FileType, NameGuid, and Attributes
|
||||
//
|
||||
*FileType = FfsFileHeader->Type;
|
||||
CopyMem (NameGuid, &FfsFileHeader->Name, sizeof (EFI_GUID));
|
||||
*Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);
|
||||
|
||||
//
|
||||
// Read four bytes out of the 3 byte array and throw out extra data
|
||||
//
|
||||
FileLength = *(UINT32 *)&FfsFileHeader->Size[0] & 0x00FFFFFF;
|
||||
|
||||
//
|
||||
// we need to substract the header size
|
||||
//
|
||||
*Size = FileLength - sizeof(EFI_FFS_FILE_HEADER);
|
||||
|
||||
if (FfsFileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||
//
|
||||
// If tail is present substract it's size;
|
||||
//
|
||||
*Size -= sizeof(EFI_FFS_FILE_TAIL);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvReadFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT EFI_FV_FILETYPE *FoundType,
|
||||
OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Locates a file in the firmware volume and
|
||||
copies it to the supplied buffer.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
NameGuid - Pointer to an EFI_GUID, which is the filename.
|
||||
Buffer - Buffer is a pointer to pointer to a buffer in
|
||||
which the file or section contents or are returned.
|
||||
BufferSize - BufferSize is a pointer to caller allocated
|
||||
UINTN. On input *BufferSize indicates the size
|
||||
in bytes of the memory region pointed to by
|
||||
Buffer. On output, *BufferSize contains the number
|
||||
of bytes required to read the file.
|
||||
FoundType - FoundType is a pointer to a caller allocated
|
||||
EFI_FV_FILETYPE that on successful return from Read()
|
||||
contains the type of file read. This output reflects
|
||||
the file type irrespective of the value of the
|
||||
SectionType input.
|
||||
FileAttributes - FileAttributes is a pointer to a caller allocated
|
||||
EFI_FV_FILE_ATTRIBUTES. On successful return from
|
||||
Read(), *FileAttributes contains the attributes of
|
||||
the file read.
|
||||
AuthenticationStatus - AuthenticationStatus is a pointer to a caller
|
||||
allocated UINTN in which the authentication status
|
||||
is returned.
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully read to memory buffer.
|
||||
EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
|
||||
EFI_NOT_FOUND - Not found.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Could not read.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_GUID SearchNameGuid;
|
||||
EFI_FV_FILETYPE LocalFoundType;
|
||||
EFI_FV_FILE_ATTRIBUTES LocalAttributes;
|
||||
UINTN FileSize;
|
||||
UINT8 *SrcPtr;
|
||||
EFI_FFS_FILE_HEADER *FfsHeader;
|
||||
UINTN InputBufferSize;
|
||||
|
||||
if (NULL == NameGuid) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||
|
||||
|
||||
//
|
||||
// Keep looking until we find the matching NameGuid.
|
||||
// The Key is really an FfsFileEntry
|
||||
//
|
||||
FvDevice->LastKey = 0;
|
||||
do {
|
||||
LocalFoundType = 0;
|
||||
Status = FvGetNextFile (
|
||||
This,
|
||||
&FvDevice->LastKey,
|
||||
&LocalFoundType,
|
||||
&SearchNameGuid,
|
||||
&LocalAttributes,
|
||||
&FileSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
} while (!CompareGuid (&SearchNameGuid, NameGuid));
|
||||
|
||||
//
|
||||
// Get a pointer to the header
|
||||
//
|
||||
FfsHeader = FvDevice->LastKey->FfsHeader;
|
||||
|
||||
//
|
||||
// Remember callers buffer size
|
||||
//
|
||||
InputBufferSize = *BufferSize;
|
||||
|
||||
//
|
||||
// Calculate return values
|
||||
//
|
||||
*FoundType = FfsHeader->Type;
|
||||
*FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);
|
||||
*AuthenticationStatus = 0;
|
||||
*BufferSize = FileSize;
|
||||
|
||||
if (Buffer == NULL) {
|
||||
//
|
||||
// If Buffer is NULL, we only want to get the information colected so far
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip over file header
|
||||
//
|
||||
SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
if (*Buffer == NULL) {
|
||||
//
|
||||
// Caller passed in a pointer so allocate buffer for them
|
||||
//
|
||||
*Buffer = CoreAllocateBootServicesPool (FileSize);
|
||||
if (*Buffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
} else if (FileSize > InputBufferSize) {
|
||||
//
|
||||
// Callers buffer was not big enough
|
||||
//
|
||||
Status = EFI_WARN_BUFFER_TOO_SMALL;
|
||||
FileSize = InputBufferSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy data into callers buffer
|
||||
//
|
||||
CopyMem (*Buffer, SrcPtr, FileSize);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvReadFileSection (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN SectionInstance,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Locates a section in a given FFS File and
|
||||
copies it to the supplied buffer (not including section header).
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
NameGuid - Pointer to an EFI_GUID, which is the filename.
|
||||
SectionType - Indicates the section type to return.
|
||||
SectionInstance - Indicates which instance of sections with a type of
|
||||
SectionType to return.
|
||||
Buffer - Buffer is a pointer to pointer to a buffer in which
|
||||
the file or section contents or are returned.
|
||||
BufferSize - BufferSize is a pointer to caller allocated UINTN.
|
||||
AuthenticationStatus -AuthenticationStatus is a pointer to a caller
|
||||
allocated UINT32 in which the authentication status
|
||||
is returned.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully read the file section into buffer.
|
||||
EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
|
||||
EFI_NOT_FOUND - Section not found.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Could not read.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_FV_FILETYPE FileType;
|
||||
EFI_FV_FILE_ATTRIBUTES FileAttributes;
|
||||
UINTN FileSize;
|
||||
UINT8 *FileBuffer;
|
||||
EFI_SECTION_EXTRACTION_PROTOCOL *Sep;
|
||||
FFS_FILE_LIST_ENTRY *FfsEntry;
|
||||
|
||||
if (NULL == NameGuid || Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Read the whole file into buffer
|
||||
//
|
||||
FileBuffer = NULL;
|
||||
Status = FvReadFile (
|
||||
This,
|
||||
NameGuid,
|
||||
(VOID **)&FileBuffer,
|
||||
&FileSize,
|
||||
&FileType,
|
||||
&FileAttributes,
|
||||
AuthenticationStatus
|
||||
);
|
||||
//
|
||||
// Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.
|
||||
//
|
||||
FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Check to see that the file actually HAS sections before we go any further.
|
||||
//
|
||||
if (FileType == EFI_FV_FILETYPE_RAW) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Use FfsEntry to cache Section Extraction Protocol Inforomation
|
||||
//
|
||||
if (FfsEntry->StreamHandle == 0) {
|
||||
//
|
||||
// Located the protocol
|
||||
//
|
||||
Status = CoreLocateProtocol (&gEfiSectionExtractionProtocolGuid, NULL, (VOID **)&Sep);
|
||||
//
|
||||
// Section Extraction Protocol is part of Dxe Core so this should never fail
|
||||
//
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = Sep->OpenSectionStream (
|
||||
Sep,
|
||||
FileSize,
|
||||
FileBuffer,
|
||||
&FfsEntry->StreamHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
FfsEntry->Sep = Sep;
|
||||
} else {
|
||||
//
|
||||
// Get cached copy of Sep
|
||||
//
|
||||
Sep = FfsEntry->Sep;
|
||||
}
|
||||
|
||||
//
|
||||
// If SectionType == 0 We need the whole section stream
|
||||
//
|
||||
Status = Sep->GetSection (
|
||||
Sep,
|
||||
FfsEntry->StreamHandle,
|
||||
(SectionType == 0) ? NULL : &SectionType,
|
||||
NULL,
|
||||
(SectionType == 0) ? 0 : SectionInstance,
|
||||
Buffer,
|
||||
BufferSize,
|
||||
AuthenticationStatus
|
||||
);
|
||||
|
||||
//
|
||||
// Close of stream defered to close of FfsHeader list to allow SEP to cache data
|
||||
//
|
||||
|
||||
Done:
|
||||
CoreFreePool (FileBuffer);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
60
MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c
Normal file
60
MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
FwVolWrite.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implements write firmware file
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvWriteFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN UINT32 NumberOfFiles,
|
||||
IN EFI_FV_WRITE_POLICY WritePolicy,
|
||||
IN EFI_FV_WRITE_FILE_DATA *FileData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Writes one or more files to the firmware volume.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
NumberOfFiles - Number of files.
|
||||
WritePolicy - WritePolicy indicates the level of reliability for
|
||||
the write in the event of a power failure or other
|
||||
system failure during the write operation.
|
||||
FileData - FileData is an pointer to an array of EFI_FV_WRITE_DATA.
|
||||
Each element of FileData[] represents a file to be written.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Files successfully written to firmware volume
|
||||
EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_WRITE_PROTECTED - Write protected.
|
||||
EFI_NOT_FOUND - Not found.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
EFI_UNSUPPORTED - This function not supported.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
Reference in New Issue
Block a user