📄 imagefile.c
字号:
Status = CoreDevicePathToInterface (
&gEfiLoadFileProtocolGuid,
&TempFilePath,
(VOID*)&LoadFile,
DeviceHandle
);
if (!EFI_ERROR (Status)) {
//
// Call LoadFile with the correct buffer size
//
while (CoreGrowBuffer (&Status, &ImageFileHandle->Source, ImageFileHandle->SourceSize)) {
Status = LoadFile->LoadFile (
LoadFile,
TempFilePath,
BootPolicy,
&ImageFileHandle->SourceSize,
ImageFileHandle->Source
);
//
// If success or other error happens, stop loop
//
if (Status != EFI_BUFFER_TOO_SMALL) {
break;
}
}
if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {
ImageFileHandle->FreeBuffer = TRUE;
goto Done;
}
}
//
// Nothing else to try
//
DEBUG ((EFI_D_LOAD|EFI_D_WARN, "CoreOpenImageFile: Device did not support a known load protocol\n"));
Status = EFI_NOT_FOUND;
Done:
//
// If the file was not accessed, clean up
//
if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
if (ImageFileHandle->FreeBuffer) {
//
// Free the source buffer if we allocated it
//
CoreFreePool (ImageFileHandle->Source);
}
}
return Status;
}
EFI_STATUS
EFIAPI
CoreReadImageFile (
IN VOID *UserHandle,
IN UINTN Offset,
IN OUT UINTN *ReadSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Read image file (specified by UserHandle) into user specified buffer with specified offset
and length.
Arguments:
UserHandle - Image file handle
Offset - Offset to the source file
ReadSize - For input, pointer of size to read;
For output, pointer of size actually read.
Buffer - Buffer to write into
Returns:
EFI_SUCCESS - Successfully read the specified part of file into buffer.
--*/
{
UINTN EndPosition;
IMAGE_FILE_HANDLE *FHand;
FHand = (IMAGE_FILE_HANDLE *)UserHandle;
ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);
//
// Move data from our local copy of the file
//
EndPosition = Offset + *ReadSize;
if (EndPosition > FHand->SourceSize) {
*ReadSize = (UINT32)(FHand->SourceSize - Offset);
}
if (Offset >= FHand->SourceSize) {
*ReadSize = 0;
}
EfiCommonLibCopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize);
return EFI_SUCCESS;
}
EFI_STATUS
CoreDevicePathToInterface (
IN EFI_GUID *Protocol,
IN EFI_DEVICE_PATH_PROTOCOL **FilePath,
OUT VOID **Interface,
OUT EFI_HANDLE *Handle
)
/*++
Routine Description:
Search a handle to a device on a specified device path that supports a specified protocol,
interface of that protocol on that handle is another output.
Arguments:
Protocol - The protocol to search for
FilePath - The specified device path
Interface - Interface of the protocol on the handle
Handle - The handle to the device on the specified device path that supports the protocol.
Returns:
Status code.
--*/
{
EFI_STATUS Status;
Status = CoreLocateDevicePath (Protocol, FilePath, Handle);
if (!EFI_ERROR (Status)) {
Status = CoreHandleProtocol (*Handle, Protocol, Interface);
}
return Status;
}
VOID
CoreDevicePathToFileName (
IN FILEPATH_DEVICE_PATH *FilePath,
OUT CHAR16 **String
)
/*++
Routine Description:
Transfer a device's full path a string.
Arguments:
FilePath - Device path
String - The string represent the device's full path
Returns:
None
--*/
{
UINTN StringSize;
FILEPATH_DEVICE_PATH *FilePathNode;
CHAR16 *Str;
*String = NULL;
StringSize = 0;
FilePathNode = FilePath;
while (!IsDevicePathEnd (&FilePathNode->Header)) {
//
// For filesystem access each node should be a filepath component
//
if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP) {
return;
}
StringSize += EfiStrLen (FilePathNode->PathName);
FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
}
*String = CoreAllocateBootServicesPool (StringSize);
if (*String == NULL) {
return;
}
FilePathNode = FilePath;
Str = *String;
while (!IsDevicePathEnd (&FilePathNode->Header)) {
EfiStrCat (Str, FilePathNode->PathName);
FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
}
}
BOOLEAN
CoreGrowBuffer (
IN OUT EFI_STATUS *Status,
IN OUT VOID **Buffer,
IN UINTN BufferSize
)
/*++
Routine Description:
Helper function called as part of the code needed
to allocate the proper sized buffer for various
EFI interfaces.
Arguments:
Status - Current status
Buffer - Current allocated buffer, or NULL
BufferSize - Current buffer size needed
Returns:
TRUE - if the buffer was reallocated and the caller
should try the API again.
FALSE - buffer could not be allocated and the caller
should not try the API again.
--*/
{
BOOLEAN TryAgain;
TryAgain = FALSE;
//
// If this is an initial request, buffer will be null with a new buffer size
//
if (*Buffer == NULL) {
*Status = EFI_BUFFER_TOO_SMALL;
}
if (BufferSize == 0) {
return TRUE;
}
//
// If the status code is "buffer too small", resize the buffer
//
if (*Status == EFI_BUFFER_TOO_SMALL) {
if (*Buffer != NULL) {
CoreFreePool (*Buffer);
}
*Buffer = CoreAllocateBootServicesPool (BufferSize);
if (*Buffer != NULL) {
TryAgain = TRUE;
} else {
*Status = EFI_OUT_OF_RESOURCES;
}
}
//
// If there's an error, free the buffer
//
if ((!TryAgain) && (EFI_ERROR (*Status)) && (*Buffer)) {
CoreFreePool (*Buffer);
*Buffer = NULL;
}
return TryAgain;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -