summaryrefslogtreecommitdiff
path: root/source/os_specific/efi/oseficlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/os_specific/efi/oseficlib.c')
-rw-r--r--source/os_specific/efi/oseficlib.c142
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);
}