diff options
Diffstat (limited to 'source/os_specific/efi/oseficlib.c')
-rw-r--r-- | source/os_specific/efi/oseficlib.c | 142 |
1 files changed, 140 insertions, 2 deletions
diff --git a/source/os_specific/efi/oseficlib.c b/source/os_specific/efi/oseficlib.c index 96b6f9f9c..333031801 100644 --- a/source/os_specific/efi/oseficlib.c +++ b/source/os_specific/efi/oseficlib.c @@ -153,6 +153,11 @@ AcpiEfiConvertArgcv ( char ***ArgvPtr, char **BufferPtr); +static int +AcpiEfiGetFileInfo ( + FILE *File, + ACPI_EFI_FILE_INFO **InfoPtr); + static CHAR16 * AcpiEfiFlushFile ( FILE *File, @@ -172,6 +177,7 @@ ACPI_EFI_GUID AcpiGbl_LoadedImageProtocol = ACPI_EFI_LOADED_IMAGE_ ACPI_EFI_GUID AcpiGbl_TextInProtocol = ACPI_SIMPLE_TEXT_INPUT_PROTOCOL; ACPI_EFI_GUID AcpiGbl_TextOutProtocol = ACPI_SIMPLE_TEXT_OUTPUT_PROTOCOL; ACPI_EFI_GUID AcpiGbl_FileSystemProtocol = ACPI_SIMPLE_FILE_SYSTEM_PROTOCOL; +ACPI_EFI_GUID AcpiGbl_GenericFileInfo = ACPI_EFI_FILE_INFO_ID; int errno = 0; @@ -683,11 +689,68 @@ ErrorExit: /******************************************************************************* * + * FUNCTION: AcpiEfiGetFileInfo + * + * PARAMETERS: File - File descriptor + * InfoPtr - Pointer to contain file information + * + * RETURN: Clibrary error code + * + * DESCRIPTION: Get file information. + * + ******************************************************************************/ + +static int +AcpiEfiGetFileInfo ( + FILE *File, + ACPI_EFI_FILE_INFO **InfoPtr) +{ + ACPI_EFI_STATUS EfiStatus = ACPI_EFI_BUFFER_TOO_SMALL; + ACPI_EFI_FILE_INFO *Buffer = NULL; + UINTN BufferSize = SIZE_OF_ACPI_EFI_FILE_INFO + 200; + ACPI_EFI_FILE_HANDLE EfiFile; + + + if (!InfoPtr) + { + errno = EINVAL; + return (-EINVAL); + } + + while (EfiStatus == ACPI_EFI_BUFFER_TOO_SMALL) + { + EfiFile = (ACPI_EFI_FILE_HANDLE) File; + Buffer = AcpiOsAllocate (BufferSize); + if (!Buffer) + { + errno = ENOMEM; + return (-ENOMEM); + } + EfiStatus = uefi_call_wrapper (EfiFile->GetInfo, 4, EfiFile, + &AcpiGbl_GenericFileInfo, &BufferSize, Buffer); + if (ACPI_EFI_ERROR (EfiStatus)) + { + AcpiOsFree (Buffer); + if (EfiStatus != ACPI_EFI_BUFFER_TOO_SMALL) + { + errno = EIO; + return (-EIO); + } + } + } + + *InfoPtr = Buffer; + return (0); +} + + +/******************************************************************************* + * * FUNCTION: ftell * * PARAMETERS: File - File descriptor * - * RETURN: Size of current position + * RETURN: current position * * DESCRIPTION: Get current file offset. * @@ -698,8 +761,32 @@ ftell ( FILE *File) { long Offset = -1; + UINT64 Current; + ACPI_EFI_STATUS EfiStatus; + ACPI_EFI_FILE_HANDLE EfiFile; + + if (File == stdin || File == stdout || File == stderr) + { + Offset = 0; + } + else + { + EfiFile = (ACPI_EFI_FILE_HANDLE) File; + + EfiStatus = uefi_call_wrapper (EfiFile->GetPosition, 2, + EfiFile, &Current); + if (ACPI_EFI_ERROR (EfiStatus)) + { + goto ErrorExit; + } + else + { + Offset = (long) Current; + } + } +ErrorExit: return (Offset); } @@ -724,8 +811,59 @@ fseek ( long Offset, int From) { + ACPI_EFI_FILE_INFO *Info; + int Error; + ACPI_SIZE Size; + UINT64 Current; + ACPI_EFI_STATUS EfiStatus; + ACPI_EFI_FILE_HANDLE EfiFile; + + + if (File == stdin || File == stdout || File == stderr) + { + return (0); + } + else + { + EfiFile = (ACPI_EFI_FILE_HANDLE) File; + Error = AcpiEfiGetFileInfo (File, &Info); + if (Error) + { + return (Error); + } + Size = Info->FileSize; + AcpiOsFree (Info); + + if (From == SEEK_CUR) + { + EfiStatus = uefi_call_wrapper (EfiFile->GetPosition, 2, + EfiFile, &Current); + if (ACPI_EFI_ERROR (EfiStatus)) + { + errno = ERANGE; + return (-ERANGE); + } + Current += Offset; + } + else if (From == SEEK_END) + { + Current = Size - Offset; + } + else + { + Current = Offset; + } - return (-1); + EfiStatus = uefi_call_wrapper (EfiFile->SetPosition, 2, + EfiFile, Current); + if (ACPI_EFI_ERROR (EfiStatus)) + { + errno = ERANGE; + return (-ERANGE); + } + } + + return (0); } |