moved everything to chookspace
This commit is contained in:
358
gnu-efi/lib/sread.c
Normal file
358
gnu-efi/lib/sread.c
Normal file
@@ -0,0 +1,358 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 1998 Intel Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sread.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Simple read file access
|
||||
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
#define SIMPLE_READ_SIGNATURE EFI_SIGNATURE_32('s','r','d','r')
|
||||
typedef struct _SIMPLE_READ_FILE {
|
||||
UINTN Signature;
|
||||
BOOLEAN FreeBuffer;
|
||||
VOID *Source;
|
||||
UINTN SourceSize;
|
||||
EFI_FILE_HANDLE FileHandle;
|
||||
} SIMPLE_READ_HANDLE;
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
OpenSimpleReadFile (
|
||||
IN BOOLEAN BootPolicy,
|
||||
IN VOID *SourceBuffer OPTIONAL,
|
||||
IN UINTN SourceSize,
|
||||
IN OUT EFI_DEVICE_PATH **FilePath,
|
||||
OUT EFI_HANDLE *DeviceHandle,
|
||||
OUT SIMPLE_READ_FILE *SimpleReadHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Opens a file for (simple) reading. The simple read abstraction
|
||||
will access the file either from a memory copy, from a file
|
||||
system interface, or from the load file interface.
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
A handle to access the file
|
||||
|
||||
--*/
|
||||
{
|
||||
SIMPLE_READ_HANDLE *FHand;
|
||||
EFI_DEVICE_PATH *UserFilePath;
|
||||
EFI_DEVICE_PATH *TempFilePath;
|
||||
EFI_DEVICE_PATH *TempFilePathPtr;
|
||||
FILEPATH_DEVICE_PATH *FilePathNode;
|
||||
EFI_FILE_HANDLE FileHandle, LastHandle;
|
||||
EFI_STATUS Status;
|
||||
EFI_LOAD_FILE_INTERFACE *LoadFile;
|
||||
|
||||
FHand = NULL;
|
||||
UserFilePath = *FilePath;
|
||||
|
||||
//
|
||||
// Allocate a new simple read handle structure
|
||||
//
|
||||
|
||||
FHand = AllocateZeroPool (sizeof(SIMPLE_READ_HANDLE));
|
||||
if (!FHand) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
*SimpleReadHandle = (SIMPLE_READ_FILE) FHand;
|
||||
FHand->Signature = SIMPLE_READ_SIGNATURE;
|
||||
|
||||
//
|
||||
// If the caller passed a copy of the file, then just use it
|
||||
//
|
||||
|
||||
if (SourceBuffer) {
|
||||
FHand->Source = SourceBuffer;
|
||||
FHand->SourceSize = SourceSize;
|
||||
*DeviceHandle = NULL;
|
||||
Status = EFI_SUCCESS;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to access the file via a file system interface
|
||||
//
|
||||
|
||||
FileHandle = NULL;
|
||||
Status = uefi_call_wrapper(BS->LocateDevicePath, 3, &FileSystemProtocol, FilePath, DeviceHandle);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
FileHandle = LibOpenRoot (*DeviceHandle);
|
||||
}
|
||||
|
||||
Status = FileHandle ? EFI_SUCCESS : EFI_UNSUPPORTED;
|
||||
|
||||
//
|
||||
// To access as a filesystem, the filepath should only
|
||||
// contain filepath components. Follow the filepath nodes
|
||||
// and find the target file
|
||||
//
|
||||
|
||||
FilePathNode = (FILEPATH_DEVICE_PATH *) *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) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// If there's been an error, stop
|
||||
//
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Open this file path node
|
||||
//
|
||||
|
||||
LastHandle = FileHandle;
|
||||
FileHandle = NULL;
|
||||
|
||||
Status = uefi_call_wrapper(
|
||||
LastHandle->Open,
|
||||
5,
|
||||
LastHandle,
|
||||
&FileHandle,
|
||||
FilePathNode->PathName,
|
||||
EFI_FILE_MODE_READ,
|
||||
0
|
||||
);
|
||||
|
||||
//
|
||||
// Close the last node
|
||||
//
|
||||
|
||||
uefi_call_wrapper(LastHandle->Close, 1, LastHandle);
|
||||
|
||||
//
|
||||
// Get the next node
|
||||
//
|
||||
|
||||
FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode(&FilePathNode->Header);
|
||||
}
|
||||
|
||||
//
|
||||
// If success, return the FHand
|
||||
//
|
||||
|
||||
if (!EFI_ERROR(Status)) {
|
||||
ASSERT(FileHandle);
|
||||
FHand->FileHandle = FileHandle;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup from filesystem access
|
||||
//
|
||||
|
||||
if (FileHandle) {
|
||||
uefi_call_wrapper(FileHandle->Close, 1, FileHandle);
|
||||
FileHandle = NULL;
|
||||
*FilePath = UserFilePath;
|
||||
}
|
||||
|
||||
//
|
||||
// If the error is something other then unsupported, return it
|
||||
//
|
||||
|
||||
if (Status != EFI_UNSUPPORTED) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to access the file via the load file protocol
|
||||
//
|
||||
|
||||
Status = LibDevicePathToInterface (&LoadFileProtocol, *FilePath, (VOID*)&LoadFile);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
|
||||
TempFilePath = DuplicateDevicePath (*FilePath);
|
||||
|
||||
TempFilePathPtr = TempFilePath;
|
||||
|
||||
Status = uefi_call_wrapper(BS->LocateDevicePath, 3, &LoadFileProtocol, &TempFilePath, DeviceHandle);
|
||||
|
||||
FreePool (TempFilePathPtr);
|
||||
|
||||
//
|
||||
// Determine the size of buffer needed to hold the file
|
||||
//
|
||||
|
||||
SourceSize = 0;
|
||||
Status = uefi_call_wrapper(
|
||||
LoadFile->LoadFile,
|
||||
5,
|
||||
LoadFile,
|
||||
*FilePath,
|
||||
BootPolicy,
|
||||
&SourceSize,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// We expect a buffer too small error to inform us
|
||||
// of the buffer size needed
|
||||
//
|
||||
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
SourceBuffer = AllocatePool (SourceSize);
|
||||
|
||||
if (SourceBuffer) {
|
||||
FHand->FreeBuffer = TRUE;
|
||||
FHand->Source = SourceBuffer;
|
||||
FHand->SourceSize = SourceSize;
|
||||
|
||||
Status = uefi_call_wrapper(
|
||||
LoadFile->LoadFile,
|
||||
5,
|
||||
LoadFile,
|
||||
*FilePath,
|
||||
BootPolicy,
|
||||
&SourceSize,
|
||||
SourceBuffer
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If success, return FHand
|
||||
//
|
||||
|
||||
if (!EFI_ERROR(Status) || Status == EFI_ALREADY_STARTED) {
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Nothing else to try
|
||||
//
|
||||
|
||||
DEBUG ((D_LOAD|D_WARN, "OpenSimpleReadFile: Device did not support a known load protocol\n"));
|
||||
Status = EFI_UNSUPPORTED;
|
||||
|
||||
Done:
|
||||
|
||||
//
|
||||
// If the file was not accessed, clean up
|
||||
//
|
||||
if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
|
||||
if (FHand) {
|
||||
if (FHand->FreeBuffer) {
|
||||
FreePool (FHand->Source);
|
||||
}
|
||||
|
||||
FreePool (FHand);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
ReadSimpleReadFile (
|
||||
IN SIMPLE_READ_FILE UserHandle,
|
||||
IN UINTN Offset,
|
||||
IN OUT UINTN *ReadSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
UINTN EndPos;
|
||||
SIMPLE_READ_HANDLE *FHand;
|
||||
EFI_STATUS Status;
|
||||
|
||||
FHand = UserHandle;
|
||||
ASSERT (FHand->Signature == SIMPLE_READ_SIGNATURE);
|
||||
if (FHand->Source) {
|
||||
|
||||
//
|
||||
// Move data from our local copy of the file
|
||||
//
|
||||
|
||||
EndPos = Offset + *ReadSize;
|
||||
if (EndPos > FHand->SourceSize) {
|
||||
*ReadSize = FHand->SourceSize - Offset;
|
||||
if (Offset >= FHand->SourceSize) {
|
||||
*ReadSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CopyMem (Buffer, (CHAR8 *) FHand->Source + Offset, *ReadSize);
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// Read data from the file
|
||||
//
|
||||
|
||||
Status = uefi_call_wrapper(FHand->FileHandle->SetPosition, 2, FHand->FileHandle, Offset);
|
||||
|
||||
if (!EFI_ERROR(Status)) {
|
||||
Status = uefi_call_wrapper(FHand->FileHandle->Read, 3, FHand->FileHandle, ReadSize, Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CloseSimpleReadFile (
|
||||
IN SIMPLE_READ_FILE UserHandle
|
||||
)
|
||||
{
|
||||
SIMPLE_READ_HANDLE *FHand;
|
||||
|
||||
FHand = UserHandle;
|
||||
ASSERT (FHand->Signature == SIMPLE_READ_SIGNATURE);
|
||||
|
||||
//
|
||||
// Free any file handle we opened
|
||||
//
|
||||
|
||||
if (FHand->FileHandle) {
|
||||
uefi_call_wrapper(FHand->FileHandle->Close, 1, FHand->FileHandle);
|
||||
}
|
||||
|
||||
//
|
||||
// If we allocated the Source buffer, free it
|
||||
//
|
||||
|
||||
if (FHand->FreeBuffer) {
|
||||
FreePool (FHand->Source);
|
||||
}
|
||||
|
||||
//
|
||||
// Done with this simple read file handle
|
||||
//
|
||||
|
||||
FreePool (FHand);
|
||||
}
|
||||
Reference in New Issue
Block a user