From b00771f50a1f9d72852de544cff5cbfd951e71ac Mon Sep 17 00:00:00 2001 From: darylm503 Date: Tue, 28 Jun 2011 02:27:55 +0000 Subject: [PATCH] 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 --- .../Include/Device/Console.h | 62 ++++ .../Include/Device/Device.h | 197 ++++++++++++ .../Include/Efi/Console.h | 81 ----- .../Include/Efi/SysEfi.h | 37 +++ StdLibPrivateInternalFiles/Include/MainData.h | 42 +-- StdLibPrivateInternalFiles/Include/kfile.h | 288 ++++++++++++++++++ 6 files changed, 606 insertions(+), 101 deletions(-) create mode 100644 StdLibPrivateInternalFiles/Include/Device/Console.h create mode 100644 StdLibPrivateInternalFiles/Include/Device/Device.h delete mode 100644 StdLibPrivateInternalFiles/Include/Efi/Console.h create mode 100644 StdLibPrivateInternalFiles/Include/Efi/SysEfi.h create mode 100644 StdLibPrivateInternalFiles/Include/kfile.h diff --git a/StdLibPrivateInternalFiles/Include/Device/Console.h b/StdLibPrivateInternalFiles/Include/Device/Console.h new file mode 100644 index 0000000000..6f65660485 --- /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.
+ 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 , , , +**/ +#ifndef _DEVICE_UEFI_CONSOLE_H +#define _DEVICE_UEFI_CONSOLE_H + +#include +#include + +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 0000000000..68eade0523 --- /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.
+ 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: +**/ +#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 "//../" 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 867865819b..0000000000 --- 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.
- 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 -#include - -/* 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 0000000000..fa9dc38cdd --- /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.
+ 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 + +#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 7788cb8310..b4b071a080 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.
- 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.
+ 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 -#include +#include +#include +#include #include #include -#include -#include #include -#include "Efi/Console.h" + +#include +#include + +#include "Device/Console.h" /* ################## Type Declarations ################################# */ @@ -52,28 +56,25 @@ typedef void __xithandler_t(void); ** 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 */ 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 @@ struct __MainData { 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 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 0000000000..845b7d908e --- /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.
+ 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 +#include +#include + +#include +#include +#include + +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_ */