Add device abstraction code for the UEFI Console and UEFI Shell-based file systems.
Make argv use narrow characters instead of wide characters.
Add setenv functionality.


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11907 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/StdLibPrivateInternalFiles/Include/Device/Console.h b/StdLibPrivateInternalFiles/Include/Device/Console.h
new file mode 100644
index 0000000..6f65660
--- /dev/null
+++ b/StdLibPrivateInternalFiles/Include/Device/Console.h
@@ -0,0 +1,62 @@
+/** @file

+  Declarations and macros for the console abstraction.

+

+  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials are licensed and made available

+  under the terms and conditions of the BSD License which accompanies this

+  distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+  Depends on <kfile.h>, <Device/Device.h>, <Protocol/SimpleTextIn.h>, <Uefi/UefiBaseType.h>

+**/

+#ifndef _DEVICE_UEFI_CONSOLE_H

+#define _DEVICE_UEFI_CONSOLE_H

+

+#include  <kfile.h>

+#include  <Device/Device.h>

+

+typedef struct {

+  UINT32    Column;

+  UINT32    Row;

+} CursorXY;

+

+typedef union {

+  UINT64      Offset;

+  CursorXY    XYpos;

+} XYoffset;

+

+/*  The members Cookie through Abstraction, inclusive, are the same type and order

+    for all instance structures.

+

+    All instance structures must be a multiple of sizeof(UINTN) bytes long

+*/

+typedef struct {

+  UINT32                      Cookie;       ///< Special value identifying this as a valid ConInstance

+  UINT32                      InstanceNum;  ///< Which instance is this?  Zero-based.

+  EFI_HANDLE                  Dev;          ///< Pointer to either Input or Output Protocol.

+  DeviceNode                 *Parent;       ///< Points to the parent Device Node.

+  struct fileops              Abstraction;  ///< Pointers to functions implementing this device's abstraction.

+  UINTN                       Reserved_1;   // Ensure that next member starts on an 8-byte boundary

+  UINT64                      NumRead;      ///< Number of characters Read.

+  UINT64                      NumWritten;   ///< Number of characters Written.

+  EFI_INPUT_KEY               UnGetKey;     ///< One-key pushback, for poll().

+  UINT32                      Reserved_2;   // Force the struct to be a multiple of 8-bytes long

+} ConInstance;

+

+__BEGIN_DECLS

+

+int

+EFIAPI

+da_ConOpen(

+  IN  struct __filedes   *filp,

+  IN  void               *DevInstance,

+  IN  CHAR16             *Path,

+  IN  CHAR16             *Flags

+);

+

+__END_DECLS

+

+#endif  /* _DEVICE_UEFI_CONSOLE_H */

diff --git a/StdLibPrivateInternalFiles/Include/Device/Device.h b/StdLibPrivateInternalFiles/Include/Device/Device.h
new file mode 100644
index 0000000..68eade0
--- /dev/null
+++ b/StdLibPrivateInternalFiles/Include/Device/Device.h
@@ -0,0 +1,197 @@
+/** @file

+  Device Abstraction Utility Routines

+

+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials are licensed and made available

+  under the terms and conditions of the BSD License which accompanies this

+  distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+  Depends upon: <kfile.h>

+**/

+#ifndef __DEV_UTILITY_H__

+#define __DEV_UTILITY_H__

+

+#define CON_COOKIE    0x62416F49    ///< 'IoAb'

+

+typedef enum {

+  PathAbsolute = 0,

+  PathRelative,

+  PathMapping,

+  PathError

+} PATH_CLASS;

+

+typedef struct _Device_Node {

+  LIST_ENTRY        DevList;        ///< List of registered device abstractions

+  const CHAR16     *DevName;

+  const GUID       *DevProto;

+  void             *InstanceList;   ///< Array of instances for this device

+  FO_OPEN           OpenFunc;

+  UINT32            InstanceSize;   ///< Size of each instance in the InstanceList

+  UINT32            NumInstances;   ///< Number of instances in InstanceList

+  UINT32            OpModes;        ///< Supported modes of operation

+} DeviceNode;

+

+__BEGIN_DECLS

+

+extern LIST_ENTRY       daDeviceList;     ///< List of registered devices.

+extern DeviceNode      *daDefaultDevice;  ///< Device to use if nothing else found

+extern DeviceNode      *daRootDevice;     ///< Device containing the root file system

+extern DeviceNode      *daCurrentDevice;  ///< Device currently being accessed

+

+/** Add a new device to the device list.

+

+    @param  DevName       Name of the device to add.

+    @param  DevProto      Pointer to the GUID identifying the protocol associated with this device.

+                          If DevProto is NULL, startup code will not try to find instances

+                          of this device.

+    @param  OpenFunc      Pointer to the device's Open function.

+    @param  InstanceList  Optional pointer to the device's initialized instance list.

+                          If InstanceList is NULL, the application startup code will

+                          scan for instances of the protocol identified by DevProto and

+                          populate the InstanceList in the order those protocols are found.

+    @param  NumInstance   Number of instances in InstanceList.

+    @param  Modes         Bit-mapped flags indicating operations (R, W, RW, ...) permitted to this device.

+

+**/

+DeviceNode * EFIAPI __DevRegister( const CHAR16 *DevName, GUID *DevProto, FO_OPEN OpenFunc,

+                                   void *InstanceList, int NumInstance, UINT32 InstanceSize, UINT32 Modes);

+

+/** Find a DeviceNode matching DevName or DevProto, or both.

+

+    If DevName is NULL, then the device name is not used in the search.

+    If DevProto is NULL, then the protocol GUID is not used in the search.

+    If both are NULL, then INVALID_PARAMETER is returned.

+    If both DevName and DevProto are specified, then both must match.

+    If both are specified but only one matches, then DEVICE_ERROR is returned.

+

+    @param  DevName     Name of the Device Abstraction to find.

+    @param  DevProto    GUID of the Protocol associated with the Device Abstraction.

+    @param  Node        Pointer to the pointer to receive the found Device Node's address.

+

+    @retval RETURN_SUCCESS              The desired Device Node was found.

+    @retval RETURN_INVALID_PARAMETER    Both DevName and DevProto are NULL or Node is NULL.

+    @retval RETURN_DEVICE_ERROR         One, but not both, of DevNode and DevProto matched.

+**/

+EFI_STATUS EFIAPI __DevSearch( CHAR16 *DevName, GUID *DevProto, DeviceNode **Node);

+

+/** Identify the type of path pointed to by Path.

+

+    Paths are classified based upon their initial character sequences.

+      ^\\       Absolute Path

+      ^\.       Relative Path

+      ^[^:\\]:  Mapping Path

+      .*        Relative Path

+

+    Mapping paths are broken into two parts at the ':'.  The part to the left of the ':'

+    is the Map Name, pointed to by Path, and the part to the right of the ':' is pointed

+    to by NewPath.

+

+    If Path was not a Mapping Path, then NewPath is set to Path.

+

+    @param[in]    Path      Pointer to the path to be classified.

+    @param[out]   NewPath   Pointer to the path portion of a mapping path.

+

+    @retval PathAbsolute  Path is an absolute path. NewPath points to the first '\'.

+    @retval PathRelative  Path is a relative path. NewPath = Path.

+    @retval PathMapping   Path is a mapping path.  NewPath points to the ':'.

+    @retval PathError     Path is NULL.

+**/

+PATH_CLASS EFIAPI ClassifyPath(IN wchar_t *Path, OUT wchar_t **NewPath, int * const Length);

+

+/*  Normalize a narrow-character path and produce a wide-character path

+    that has forward slashes replaced with backslashes.

+    Backslashes are directory separators in UEFI File Paths.

+

+    It is the caller's responsibility to eventually free() the returned buffer.

+

+    @param[in]    path    A pointer to the narrow-character path to be normalized.

+

+    @return     A pointer to a buffer containing the normalized, wide-character, path.

+*/

+wchar_t *

+NormalizePath( const char *path);

+

+/** Process a MBCS path returning the final absolute path and the target device.

+

+    @param path

+    @param FullPath

+    @param DevNode

+

+    @retval RETURN_SUCCESS

+    @retval RETURN_INVALID_PARAMETER

+    @retval RETURN_NOT_FOUND

+**/

+RETURN_STATUS

+EFIAPI

+ParsePath( const char *path, wchar_t **FullPath, DeviceNode **DevNode, int *Which);

+

+/** Process a wide character string representing a Mapping Path and extract the instance number.

+

+    The instance number is the sequence of decimal digits immediately to the left

+    of the ":" in the Map Name portion of a Mapping Path.

+

+    This function is called with a pointer to beginning of the Map Name.

+    Thus Path[Length] must be a ':' and Path[Length - 1] must be a decimal digit.

+    If either of these are not true, an instance value of 0 is returned.

+

+    If Path is NULL, an instance value of 0 is returned.

+

+    @param[in]  Path    Points to the beginning of a Mapping Path

+    @param[in]  Length  Number of valid characters to the left of the ':'

+

+    @return   Returns either 0 or the value of the contiguous digits to the left of the ':'.

+**/

+int

+EFIAPI

+PathInstance( const wchar_t *Path, int length);

+

+/** Transform a relative path into an absolute path.

+

+    If Path is NULL, return NULL.

+    Otherwise, pre-pend the CWD to Path then process the resulting path to:

+      - Replace "/./" with "/"

+      - Replace "/<dirname>/../" with "/"

+      - Do not allow one to back up past the root, "/"

+

+    Also sets the Current Working Device to the Root Device.

+

+    Path must be a previously allocated buffer.  PathAdjust will

+    allocate a new buffer to hold the results of the transformation

+    then free Path.  A pointer to the newly allocated buffer is returned.

+

+    @param[in]  Path    A pointer to the path to be transformed.  This buffer

+                        will always be freed.

+

+    @return   A pointer to a buffer containing the transformed path.

+**/

+wchar_t *

+EFIAPI

+PathAdjust(wchar_t *Path);

+

+/** Replace the leading portion of Path with any aliases.

+

+    Aliases are read from /etc/fstab.  If there is an associated device, the

+    Current Working Device is set to that device.

+

+    Path must be a previously allocated buffer.  PathAlias will

+    allocate a new buffer to hold the results of the transformation

+    then free Path.  A pointer to the newly allocated buffer is returned.

+

+    @param[in]    Path    A pointer to the original, unaliased, path.  This

+                          buffer is always freed.

+    @param[out]   Node    Filled in with a pointer to the Device Node describing

+                          the device abstraction associated with this path.

+

+    @return     A pointer to a buffer containing the aliased path.

+**/

+wchar_t *

+EFIAPI

+PathAlias(wchar_t *Path, DeviceNode **Node);

+

+__END_DECLS

+

+#endif  /* __DEV_UTILITY_H__ */

diff --git a/StdLibPrivateInternalFiles/Include/Efi/Console.h b/StdLibPrivateInternalFiles/Include/Efi/Console.h
deleted file mode 100644
index 8678658..0000000
--- a/StdLibPrivateInternalFiles/Include/Efi/Console.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/** @file

-  Declarations and macros for the console abstraction.

-

-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>

-  This program and the accompanying materials are licensed and made available under

-  the terms and conditions of the BSD License that accompanies this distribution.

-  The full text of the license may be found at

-  http://opensource.org/licenses/bsd-license.php.

-

-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

-

-**/

-#ifndef _LIBRARY_UEFI_CONSOLE_H

-#define _LIBRARY_UEFI_CONSOLE_H

-#include  <Protocol/SimpleTextOut.h>

-#include  <Protocol/SimpleFileSystem.h>

-

-/* The number of "special" character stream devices.

-   These include:

-    stdin, stdout, stderr

-*/

-#define NUM_SPECIAL   3

-

-typedef struct {

-  UINT32    Column;

-  UINT32    Row;

-} CursorXY;

-

-typedef union {

-  UINT64      Offset;

-  CursorXY    XYpos;

-} XYoffset;

-

-/**

-  In support of the "everything is a file" paradigm of the Standard C Library,

-  the UEFI Console support is abstracted as an instance of EFI_FILE_PROTOCOL.

-  The member functions of the protocol translate as:

-    Open      Associates a stream with one of the pseudo-devices: stdin,

-              stdout, or stderr; as defined by the UEFI System Table.

-    Close     The stream is marked closed and released for use by a

-              subsequent Open().

-    Delete    Returns RETURN_UNSUPPORTED.  Does Nothing.

-    Read      Blocks reading BufferSize characters using the

-              EFI_SIMPLE_TEXT_INPUT_PROTOCOL::ReadKeyStroke() function.

-    Write     Sends BufferSize characters to the console for display.  The

-              output is examined for new line characters, '\n', which are then

-              translated into a Return + New Line, '\r' '\n', sequence.

-    GetPosition   Returns the number of characters input or output to this

-                  stream.  Return, '\r', characters inserted due to line ending

-                  translation are not counted.

-    SetPosition   Only valid for Stdout or Stderr.  Offset is interpreted as a

-                  CursorXY structure and is used to position the console cursor

-                  using the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL::SetCursorPosition()

-                  call.

-    GetInfo   Populates an EFI_FILE_INFO Buffer with no useful information.

-    SetInfo   Returns RETURN_UNSUPPORTED.  Does Nothing.

-    Flush     Returns RETURN_SUCCESS.  Does Nothing.

-

-**/

-typedef struct {

-  UINT32                      Cookie;

-  UINT32                      ConOutMode;   // Only valid for stdout & stderr

-  UINT64                      NumRead;

-  UINT64                      NumWritten;

-  XYoffset                    MaxConXY;     // Only valid for stdout & stderr

-  EFI_HANDLE                  Dev;          // Could be either Input or Output

-  EFI_FILE_PROTOCOL           Abstraction;

-} ConInstance;

-

-EFI_STATUS

-EFIAPI

-ConOpen(

-  IN  EFI_FILE_PROTOCOL        *This,

-  OUT EFI_FILE_PROTOCOL       **NewHandle,

-  IN  CHAR16                   *FileName,

-  IN  UINT64                    OpenMode,

-  IN  UINT64                    Attributes

-);

-

-#endif  /* _LIBRARY_UEFI_CONSOLE_H */

diff --git a/StdLibPrivateInternalFiles/Include/Efi/SysEfi.h b/StdLibPrivateInternalFiles/Include/Efi/SysEfi.h
new file mode 100644
index 0000000..fa9dc38
--- /dev/null
+++ b/StdLibPrivateInternalFiles/Include/Efi/SysEfi.h
@@ -0,0 +1,37 @@
+/** @file

+  Declarations local to the Uefi SysCalls module of the Standard C Library.

+

+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials are licensed and made available under

+  the terms and conditions of the BSD License that accompanies this distribution.

+  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+#ifndef _SYSEFI_H

+#define _SYSEFI_H

+#include  <Protocol/SimpleFileSystem.h>

+

+#define EFI_FILE_MODE_MASK    ( EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE )

+#define OMODE_MASK            0xFFFF00UL

+#define OMODE_SHIFT           8

+

+#define S_ACC_READ            ( S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH )

+#define S_ACC_WRITE           ( S_IWUSR | S_IWGRP | S_IWOTH )

+#define S_ACC_MASK            ( S_IRWXU | S_IRWXG | S_IRWXO )

+

+UINT64

+Oflags2EFI( int oflags);

+

+UINT64

+Omode2EFI( int mode);

+

+/* Converts the first several EFI status values into the appropriate errno value.

+*/

+int

+EFI2errno( RETURN_STATUS Status);

+

+#endif  /* _SYSEFI_H */

diff --git a/StdLibPrivateInternalFiles/Include/MainData.h b/StdLibPrivateInternalFiles/Include/MainData.h
index 7788cb8..b4b071a 100644
--- a/StdLibPrivateInternalFiles/Include/MainData.h
+++ b/StdLibPrivateInternalFiles/Include/MainData.h
@@ -1,24 +1,28 @@
 /** @file

   Global data for the program environment.

 

-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>

-  This program and the accompanying materials are licensed and made available under

-  the terms and conditions of the BSD License that accompanies this distribution.

-  The full text of the license may be found at

+  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials are licensed and made available

+  under the terms and conditions of the BSD License which accompanies this

+  distribution.  The full text of the license may be found at

   http://opensource.org/licenses/bsd-license.php.

 

   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

 **/

 #include  <Uefi.h>

-#include  <Library/ShellLib.h>

 

+#include  <stdio.h>

+#include  <stdlib.h>

+#include  <sys/types.h>

 #include  <limits.h>

 #include  <signal.h>

-#include  <stdlib.h>

-#include  <stdio.h>

 #include  <time.h>

-#include  "Efi/Console.h"

+

+#include  <kfile.h>

+#include  <Device/Device.h>

+

+#include  "Device/Console.h"

 

 /* ##################  Type Declarations  ################################# */

 

@@ -52,28 +56,25 @@
 ** three explicit spaces, two explicit colons, a newline,

 ** and a trailing ASCII nul).

 */

-#define ASCTIME_BUFLEN  (3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + 3 + 2 + 1 + 1)

+#define ASCTIME_BUFLEN  ((2 * 3) + (5 * INT_STRLEN_MAXIMUM(int)) + 3 + 2 + 1 + 1)

 

-struct  __filedes {

-  EFI_FILE_HANDLE   FileHandle;

-  UINT32            State;        // In use if non-zero

-  int               Oflags;       // From the open call

-  int               Omode;        // From the open call

-  int               RefCount;     // Reference count of opens

-  int               SocProc;      // Placeholder: socket owner process or process group.

-  UINT16            MyFD;         // Which FD this is.

-};

+struct __filedes;   /* Forward Reference */

+struct stat;        /* Forward Reference so I don't have to include <stat.h> */

 

 struct  __MainData {

   // File descriptors

   struct __filedes  fdarray[OPEN_MAX];

   // Low-level File abstractions for the stdin, stdout, stderr streams

-  ConInstance       StdIo[3];

+  ConInstance      *StdIo[3];

 

   // Signal Handlers

   __sighandler_t    *sigarray[SIG_LAST];      // Pointers to signal handlers

 

-  void (*cleanup)(void);   // Cleanup Function Pointer

+  char              *NArgV[ARGC_MAX];         // Narrow character argv array

+  char              *NCmdLine;                // Narrow character version of command line arguments.

+

+  void (*cleanup)(void);        // Stdio Cleanup Function Pointer

+  void (*FinalCleanup)(void);   // Function to free this structure and cleanup before exit.

 

   __xithandler_t   *atexit_handler[ATEXIT_MAX];  // Array of handlers for atexit.

   clock_t           AppStartTime;                // Set in Main.c and used for time.h

@@ -81,6 +82,7 @@
   int               num_atexit;                  ///< Number of registered atexit handlers.

 

   CHAR16            UString[UNICODE_STRING_MAX];

+  CHAR16            UString2[UNICODE_STRING_MAX];

   struct tm         BDTime;                       // Broken-down time structure for localtime.

   EFI_TIME          TimeBuffer;                   // Used by <time.h>mk

   char              ASgetenv[ASCII_STRING_MAX];   // Only modified by getenv

diff --git a/StdLibPrivateInternalFiles/Include/kfile.h b/StdLibPrivateInternalFiles/Include/kfile.h
new file mode 100644
index 0000000..845b7d9
--- /dev/null
+++ b/StdLibPrivateInternalFiles/Include/kfile.h
@@ -0,0 +1,288 @@
+/** @file

+  The EFI kernel's interpretation of a "file".

+

+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials are licensed and made available

+  under the terms and conditions of the BSD License which accompanies this

+  distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+ * Copyright (c) 1982, 1986, 1989, 1993

+ *  The Regents of the University of California.  All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. Neither the name of the University nor the names of its contributors

+ *    may be used to endorse or promote products derived from this software

+ *    without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE

+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ *

+ *  file.h  8.3 (Berkeley) 1/9/95

+    NetBSD: file.h,v 1.56 2006/05/14 21:38:18 elad Exp

+**/

+#ifndef _PIF_KFILE_H_

+#define _PIF_KFILE_H_

+

+#include  <Uefi.h>

+#include  <Protocol/SimpleTextOut.h>

+#include  <Protocol/SimpleFileSystem.h>

+

+#include  <wchar.h>

+#include  <sys/fcntl.h>

+#include  <sys/unistd.h>

+

+struct stat;

+struct fileops;

+struct _Device_Node;

+

+/* The number of "special" character stream devices.

+   These include:

+    stdin, stdout, stderr

+*/

+#define NUM_SPECIAL   3

+

+/* Organization of the f_iflags member of the __filedes structure. */

+#define DTYPE_MASK      0x00000007    ///< Device Type

+#define DTYPE_VNODE             1     /* file */

+#define DTYPE_SOCKET            2     /* communications endpoint */

+#define DTYPE_PIPE              3     /* pipe */

+#define DTYPE_KQUEUE            4     /* event queue */

+#define DTYPE_MISC              5     /* misc file descriptor type */

+#define DTYPE_CRYPTO            6     /* crypto */

+#define DTYPE_NAMES   "0", "file", "socket", "pipe", "kqueue", "misc", "crypto"

+

+#define FIF_WANTCLOSE   0x10000000  /* a close is waiting for usecount */

+#define FIF_DELCLOSE    0x20000000  /* Delete on close. */

+#define FIF_LARVAL      0x80000000  /* not fully constructed; don't use */

+

+/*

+    This structure must be a multiple of 8 bytes in length.

+*/

+struct __filedes {

+  const struct fileops   *f_ops;

+  void                   *devdata;      /* Device-specific data */

+  off_t                   f_offset;     /* current position in file */

+  UINT32                  f_flag;       /* see fcntl.h */

+  UINT32                  f_iflags;     // In use if non-zero

+  int                     Oflags;       // From the open call

+  int                     Omode;        // From the open call

+  int                     RefCount;     // Reference count of opens

+  UINT16                  MyFD;         // Which FD this is.

+  UINT16                  Reserved_1;   // Force this structure to be a multiple of 8-bytes in length

+};

+

+struct fileops {

+  /* These functions must always be implemented. */

+  int     (EFIAPI *fo_close)    (struct __filedes *filp);

+  ssize_t (EFIAPI *fo_read)     (struct __filedes *filp, off_t *Offset, size_t Len, void *Buf);

+  ssize_t (EFIAPI *fo_write)    (struct __filedes *filp, off_t *Offset, size_t Len, const void *Buf);

+

+  /* Call the fnullop_* version of these functions if not implemented by the device. */

+  int     (EFIAPI *fo_fcntl)    (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4);

+  short   (EFIAPI *fo_poll)     (struct __filedes *filp, short Events);

+  int     (EFIAPI *fo_flush)    (struct __filedes *filp);

+

+  /* Call the fbadop_* version of these functions if not implemented by the device. */

+  int     (EFIAPI *fo_stat)     (struct __filedes *filp, struct stat *StatBuf, void *Buf);

+  int     (EFIAPI *fo_ioctl)    (struct __filedes *filp, ULONGN Cmd, void *argp);

+  int     (EFIAPI *fo_delete)   (struct __filedes *filp);

+  int     (EFIAPI *fo_rmdir)    (struct __filedes *filp);

+  int     (EFIAPI *fo_mkdir)    (const char *path, __mode_t perms);

+  int     (EFIAPI *fo_rename)   (const char *from, const char *to);

+

+  /* Use a NULL if this function has not been implemented by the device. */

+  off_t   (EFIAPI *fo_lseek)    (struct __filedes *filp, off_t, int);

+};

+

+/*  A generic instance structure which is valid for

+    for all device instance structures.

+

+    All device instance structures MUST be a multiple of 8-bytes in length.

+*/

+typedef struct {

+  UINT32                      Cookie;       ///< Special value identifying this as a valid Instance

+  UINT32                      InstanceNum;  ///< Which instance is this?  Zero-based.

+  EFI_HANDLE                  Dev;          ///< Pointer to either Input or Output Protocol.

+  struct _Device_Node        *Parent;       ///< Points to the parent Device Node.

+  struct fileops              Abstraction;  ///< Pointers to functions implementing this device's abstraction.

+  UINTN                       Reserved_1;   // Force this to always be a multiple of 8-bytes in length

+} GenericInstance;

+

+/* Type of all Device-specific handler's open routines. */

+typedef

+  int     (EFIAPI *FO_OPEN)    (struct __filedes *FD, void *IP, wchar_t *Path, wchar_t *Flags);

+

+#define FILE_IS_USABLE(fp)  (((fp)->f_iflags &      \

+          (FIF_WANTCLOSE|FIF_LARVAL)) == 0)

+

+#define FILE_SET_MATURE(fp)       \

+do {                              \

+  (fp)->f_iflags &= ~FIF_LARVAL;  \

+} while (/*CONSTCOND*/0)

+

+/*

+ * Flags for fo_read and fo_write.

+ */

+#define FOF_UPDATE_OFFSET 0x01      /* update the file offset */

+

+__BEGIN_DECLS

+

+int   fdcreate    (CHAR16 *, UINT32, UINT32, BOOLEAN, VOID *, const struct fileops *);

+

+/* Commonly used fileops

+      fnullop_*   Does nothing and returns success.

+      fbadop_*    Does nothing and returns EPERM

+*/

+int     fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4);

+short   fnullop_poll  (struct __filedes *filp, short Events);

+int     fnullop_flush (struct __filedes *filp);

+

+int     fbadop_stat   (struct __filedes *filp, struct stat *StatBuf, void *Buf);

+int     fbadop_ioctl  (struct __filedes *filp, ULONGN Cmd, void *argp);

+int     fbadop_delete (struct __filedes *filp);

+int     fbadop_rmdir  (struct __filedes *filp);

+int     fbadop_mkdir  (const char *path, __mode_t perms);

+int     fbadop_rename (const char *from, const char *to);

+

+__END_DECLS

+

+/* From the original file... */

+#if 0

+

+//struct proc;

+//struct lwp;

+//struct uio;

+//struct iovec;

+//struct knote;

+

+//LIST_HEAD(filelist, file);

+//extern struct filelist  filehead;   /* head of list of open files */

+//extern int              maxfiles;   /* kernel limit on # of open files */

+//extern int              nfiles;     /* actual number of open files */

+

+//extern const struct fileops vnops;  /* vnode operations for files */

+

+struct fileops {

+  int (*fo_read)      (struct file *, off_t *, struct uio *, kauth_cred_t, int);

+  int (*fo_write)     (struct file *, off_t *, struct uio *, kauth_cred_t, int);

+  int (*fo_ioctl)     (struct file *, u_long, void *, struct lwp *);

+  int (*fo_fcntl)     (struct file *, u_int, void *, struct lwp *);

+  int (*fo_poll)      (struct file *, int, struct lwp *);

+  int (*fo_stat)      (struct file *, struct stat *, struct lwp *);

+  int (*fo_close)     (struct file *, struct lwp *);

+};

+

+/*

+ * Kernel descriptor table.

+ * One entry for each open kernel vnode and socket.

+ */

+struct file {

+  LIST_ENTRY(file)        f_list;     /* list of active files */

+  void                   *f_data;     /* descriptor data, e.g. vnode/socket */

+  const struct fileops   *f_ops;

+  void                   *f_DevDesc;  /* Device Descriptor pointer */

+  EFI_FILE_HANDLE         FileHandle;

+  EFI_HANDLE              Handle;

+  off_t                   f_offset;   /* current position in file */

+  int                     f_flag;     /* see fcntl.h */

+  UINT32                  f_iflags;   /* internal flags; FIF_* */

+  int                     f_advice;   /* access pattern hint; UVM_ADV_* */

+  int                     f_type;     /* descriptor type */

+  int                     f_usecount; /* number active users */

+  u_int                   f_count;    /* reference count */

+  u_int                   f_msgcount; /* references from message queue */

+//  kauth_cred_t            f_cred;     /* creds associated with descriptor */

+  struct simplelock       f_slock;

+  UINT16                  MyFD;       /* Which FD this is. */

+};

+

+#ifdef DIAGNOSTIC

+#define FILE_USE_CHECK(fp, str)   \

+  do {                              \

+  if ((fp)->f_usecount < 0)       \

+    panic(str);                   \

+} while (/* CONSTCOND */ 0)

+#else

+#define FILE_USE_CHECK(fp, str)   /* nothing */

+#endif

+

+  /*

+   * FILE_USE() must be called with the file lock held.

+   * (Typical usage is: `fp = fd_getfile(..); FILE_USE(fp);'

+   * and fd_getfile() returns the file locked)

+   *

+   * fp is a pointer to a __filedes structure.

+   */

+#define FILE_USE(fp)                                \

+    do {                                                \

+    (fp)->f_usecount++;                               \

+    FILE_USE_CHECK((fp), "f_usecount overflow");      \

+    simple_unlock(&(fp)->f_slock);                    \

+  } while (/* CONSTCOND */ 0)

+

+#define FILE_UNUSE_WLOCK(fp, l, havelock)           \

+      do {                                                \

+      if (!(havelock))                                  \

+        simple_lock(&(fp)->f_slock);                    \

+        if ((fp)->f_iflags & FIF_WANTCLOSE) {             \

+        simple_unlock(&(fp)->f_slock);                  \

+        /* Will drop usecount */                        \

+        (void) closef((fp), (l));                       \

+        break;                                          \

+        } else {                                          \

+        (fp)->f_usecount--;                             \

+        FILE_USE_CHECK((fp), "f_usecount underflow");   \

+      }                                                 \

+      simple_unlock(&(fp)->f_slock);                    \

+    } while (/* CONSTCOND */ 0)

+

+#define FILE_UNUSE(fp, l)           FILE_UNUSE_WLOCK(fp, l, 0)

+#define FILE_UNUSE_HAVELOCK(fp, l)  FILE_UNUSE_WLOCK(fp, l, 1)

+

+__BEGIN_DECLS

+//int   dofileread  (struct lwp *, int, struct file *, void *, size_t, off_t *, int, register_t *);

+//int   dofilewrite (struct lwp *, int, struct file *, const void *, size_t, off_t *, int, register_t *);

+

+//int   dofilereadv (struct lwp *, int, struct file *, const struct iovec *, int, off_t *, int, register_t *);

+//int   dofilewritev(struct lwp *, int, struct file *, const struct iovec *, int, off_t *, int, register_t *);

+

+//int   fsetown     (struct proc *, pid_t *, int, const void *);

+//int   fgetown     (struct proc *, pid_t, int, void *);

+//void  fownsignal  (pid_t, int, int, int, void *);

+

+//int   fdclone     (struct lwp *, struct file *, int, int, const struct fileops *, void *);

+

+/* Commonly used fileops

+      fnullop_*   Does nothing and returns success.

+      fbadop_*    Does nothing and returns EPERM

+*/

+//int   fnullop_fcntl   (struct file *, u_int, void *, struct lwp *);

+//int   fnullop_poll    (struct file *, int, struct lwp *);

+//int   fnullop_kqfilter(struct file *, struct knote *);

+//int   fbadop_stat     (struct file *, struct stat *, struct lwp *);

+//int   fbadop_ioctl    (struct file *, u_long, void *, struct lwp *);

+__END_DECLS

+

+#endif

+

+#endif /* _PIF_KFILE_H_ */