summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2016-05-23 23:06:56 +0800
committerLv Zheng <lv.zheng@intel.com>2016-06-06 12:58:31 +0800
commitfa8cacd85745e3aa7d454c299e8cd2dd4bfa3771 (patch)
tree76f0d8b8a523157e3c7b2b58b033005920b8ad07
parent9bba284f4de0268356af8c004bf8482e079eb842 (diff)
downloadacpica-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.h31
-rw-r--r--source/os_specific/service_layers/oseficlib.c142
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);
}