diff options
author | Lv Zheng <lv.zheng@intel.com> | 2016-05-23 23:06:56 +0800 |
---|---|---|
committer | Lv Zheng <lv.zheng@intel.com> | 2016-06-06 12:58:31 +0800 |
commit | fa8cacd85745e3aa7d454c299e8cd2dd4bfa3771 (patch) | |
tree | 76f0d8b8a523157e3c7b2b58b033005920b8ad07 | |
parent | 9bba284f4de0268356af8c004bf8482e079eb842 (diff) | |
download | acpica-fa8cacd85745e3aa7d454c299e8cd2dd4bfa3771.tar.gz |
Clib/EFI: Add file position seeking/telling support
This patch adds file position seeking/telling support. Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
-rw-r--r-- | source/include/platform/acefiex.h | 31 | ||||
-rw-r--r-- | source/os_specific/service_layers/oseficlib.c | 142 |
2 files changed, 171 insertions, 2 deletions
diff --git a/source/include/platform/acefiex.h b/source/include/platform/acefiex.h index 17f347221..f78f034ad 100644 --- a/source/include/platform/acefiex.h +++ b/source/include/platform/acefiex.h @@ -154,6 +154,20 @@ typedef struct { UINT8 Data4[8]; } EFI_GUID; +typedef struct { + UINT16 Year; /* 1998 - 20XX */ + UINT8 Month; /* 1 - 12 */ + UINT8 Day; /* 1 - 31 */ + UINT8 Hour; /* 0 - 23 */ + UINT8 Minute; /* 0 - 59 */ + UINT8 Second; /* 0 - 59 */ + UINT8 Pad1; + UINT32 Nanosecond; /* 0 - 999,999,999 */ + INT16 TimeZone; /* -1440 to 1440 or 2047 */ + UINT8 Daylight; + UINT8 Pad2; +} EFI_TIME; + typedef struct _EFI_DEVICE_PATH { UINT8 Type; UINT8 SubType; @@ -434,6 +448,22 @@ EFI_STATUS struct _EFI_FILE_HANDLE *File, UINT64 *Position); +#define EFI_FILE_INFO_ID \ + { 0x9576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +typedef struct { + UINT64 Size; + UINT64 FileSize; + UINT64 PhysicalSize; + EFI_TIME CreateTime; + EFI_TIME LastAccessTime; + EFI_TIME ModificationTime; + UINT64 Attribute; + CHAR16 FileName[1]; +} EFI_FILE_INFO; + +#define SIZE_OF_EFI_FILE_INFO ACPI_OFFSET(EFI_FILE_INFO, FileName) + typedef EFI_STATUS (EFIAPI *EFI_FILE_GET_INFO) ( @@ -940,5 +970,6 @@ extern EFI_GUID AcpiGbl_LoadedImageProtocol; extern EFI_GUID AcpiGbl_TextInProtocol; extern EFI_GUID AcpiGbl_TextOutProtocol; extern EFI_GUID AcpiGbl_FileSystemProtocol; +extern EFI_GUID AcpiGbl_GenericFileInfo; #endif /* __ACEFIEX_H__ */ diff --git a/source/os_specific/service_layers/oseficlib.c b/source/os_specific/service_layers/oseficlib.c index 5d6b1a7f4..7839f2a0c 100644 --- a/source/os_specific/service_layers/oseficlib.c +++ b/source/os_specific/service_layers/oseficlib.c @@ -153,6 +153,11 @@ AcpiEfiConvertArgcv ( char ***ArgvPtr, char **BufferPtr); +static int +AcpiEfiGetFileInfo ( + FILE *File, + EFI_FILE_INFO **InfoPtr); + static CHAR16 * AcpiEfiFlushFile ( FILE *File, @@ -169,6 +174,7 @@ EFI_GUID AcpiGbl_LoadedImageProtocol = LOADED_IMAGE_PROTOCOL; EFI_GUID AcpiGbl_TextInProtocol = SIMPLE_TEXT_INPUT_PROTOCOL; EFI_GUID AcpiGbl_TextOutProtocol = SIMPLE_TEXT_OUTPUT_PROTOCOL; EFI_GUID AcpiGbl_FileSystemProtocol = SIMPLE_FILE_SYSTEM_PROTOCOL; +EFI_GUID AcpiGbl_GenericFileInfo = EFI_FILE_INFO_ID; int errno = 0; @@ -680,11 +686,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, + EFI_FILE_INFO **InfoPtr) +{ + EFI_STATUS EfiStatus = EFI_BUFFER_TOO_SMALL; + EFI_FILE_INFO *Buffer = NULL; + UINTN BufferSize = SIZE_OF_EFI_FILE_INFO + 200; + EFI_FILE_HANDLE EfiFile; + + + if (!InfoPtr) + { + errno = EINVAL; + return (-EINVAL); + } + + while (EfiStatus == EFI_BUFFER_TOO_SMALL) + { + EfiFile = ACPI_CAST_PTR (EFI_FILE, File); + Buffer = AcpiOsAllocate (BufferSize); + if (!Buffer) + { + errno = ENOMEM; + return (-ENOMEM); + } + EfiStatus = uefi_call_wrapper (EfiFile->GetInfo, 4, EfiFile, + &AcpiGbl_GenericFileInfo, &BufferSize, Buffer); + if (EFI_ERROR (EfiStatus)) + { + AcpiOsFree (Buffer); + if (EfiStatus != 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. * @@ -695,8 +758,32 @@ ftell ( FILE *File) { long Offset = -1; + UINT64 Current; + EFI_STATUS EfiStatus; + EFI_FILE_HANDLE EfiFile; + if (File == stdin || File == stdout || File == stderr) + { + Offset = 0; + } + else + { + EfiFile = ACPI_CAST_PTR (EFI_FILE, File); + + EfiStatus = uefi_call_wrapper (EfiFile->GetPosition, 2, + EfiFile, &Current); + if (EFI_ERROR (EfiStatus)) + { + goto ErrorExit; + } + else + { + Offset = (long) Current; + } + } + +ErrorExit: return (Offset); } @@ -721,8 +808,59 @@ fseek ( long Offset, int From) { + EFI_FILE_INFO *Info; + int Error; + ACPI_SIZE Size; + UINT64 Current; + EFI_STATUS EfiStatus; + EFI_FILE_HANDLE EfiFile; + + + if (File == stdin || File == stdout || File == stderr) + { + return (0); + } + else + { + EfiFile = ACPI_CAST_PTR (EFI_FILE, File); + Error = AcpiEfiGetFileInfo (File, &Info); + if (Error) + { + return (Error); + } + Size = Info->FileSize; + AcpiOsFree (Info); - return (-1); + if (From == SEEK_CUR) + { + EfiStatus = uefi_call_wrapper (EfiFile->GetPosition, 2, + EfiFile, &Current); + if (EFI_ERROR (EfiStatus)) + { + errno = ERANGE; + return (-ERANGE); + } + Current += Offset; + } + else if (From == SEEK_END) + { + Current = Size - Offset; + } + else + { + Current = Offset; + } + + EfiStatus = uefi_call_wrapper (EfiFile->SetPosition, 2, + EfiFile, Current); + if (EFI_ERROR (EfiStatus)) + { + errno = ERANGE; + return (-ERANGE); + } + } + + return (0); } |