udk2010.up2.shell initial release.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10874 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jcarsey
2010-09-14 05:18:09 +00:00
parent 52fb4d3d13
commit a405b86d27
102 changed files with 30419 additions and 1040 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,341 @@
/** @file
Provides interface to shell console logger.
Copyright (c) 2009 - 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
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.
**/
#ifndef _CONSOLE_LOGGER_HEADER_
#define _CONSOLE_LOGGER_HEADER_
#include <Uefi.h>
#include <Protocol/SimpleTextOut.h>
#include <Protocol/EfiShell.h>
#include <Protocol/EfiShellParameters.h>
#include <Library/Debuglib.h>
#include <Library/Baselib.h>
#include <Library/BaseMemorylib.h>
#include <Library/MemoryAllocationlib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/HiiLib.h>
#include <Library/ShellLib.h>
#define CONSOLE_LOGGER_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('c', 'o', 'P', 'D')
typedef struct _CONSOLE_LOGGER_PRIVATE_DATA{
UINTN Signature;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL OurConOut; ///< the protocol we installed onto the system table
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OldConOut; ///< old protocol to reinstall upon exiting
EFI_HANDLE OldConHandle; ///< old protocol handle
UINTN ScreenCount; ///< How many screens worth of data to save
CHAR16 *Buffer; ///< Buffer to save data
UINTN BufferSize; ///< size of buffer in bytes
// start row is the top of the screen
UINTN OriginalStartRow; ///< What the originally visible start row was
UINTN CurrentStartRow; ///< what the currently visible start row is
UINTN RowsPerScreen; ///< how many rows the screen can display
UINTN ColsPerScreen; ///< how many columns the screen can display
INT32 *Attributes; ///< Buffer for Attribute to be saved for each character
UINTN AttribSize; ///< Size of Attributes in bytes
EFI_SIMPLE_TEXT_OUTPUT_MODE HistoryMode; ///< mode of the history log
BOOLEAN Enabled; ///< Set to FALSE when a break is requested.
UINTN RowCounter; ///< Initial row of each print job.
} CONSOLE_LOGGER_PRIVATE_DATA;
#define CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(a) CR (a, CONSOLE_LOGGER_PRIVATE_DATA, OurConOut, CONSOLE_LOGGER_PRIVATE_DATA_SIGNATURE)
/**
Install our intermediate ConOut into the system table to
keep a log of all the info that is displayed to the user.
@param[in] ScreensToSave Sets how many screen-worths of data to save.
@param[out] ConsoleInfo The object to pass into later functions.
@retval EFI_SUCCESS The operation was successful.
@return other The operation failed.
@sa ConsoleLoggerResetBuffers
@sa InstallProtocolInterface
**/
EFI_STATUS
EFIAPI
ConsoleLoggerInstall(
IN CONST UINTN ScreensToSave,
OUT CONSOLE_LOGGER_PRIVATE_DATA **ConsoleInfo
);
/**
Return the system to the state it was before InstallConsoleLogger
was installed.
@param[in,out] ConsoleInfo The object from the install function.
@retval EFI_SUCCESS The operation was successful
@return other The operation failed. This was from UninstallProtocolInterface.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerUninstall(
IN OUT CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
);
/**
Displays previously logged output back to the screen.
This will scroll the screen forwards and backwards through the log of previous
output. If Rows is 0 then the size of 1/2 the screen will be scrolled. If Rows
is (UINTN)(-1) then the size of the screen will be scrolled.
@param[in] Forward If TRUE then the log will be displayed forwards (scroll to newer).
If FALSE then the log will be displayed backwards (scroll to older).
@param[in] Rows Determines how many rows the log should scroll.
@param[in] ConsoleInfo The pointer to the instance of the console logger information.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerDisplayHistory(
IN CONST BOOLEAN Forward,
IN CONST UINTN Rows,
IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
);
/**
Function to return to normal output whent he scrolling is complete.
@param[in] ConsoleInfo The pointer to the instance of the console logger information.
@retval EFI_SUCCESS The operation was successful.
@return other The operation failed. See UpdateDisplayFromHistory.
@sa UpdateDisplayFromHistory
**/
EFI_STATUS
EFIAPI
ConsoleLoggerStopHistory(
IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
);
/**
Updates the hidden ConOut to be displaying the correct stuff.
@param[in] ConsoleInfo The pointer to the instance of the console logger information.
@retval EFI_SUCCESS The operation was successful.
@return other The operation failed.
**/
EFI_STATUS
EFIAPI
UpdateDisplayFromHistory(
IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
);
/**
Reset the text output device hardware and optionaly run diagnostics
@param This Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
@param ExtendedVerification Indicates that a more extensive test may be performed
@retval EFI_SUCCESS The text output device was reset.
@retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
could not be reset.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerReset (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
/**
Write a Unicode string to the output device.
@param[in] This Protocol instance pointer.
@param[in] WString The NULL-terminated Unicode string to be displayed on the output
device(s). All output devices must also support the Unicode
drawing defined in this file.
@retval EFI_SUCCESS The string was output to the device.
@retval EFI_DEVICE_ERROR The device reported an error while attempting to output
the text.
@retval EFI_UNSUPPORTED The output device's mode is not currently in a
defined text mode.
@retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
characters in the Unicode string could not be
rendered and were skipped.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerOutputString(
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN CHAR16 *WString
);
/**
Verifies that all characters in a Unicode string can be output to the
target device.
@param[in] This Protocol instance pointer.
@param[in] WString The NULL-terminated Unicode string to be examined for the output
device(s).
@retval EFI_SUCCESS The device(s) are capable of rendering the output string.
@retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
rendered by one or more of the output devices mapped
by the EFI handle.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerTestString (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN CHAR16 *WString
);
/**
Returns information for an available text mode that the output device(s)
supports.
@param[in] This Protocol instance pointer.
@param[in] ModeNumber The mode number to return information on.
@param[out] Columns Upon return, the number of columns in the selected geometry
@param[out] Rows Upon return, the number of rows in the selected geometry
@retval EFI_SUCCESS The requested mode information was returned.
@retval EFI_DEVICE_ERROR The device had an error and could not
complete the request.
@retval EFI_UNSUPPORTED The mode number was not valid.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerQueryMode (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN ModeNumber,
OUT UINTN *Columns,
OUT UINTN *Rows
);
/**
Sets the output device(s) to a specified mode.
@param[in] This Protocol instance pointer.
@param[in] ModeNumber The mode number to set.
@retval EFI_SUCCESS The requested text mode was set.
@retval EFI_DEVICE_ERROR The device had an error and
could not complete the request.
@retval EFI_UNSUPPORTED The mode number was not valid.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerSetMode (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN ModeNumber
);
/**
Sets the background and foreground colors for the OutputString () and
ClearScreen () functions.
@param[in] This Protocol instance pointer.
@param[in] Attribute The attribute to set. Bits 0..3 are the foreground color, and
bits 4..6 are the background color. All other bits are undefined
and must be zero. The valid Attributes are defined in this file.
@retval EFI_SUCCESS The attribute was set.
@retval EFI_DEVICE_ERROR The device had an error and
could not complete the request.
@retval EFI_UNSUPPORTED The attribute requested is not defined.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerSetAttribute (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN Attribute
);
/**
Clears the output device(s) display to the currently selected background
color.
@param[in] This Protocol instance pointer.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_DEVICE_ERROR The device had an error and
could not complete the request.
@retval EFI_UNSUPPORTED The output device is not in a valid text mode.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerClearScreen (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
);
/**
Sets the current coordinates of the cursor position.
@param[in] This Protocol instance pointer.
@param[in] Column Column to put the cursor in. Must be between zero and Column returned from QueryMode
@param[in] Row Row to put the cursor in. Must be between zero and Row returned from QueryMode
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_DEVICE_ERROR The device had an error and
could not complete the request.
@retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
cursor position is invalid for the current mode.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerSetCursorPosition (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN Column,
IN UINTN Row
);
/**
Makes the cursor visible or invisible
@param[in] This Protocol instance pointer.
@param[in] Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is
set to be invisible.
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_DEVICE_ERROR The device had an error and could not complete the
request, or the device does not support changing
the cursor mode.
@retval EFI_UNSUPPORTED The output device is not in a valid text mode.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerEnableCursor (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN BOOLEAN Visible
);
/**
Function to update and verify that the current buffers are correct.
@param[in] ConsoleInfo The pointer to the instance of the console logger information.
This will be used when a mode has changed or a reset ocurred to verify all
history buffers.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerResetBuffers(
IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
);
#endif //_CONSOLE_LOGGER_HEADER_

View File

@@ -0,0 +1,68 @@
/** @file
internal worker functions for FileHandleWrappers to use
Copyright (c) 2009 - 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
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.
**/
#ifndef _FILE_HANDLE_INTERNAL_HEADER_
#define _FILE_HANDLE_INTERNAL_HEADER_
/**
Move the cursor position one character backward.
@param[in] LineLength Length of a line. Get it by calling QueryMode
@param[in,out] Column Current column of the cursor position
@param[in,out] Row Current row of the cursor position
**/
VOID
EFIAPI
MoveCursorBackward (
IN UINTN LineLength,
IN OUT UINTN *Column,
IN OUT UINTN *Row
);
/**
Move the cursor position one character forward.
@param[in] LineLength Length of a line.
@param[in] TotalRow Total row of a screen
@param[in,out] Column Current column of the cursor position
@param[in,out] Row Current row of the cursor position
**/
VOID
EFIAPI
MoveCursorForward (
IN UINTN LineLength,
IN UINTN TotalRow,
IN OUT UINTN *Column,
IN OUT UINTN *Row
);
/**
Prints out each previously typed command in the command list history log.
When each screen is full it will pause for a key before continuing.
@param[in] TotalCols How many columns are on the screen
@param[in] TotalRows How many rows are on the screen
@param[in] StartColumn which column to start at
**/
VOID
EFIAPI
PrintCommandHistory (
IN CONST UINTN TotalCols,
IN CONST UINTN TotalRows,
IN CONST UINTN StartColumn
);
#endif //_FILE_HANDLE_INTERNAL_HEADER_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
/** @file
EFI_FILE_PROTOCOL wrappers for other items (Like Environment Variables, StdIn, StdOut, StdErr, etc...)
Copyright (c) 2009 - 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
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.
**/
#ifndef _SHELL_FILE_HANDLE_WRAPPERS_HEADER_
#define _SHELL_FILE_HANDLE_WRAPPERS_HEADER_
typedef struct {
LIST_ENTRY Link;
CHAR16* Buffer;
} SHELL_LINE_LIST;
typedef struct {
UINTN LogCount;
SHELL_LINE_LIST *Log;
} SHELL_LINE_LOG;
///
/// FILE sytle interfaces for StdIn.
///
extern EFI_FILE_PROTOCOL FileInterfaceStdIn;
///
/// FILE sytle interfaces for StdOut.
///
extern EFI_FILE_PROTOCOL FileInterfaceStdOut;
///
/// FILE sytle interfaces for StdErr.
///
extern EFI_FILE_PROTOCOL FileInterfaceStdErr;
///
/// FILE style interface for NUL file.
///
extern EFI_FILE_PROTOCOL FileInterfaceNulFile;
/**
Creates a EFI_FILE_PROTOCOL (almost) object for using to access
environment variables through file operations.
@param EnvName The name of the Environment Variable to be operated on.
@retval NULL Memory could not be allocated.
@return other a pointer to an EFI_FILE_PROTOCOL structure
**/
EFI_FILE_PROTOCOL*
EFIAPI
CreateFileInterfaceEnv(
CONST CHAR16 *EnvName
);
/**
Creates a EFI_FILE_PROTOCOL (almost) object for using to access
a file entirely in memory through file operations.
@param[in] Unicode TRUE if the data is UNICODE, FALSE otherwise.
@retval NULL Memory could not be allocated.
@return other a pointer to an EFI_FILE_PROTOCOL structure
**/
EFI_FILE_PROTOCOL*
EFIAPI
CreateFileInterfaceMem(
IN CONST BOOLEAN Unicode
);
/**
Creates a EFI_FILE_PROTOCOL (almost) object for using to access
a file entirely with unicode awareness through file operations.
@param[in] Template The pointer to the handle to start with.
@param[in] Unicode TRUE if the data is UNICODE, FALSE otherwise.
@retval NULL Memory could not be allocated.
@return other a pointer to an EFI_FILE_PROTOCOL structure
**/
EFI_FILE_PROTOCOL*
CreateFileInterfaceFile(
IN CONST EFI_FILE_PROTOCOL *Template,
IN CONST BOOLEAN Unicode
);
#endif //_SHELL_FILE_HANDLE_WRAPPERS_HEADER_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,292 @@
/** @file
function definitions for internal to shell functions.
Copyright (c) 2009 - 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
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.
**/
#ifndef _SHELL_INTERNAL_HEADER_
#define _SHELL_INTERNAL_HEADER_
#include <Uefi.h>
#include <ShellBase.h>
#include <Guid/ShellVariableGuid.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/SimpleTextOut.h>
#include <Protocol/EfiShell.h>
#include <Protocol/EfiShellInterface.h>
#include <Protocol/EfiShellEnvironment2.h>
#include <Protocol/EfiShellParameters.h>
#include <Protocol/BlockIo.h>
#include <Library/BaseLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/ShellCommandLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DevicePathLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PcdLib.h>
#include <Library/ShellLib.h>
#include <Library/SortLib.h>
#include <Library/HiiLib.h>
#include <Library/PrintLib.h>
#include <Library/HandleParsingLib.h>
#include "ShellParametersProtocol.h"
#include "ShellProtocol.h"
#include "ShellEnvVar.h"
#include "ConsoleLogger.h"
#include "ShellManParser.h"
typedef struct {
LIST_ENTRY Link; ///< Standard linked list handler.
SHELL_FILE_HANDLE *SplitStdOut; ///< ConsoleOut for use in the split.
SHELL_FILE_HANDLE *SplitStdIn; ///< ConsoleIn for use in the split.
} SPLIT_LIST;
typedef struct {
UINT32 Startup:1; ///< Was "-startup" found on command line.
UINT32 NoStartup:1; ///< Was "-nostartup" found on command line.
UINT32 NoConsoleOut:1; ///< Was "-noconsoleout" found on command line.
UINT32 NoConsoleIn:1; ///< Was "-noconsolein" found on command line.
UINT32 NoInterrupt:1; ///< Was "-nointerrupt" found on command line.
UINT32 NoMap:1; ///< Was "-nomap" found on command line.
UINT32 NoVersion:1; ///< Was "-noversion" found on command line.
UINT32 Delay:1; ///< Was "-delay[:n] found on command line
UINT32 Reserved:8; ///< Extra bits
} SHELL_BITS;
typedef union {
SHELL_BITS Bits;
UINT16 AllBits;
} SHELL_BIT_UNION;
typedef struct {
SHELL_BIT_UNION BitUnion;
UINTN Delay; ///< Seconds of delay default:5.
CHAR16 *FileName; ///< Filename to run upon successful initialization.
CHAR16 *FileOptions; ///< Options to pass to FileName.
} SHELL_INIT_SETTINGS;
typedef struct {
BUFFER_LIST CommandHistory;
UINTN VisibleRowNumber;
UINTN OriginalVisibleRowNumber;
BOOLEAN InsertMode; ///< Is the current typing mode insert (FALSE = overwrite).
} SHELL_VIEWING_SETTINGS;
typedef struct {
EFI_SHELL_PARAMETERS_PROTOCOL *NewShellParametersProtocol;
EFI_SHELL_PROTOCOL *NewEfiShellProtocol;
BOOLEAN PageBreakEnabled;
BOOLEAN RootShellInstance;
SHELL_INIT_SETTINGS ShellInitSettings;
BUFFER_LIST BufferToFreeList; ///< List of buffers that were returned to the user to free.
SHELL_VIEWING_SETTINGS ViewingSettings;
EFI_HII_HANDLE HiiHandle; ///< Handle from HiiLib.
UINTN LogScreenCount; ///< How many screens of log information to save.
EFI_EVENT UserBreakTimer; ///< Timer event for polling for CTRL-C.
EFI_DEVICE_PATH_PROTOCOL *ImageDevPath; ///< DevicePath for ourselves.
EFI_DEVICE_PATH_PROTOCOL *FileDevPath; ///< DevicePath for ourselves.
CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo; ///< Pointer for ConsoleInformation.
EFI_SHELL_PARAMETERS_PROTOCOL *OldShellParameters; ///< old shell parameters to reinstall upon exiting.
SHELL_PROTOCOL_HANDLE_LIST OldShellList; ///< List of other instances to reinstall when closing.
SPLIT_LIST SplitList; ///< List of Splits in FILO stack.
} SHELL_INFO;
extern SHELL_INFO ShellInfoObject;
/**
Sets all the alias' that were registered with the ShellCommandLib library.
@retval EFI_SUCCESS all init commands were run sucessfully.
**/
EFI_STATUS
EFIAPI
SetBuiltInAlias(
VOID
);
/**
This function will populate the 2 device path protocol parameters based on the
global gImageHandle. the DevPath will point to the device path for the handle that has
loaded image protocol installed on it. the FilePath will point to the device path
for the file that was loaded.
@param[in,out] DevPath on a sucessful return the device path to the loaded image
@param[in,out] FilePath on a sucessful return the device path to the file
@retval EFI_SUCCESS the 2 device paths were sucessfully returned.
@return other a error from gBS->HandleProtocol
@sa HandleProtocol
**/
EFI_STATUS
EFIAPI
GetDevicePathsForImageAndFile (
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevPath,
IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
);
/**
Process all Uefi Shell 2.0 command line options.
see Uefi Shell 2.0 section 3.2 for full details.
the command line should resemble the following:
shell.efi [ShellOpt-options] [options] [file-name [file-name-options]]
ShellOpt options Options which control the initialization behavior of the shell.
These options are read from the EFI global variable "ShellOpt"
and are processed before options or file-name.
options Options which control the initialization behavior of the shell.
file-name The name of a UEFI shell application or script to be executed
after initialization is complete. By default, if file-name is
specified, then -nostartup is implied. Scripts are not supported
by level 0.
file-nameoptions The command-line options that are passed to file-name when it
is invoked.
This will initialize the ShellInitSettings global variable.
@retval EFI_SUCCESS the variable is initialized.
**/
EFI_STATUS
EFIAPI
ProcessCommandLine(
VOID
);
/**
Handles all interaction with the default startup script.
this will check that the correct command line parameters were passed, handle the delay, and then start running the script.
@param[in] ImagePath The path to the image for shell. The first place to look for the startup script.
@param[in] FilePath The path to the file for shell. The second place to look for the startup script.
@retval EFI_SUCCESS The variable is initialized.
**/
EFI_STATUS
EFIAPI
DoStartupScript(
IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath
);
/**
Function to perform the shell prompt looping. It will do a single prompt,
dispatch the result, and then return. It is expected that the caller will
call this function in a loop many times.
@retval EFI_SUCCESS
@retval RETURN_ABORTED
**/
EFI_STATUS
EFIAPI
DoShellPrompt (
VOID
);
/**
Add a buffer to the Buffer To Free List for safely returning buffers to other
places without risking letting them modify internal shell information.
@param Buffer Something to pass to FreePool when the shell is exiting.
**/
VOID*
EFIAPI
AddBufferToFreeList(
VOID *Buffer
);
/**
Add a buffer to the Command History List.
@param Buffer[in] The line buffer to add.
**/
VOID
EFIAPI
AddLineToCommandHistory(
IN CONST CHAR16 *Buffer
);
/**
Function will process and run a command line.
This will determine if the command line represents an internal shell command or dispatch an external application.
@param[in] CmdLine the command line to parse
@retval EFI_SUCCESS the command was completed
@retval EFI_ABORTED the command's operation was aborted
**/
EFI_STATUS
EFIAPI
RunCommand(
IN CONST CHAR16 *CmdLine
);
/**
Function determins if the CommandName COULD be a valid command. It does not determine whether
this is a valid command. It only checks for invalid characters.
@param[in] CommandName The name to check
@retval TRUE CommandName could be a command name
@retval FALSE CommandName could not be a valid command name
**/
BOOLEAN
EFIAPI
IsValidCommandName(
IN CONST CHAR16 *CommandName
);
/**
Function to process a NSH script file via SHELL_FILE_HANDLE.
@param[in] Handle The handle to the already opened file.
@param[in] Name The name of the script file.
@retval EFI_SUCCESS the script completed sucessfully
**/
EFI_STATUS
EFIAPI
RunScriptFileHandle (
IN SHELL_FILE_HANDLE Handle,
IN CONST CHAR16 *Name
);
/**
Function to process a NSH script file.
@param[in] ScriptPath Pointer to the script file name (including file system path).
@retval EFI_SUCCESS the script completed sucessfully
**/
EFI_STATUS
EFIAPI
RunScriptFile (
IN CONST CHAR16 *ScriptPath
);
#endif //_SHELL_INTERNAL_HEADER_

View File

@@ -0,0 +1,105 @@
## @file
# This is the shell application
#
# Copyright (c) 2009-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
# 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.
#
#
##
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = Shell
FILE_GUID = 7C04A583-9E3E-4f1c-AD65-E05268D0B4D1
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
Shell.c
Shell.h
ShellParametersProtocol.c
ShellParametersProtocol.h
ShellProtocol.c
ShellProtocol.h
FileHandleWrappers.c
FileHandleWrappers.h
FileHandleInternal.h
ShellEnvVar.c
ShellEnvVar.h
ShellManParser.c
ShellManParser.h
Shell.uni
ConsoleLogger.c
ConsoleLogger.h
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
MdeModulePkg/MdeModulePkg.dec
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
BaseLib
UefiApplicationEntryPoint
UefiLib
DebugLib
MemoryAllocationLib
ShellCommandLib
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
DevicePathLib
BaseMemoryLib
PcdLib
FileHandleLib
PrintLib
HiiLib
SortLib
HandleParsingLib
[Guids]
gShellVariableGuid # ALWAYS_CONSUMED
gShellMapGuid # ALWAYS_CONSUMED
gShellAliasGuid # ALWAYS_CONSUMED
[Protocols]
gEfiShellProtocolGuid # ALWAYS_PRODUCED
gEfiShellParametersProtocolGuid # ALWAYS_PRODUCED
gEfiShellEnvironment2Guid # SOMETIMES_PRODUCED
gEfiShellInterfaceGuid # SOMETIMES_PRODUCED
gEfiLoadedImageProtocolGuid # ALWAYS_CONSUMED
gEfiSimpleTextInputExProtocolGuid # ALWAYS_CONSUMED
gEfiSimpleTextOutProtocolGuid # ALWAYS_CONSUMED
gEfiSimpleFileSystemProtocolGuid # ALWAYS_CONSUMED
gEfiLoadedImageProtocolGuid # ALWAYS_CONSUMED
gEfiComponentName2ProtocolGuid # ALWAYS_CONSUMED
gEfiUnicodeCollation2ProtocolGuid # ALWAYS_CONSUMED
gEfiDevicePathProtocolGuid # ALWAYS_CONSUMED
gEfiDevicePathToTextProtocolGuid # ALWAYS_CONSUMED
[Pcd]
gEfiShellPkgTokenSpaceGuid.PcdShellSupportLevel # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellSupportOldProtocols # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellRequireHiiPlatform # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellSupportFrameworkHii # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellPageBreakDefault # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellInsertModeDefault # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellScreenLogCount # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellMapNameLength # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellPrintBufferSize # ALWAYS_CONSUMED
gEfiShellPkgTokenSpaceGuid.PcdShellForceConsole # ALWAYS_CONSUMED

Binary file not shown.

View File

@@ -0,0 +1,326 @@
/** @file
function declarations for shell environment functions.
Copyright (c) 2009 - 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
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 <Guid/ShellVariableGuid.h>
#include <Library/BaseLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include "ShellEnvVar.h"
/**
Reports whether an environment variable is Volatile or Non-Volatile.
@param EnvVarName The name of the environment variable in question
@retval TRUE This environment variable is Volatile
@retval FALSE This environment variable is NON-Volatile
**/
BOOLEAN
EFIAPI
IsVolatileEnv (
IN CONST CHAR16 *EnvVarName
)
{
EFI_STATUS Status;
UINTN Size;
VOID *Buffer;
UINT32 Attribs;
Size = 0;
Buffer = NULL;
//
// get the variable
//
Status = gRT->GetVariable((CHAR16*)EnvVarName,
&gShellVariableGuid,
&Attribs,
&Size,
Buffer);
if (Status == EFI_BUFFER_TOO_SMALL) {
Buffer = AllocatePool(Size);
ASSERT(Buffer != NULL);
Status = gRT->GetVariable((CHAR16*)EnvVarName,
&gShellVariableGuid,
&Attribs,
&Size,
Buffer);
FreePool(Buffer);
}
//
// not found means volatile
//
if (Status == EFI_NOT_FOUND) {
return (TRUE);
}
ASSERT_EFI_ERROR(Status);
//
// check for the Non Volatile bit
//
if ((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE) {
return (FALSE);
}
//
// everything else is volatile
//
return (TRUE);
}
/**
free function for ENV_VAR_LIST objects.
@param[in] List The pointer to pointer to list.
**/
VOID
EFIAPI
FreeEnvironmentVariableList(
IN LIST_ENTRY *List
)
{
ENV_VAR_LIST *Node;
ASSERT (List != NULL);
if (List == NULL) {
return;
}
for ( Node = (ENV_VAR_LIST*)GetFirstNode(List)
; IsListEmpty(List)
; Node = (ENV_VAR_LIST*)GetFirstNode(List)
){
ASSERT(Node != NULL);
RemoveEntryList(&Node->Link);
if (Node->Key != NULL) {
FreePool(Node->Key);
}
if (Node->Val != NULL) {
FreePool(Node->Val);
}
FreePool(Node);
}
}
/**
Creates a list of all Shell-Guid-based environment variables.
@param[in,out] ListHead The pointer to pointer to LIST ENTRY object for
storing this list.
@retval EFI_SUCCESS the list was created sucessfully.
**/
EFI_STATUS
EFIAPI
GetEnvironmentVariableList(
IN OUT LIST_ENTRY *ListHead
)
{
CHAR16 *VariableName;
UINTN NameSize;
UINT64 MaxStorSize;
UINT64 RemStorSize;
UINT64 MaxVarSize;
EFI_STATUS Status;
EFI_GUID Guid;
UINTN ValSize;
ENV_VAR_LIST *VarList;
ASSERT(ListHead != NULL);
Status = gRT->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS, &MaxStorSize, &RemStorSize, &MaxVarSize);
ASSERT_EFI_ERROR(Status);
NameSize = (UINTN)MaxVarSize;
VariableName = AllocatePool(NameSize);
StrCpy(VariableName, L"");
while (TRUE) {
NameSize = (UINTN)MaxVarSize;
Status = gRT->GetNextVariableName(&NameSize, VariableName, &Guid);
if (Status == EFI_NOT_FOUND){
Status = EFI_SUCCESS;
break;
}
ASSERT_EFI_ERROR(Status);
if (EFI_ERROR(Status)) {
break;
}
if (CompareGuid(&Guid, &gShellVariableGuid)){
VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));
ValSize = 0;
Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
if (Status == EFI_BUFFER_TOO_SMALL){
VarList->Val = AllocatePool(ValSize);
ASSERT(VarList->Val != NULL);
Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);
}
ASSERT_EFI_ERROR(Status);
VarList->Key = AllocatePool(StrSize(VariableName));
ASSERT(VarList->Key != NULL);
StrCpy(VarList->Key, VariableName);
InsertTailList(ListHead, &VarList->Link);
} // compare guid
} // while
FreePool(VariableName);
if (EFI_ERROR(Status)) {
FreeEnvironmentVariableList(ListHead);
}
return (Status);
}
/**
Sets a list of all Shell-Guid-based environment variables. this will
also eliminate all existing shell environment variables (even if they
are not on the list).
This function will also deallocate the memory from List.
@param[in] ListHead The pointer to LIST_ENTRY from
GetShellEnvVarList().
@retval EFI_SUCCESS the list was Set sucessfully.
**/
EFI_STATUS
EFIAPI
SetEnvironmentVariableList(
IN LIST_ENTRY *ListHead
)
{
ENV_VAR_LIST VarList;
ENV_VAR_LIST *Node;
EFI_STATUS Status;
UINTN Size;
InitializeListHead(&VarList.Link);
//
// Delete all the current environment variables
//
Status = GetEnvironmentVariableList(&VarList.Link);
ASSERT_EFI_ERROR(Status);
for ( Node = (ENV_VAR_LIST*)GetFirstNode(&VarList.Link)
; !IsNull(&VarList.Link, &Node->Link)
; Node = (ENV_VAR_LIST*)GetNextNode(&VarList.Link, &Node->Link)
){
if (Node->Key != NULL) {
Status = SHELL_DELETE_ENVIRONMENT_VARIABLE(Node->Key);
}
ASSERT_EFI_ERROR(Status);
}
FreeEnvironmentVariableList(&VarList.Link);
//
// set all the variables fron the list
//
for ( Node = (ENV_VAR_LIST*)GetFirstNode(ListHead)
; !IsNull(ListHead, &Node->Link)
; Node = (ENV_VAR_LIST*)GetNextNode(ListHead, &Node->Link)
){
Size = StrSize(Node->Val);
if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) {
Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(Node->Key, Size, Node->Val);
} else {
Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (Node->Key, Size, Node->Val);
}
ASSERT_EFI_ERROR(Status);
}
FreeEnvironmentVariableList(ListHead);
return (Status);
}
/**
sets a list of all Shell-Guid-based environment variables.
@param Environment Points to a NULL-terminated array of environment
variables with the format 'x=y', where x is the
environment variable name and y is the value.
@retval EFI_SUCCESS The command executed successfully.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval EFI_OUT_OF_RESOURCES Out of resources.
@sa SetEnvironmentVariableList
**/
EFI_STATUS
EFIAPI
SetEnvironmentVariables(
IN CONST CHAR16 **Environment
)
{
CONST CHAR16 *CurrentString;
UINTN CurrentCount;
ENV_VAR_LIST *VarList;
ENV_VAR_LIST *Node;
UINTN NewSize;
VarList = NULL;
if (Environment == NULL) {
return (EFI_INVALID_PARAMETER);
}
//
// Build a list identical to the ones used for get/set list functions above
//
for ( CurrentCount = 0
;
; CurrentCount++
){
CurrentString = Environment[CurrentCount];
if (CurrentString == NULL) {
break;
}
ASSERT(StrStr(CurrentString, L"=") != NULL);
Node = AllocatePool(sizeof(ENV_VAR_LIST));
ASSERT(Node != NULL);
Node->Key = AllocateZeroPool((StrStr(CurrentString, L"=") - CurrentString + 1) * sizeof(CHAR16));
ASSERT(Node->Key != NULL);
StrnCpy(Node->Key, CurrentString, StrStr(CurrentString, L"=") - CurrentString);
NewSize = StrSize(CurrentString);
NewSize -= StrLen(Node->Key) - 1;
Node->Val = AllocateZeroPool(NewSize);
ASSERT(Node->Val != NULL);
StrCpy(Node->Val, CurrentString + StrLen(Node->Key) + 1);
Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS;
if (VarList == NULL) {
VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));
ASSERT(VarList != NULL);
InitializeListHead(&VarList->Link);
}
InsertTailList(&VarList->Link, &Node->Link);
} // for loop
//
// set this new list as the set of all environment variables.
// this function also frees the memory and deletes all pre-existing
// shell-guid based environment variables.
//
return (SetEnvironmentVariableList(&VarList->Link));
}

View File

@@ -0,0 +1,210 @@
/** @file
function definitions for shell environment functions.
the following includes are required:
//#include <Guid/ShellVariableGuid.h>
//#include <Library/UefiRuntimeServicesTableLib.h>
Copyright (c) 2009 - 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
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.
**/
#ifndef _SHELL_ENVIRONMENT_VARIABLE_HEADER_
#define _SHELL_ENVIRONMENT_VARIABLE_HEADER_
typedef struct {
LIST_ENTRY Link;
CHAR16 *Key;
CHAR16 *Val;
UINT32 Atts;
} ENV_VAR_LIST;
/**
Reports whether an environment variable is Volatile or Non-Volatile
This will use the Runtime Services call GetVariable to to search for the variable.
@param EnvVarName The name of the environment variable in question
@retval TRUE This environment variable is Volatile
@retval FALSE This environment variable is NON-Volatile
**/
BOOLEAN
EFIAPI
IsVolatileEnv (
IN CONST CHAR16 *EnvVarName
);
/**
Delete a Non-Violatile environment variable.
This will use the Runtime Services call SetVariable to remove a non-violatile variable.
@param EnvVarName The name of the environment variable in question
@retval EFI_SUCCESS The variable was deleted sucessfully
@retval other An error ocurred
@sa SetVariable
**/
#define SHELL_DELETE_ENVIRONMENT_VARIABLE(EnvVarName) \
(gRT->SetVariable((CHAR16*)EnvVarName, \
&gShellVariableGuid, \
0, \
0, \
NULL))
/**
Set a Non-Violatile environment variable.
This will use the Runtime Services call SetVariable to set a non-violatile variable.
@param EnvVarName The name of the environment variable in question
@param BufferSize UINTN size of Buffer
@param Buffer Pointer to value to set variable to
@retval EFI_SUCCESS The variable was changed sucessfully
@retval other An error ocurred
@sa SetVariable
**/
#define SHELL_SET_ENVIRONMENT_VARIABLE_NV(EnvVarName,BufferSize,Buffer) \
(gRT->SetVariable((CHAR16*)EnvVarName, \
&gShellVariableGuid, \
EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS, \
BufferSize, \
(VOID*)Buffer))
/**
Get an environment variable.
This will use the Runtime Services call GetVariable to get a variable.
@param EnvVarName The name of the environment variable in question
@param BufferSize Pointer to the UINTN size of Buffer
@param Buffer Pointer buffer to get variable value into
@retval EFI_SUCCESS The variable's value was retrieved sucessfully
@retval other An error ocurred
@sa SetVariable
**/
#define SHELL_GET_ENVIRONMENT_VARIABLE(EnvVarName,BufferSize,Buffer) \
(gRT->GetVariable((CHAR16*)EnvVarName, \
&gShellVariableGuid, \
0, \
BufferSize, \
Buffer))
/**
Get an environment variable.
This will use the Runtime Services call GetVariable to get a variable.
@param EnvVarName The name of the environment variable in question
@param Atts Pointer to the UINT32 for attributes (or NULL)
@param BufferSize Pointer to the UINTN size of Buffer
@param Buffer Pointer buffer to get variable value into
@retval EFI_SUCCESS The variable's value was retrieved sucessfully
@retval other An error ocurred
@sa SetVariable
**/
#define SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(EnvVarName,Atts,BufferSize,Buffer) \
(gRT->GetVariable((CHAR16*)EnvVarName, \
&gShellVariableGuid, \
Atts, \
BufferSize, \
Buffer))
/**
Set a Violatile environment variable.
This will use the Runtime Services call SetVariable to set a violatile variable.
@param EnvVarName The name of the environment variable in question
@param BufferSize UINTN size of Buffer
@param Buffer Pointer to value to set variable to
@retval EFI_SUCCESS The variable was changed sucessfully
@retval other An error ocurred
@sa SetVariable
**/
#define SHELL_SET_ENVIRONMENT_VARIABLE_V(EnvVarName,BufferSize,Buffer) \
(gRT->SetVariable((CHAR16*)EnvVarName, \
&gShellVariableGuid, \
EFI_VARIABLE_BOOTSERVICE_ACCESS, \
BufferSize, \
(VOID*)Buffer))
/**
Creates a list of all Shell-Guid-based environment variables.
@param[in,out] List The pointer to pointer to LIST_ENTRY object for
storing this list.
@retval EFI_SUCCESS the list was created sucessfully.
**/
EFI_STATUS
EFIAPI
GetEnvironmentVariableList(
IN OUT LIST_ENTRY *List
);
/**
Sets a list of all Shell-Guid-based environment variables. this will
also eliminate all pre-existing shell environment variables (even if they
are not on the list).
This function will also deallocate the memory from List.
@param[in] List The pointer to LIST_ENTRY from
GetShellEnvVarList().
@retval EFI_SUCCESS The list was Set sucessfully.
**/
EFI_STATUS
EFIAPI
SetEnvironmentVariableList(
IN LIST_ENTRY *List
);
/**
sets all Shell-Guid-based environment variables. this will
also eliminate all pre-existing shell environment variables (even if they
are not on the list).
@param[in] Environment Points to a NULL-terminated array of environment
variables with the format 'x=y', where x is the
environment variable name and y is the value.
@retval EFI_SUCCESS The command executed successfully.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval EFI_OUT_OF_RESOURCES Out of resources.
@sa SetEnvironmentVariableList
**/
EFI_STATUS
EFIAPI
SetEnvironmentVariables(
IN CONST CHAR16 **Environment
);
/**
free function for ENV_VAR_LIST objects.
@param[in] List The pointer to pointer to list.
**/
VOID
EFIAPI
FreeEnvironmentVariableList(
IN LIST_ENTRY *List
);
#endif //_SHELL_ENVIRONMENT_VARIABLE_HEADER_

View File

@@ -0,0 +1,615 @@
/** @file
Provides interface to shell MAN file parser.
Copyright (c) 2009 - 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
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 "Shell.h"
/**
Verifies that the filename has .MAN on the end.
allocates a new buffer and copies the name (appending .MAN if necessary)
ASSERT if ManFileName is NULL
@param[in] ManFileName original filename
@return the new filename with .man as the extension.
**/
CHAR16 *
EFIAPI
GetManFileName(
IN CONST CHAR16 *ManFileName
)
{
CHAR16 *Buffer;
ASSERT(ManFileName != NULL);
//
// Fix the file name
//
if (StrnCmp(ManFileName+StrLen(ManFileName)-4, L".man", 4)==0) {
Buffer = AllocateZeroPool(StrSize(ManFileName));
StrCpy(Buffer, ManFileName);
} else {
Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16));
StrCpy(Buffer, ManFileName);
StrCat(Buffer, L".man");
}
return (Buffer);
}
/**
Search the path environment variable for possible locations and test for
which one contains a man file with the name specified. If a valid file is found
stop searching and return the (opened) SHELL_FILE_HANDLE for that file.
@param[in] FileName Name of the file to find and open.
@param[out] Handle Pointer to the handle of the found file. The
value of this is undefined for return values
except EFI_SUCCESS.
@retval EFI_SUCCESS The file was found. Handle is a valid SHELL_FILE_HANDLE
@retval EFI_INVALID_PARAMETER A parameter had an invalid value.
@retval EFI_NOT_FOUND The file was not found.
**/
EFI_STATUS
EFIAPI
SearchPathForFile(
IN CONST CHAR16 *FileName,
OUT SHELL_FILE_HANDLE *Handle
)
{
CHAR16 *FullFileName;
EFI_STATUS Status;
if ( FileName == NULL
|| Handle == NULL
|| StrLen(FileName) == 0
){
return (EFI_INVALID_PARAMETER);
}
FullFileName = ShellFindFilePath(FileName);
if (FullFileName == NULL) {
return (EFI_NOT_FOUND);
}
//
// now open that file
//
Status = EfiShellOpenFileByName(FullFileName, Handle, EFI_FILE_MODE_READ);
FreePool(FullFileName);
return (Status);
}
/**
parses through Buffer (which is MAN file formatted) and returns the
detailed help for any sub section specified in the comma seperated list of
sections provided. If the end of the file or a .TH section is found then
return.
Upon a sucessful return the caller is responsible to free the memory in *HelpText
@param[in] Buffer Buffer to read from
@param[in] Sections name of command's sub sections to find
@param[in] HelpText pointer to pointer to string where text goes.
@param[in] HelpSize pointer to size of allocated HelpText (may be updated)
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.
@retval EFI_SUCCESS the section was found and its description sotred in
an alloceted buffer.
**/
EFI_STATUS
EFIAPI
ManBufferFindSections(
IN CONST CHAR16 *Buffer,
IN CONST CHAR16 *Sections,
IN CHAR16 **HelpText,
IN UINTN *HelpSize
)
{
EFI_STATUS Status;
CONST CHAR16 *CurrentLocation;
BOOLEAN CurrentlyReading;
CHAR16 *SectionName;
UINTN SectionLen;
BOOLEAN Found;
CHAR16 *TempString;
CHAR16 *TempString2;
if ( Buffer == NULL
|| HelpText == NULL
|| HelpSize == NULL
){
return (EFI_INVALID_PARAMETER);
}
Status = EFI_SUCCESS;
CurrentlyReading = FALSE;
Found = FALSE;
for (CurrentLocation = Buffer,TempString = NULL
; CurrentLocation != NULL && *CurrentLocation != CHAR_NULL
; CurrentLocation=StrStr(CurrentLocation, L"\r\n"),TempString = NULL
){
while(CurrentLocation[0] == L'\r' || CurrentLocation[0] == L'\n') {
CurrentLocation++;
}
if (CurrentLocation[0] == L'#') {
//
// Skip comment lines
//
continue;
}
if (StrnCmp(CurrentLocation, L".TH", 3) == 0) {
//
// we hit the end of this commands section so stop.
//
break;
}
if (StrnCmp(CurrentLocation, L".SH ", 4) == 0) {
if (Sections == NULL) {
CurrentlyReading = TRUE;
continue;
} else if (CurrentlyReading) {
CurrentlyReading = FALSE;
}
CurrentLocation += 4;
//
// is this a section we want to read in?
//
if (StrLen(CurrentLocation)!=0) {
TempString2 = StrStr(CurrentLocation, L" ");
TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\r"));
TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));
ASSERT(TempString == NULL);
TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);
SectionName = TempString;
SectionLen = StrLen(SectionName);
SectionName = StrStr(Sections, SectionName);
if (SectionName == NULL) {
continue;
}
if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {
CurrentlyReading = TRUE;
}
}
} else if (CurrentlyReading) {
Found = TRUE;
if (StrLen(CurrentLocation)!=0) {
TempString2 = StrStr(CurrentLocation, L"\r");
TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));
ASSERT(TempString == NULL);
TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);
//
// copy and save the current line.
//
ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));
StrnCatGrow (HelpText, HelpSize, TempString, 0);
StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);
}
}
SHELL_FREE_NON_NULL(TempString);
}
if (!Found && !EFI_ERROR(Status)) {
return (EFI_NOT_FOUND);
}
return (Status);
}
/**
parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
detailed help for any sub section specified in the comma seperated list of
sections provided. If the end of the file or a .TH section is found then
return.
Upon a sucessful return the caller is responsible to free the memory in *HelpText
@param[in] Handle FileHandle to read from
@param[in] Sections name of command's sub sections to find
@param[out] HelpText pointer to pointer to string where text goes.
@param[out] HelpSize pointer to size of allocated HelpText (may be updated)
@param[in] Ascii TRUE if the file is ASCII, FALSE otherwise.
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.
@retval EFI_SUCCESS the section was found and its description sotred in
an alloceted buffer.
**/
EFI_STATUS
EFIAPI
ManFileFindSections(
IN SHELL_FILE_HANDLE Handle,
IN CONST CHAR16 *Sections,
OUT CHAR16 **HelpText,
OUT UINTN *HelpSize,
IN BOOLEAN Ascii
)
{
EFI_STATUS Status;
CHAR16 *ReadLine;
UINTN Size;
BOOLEAN CurrentlyReading;
CHAR16 *SectionName;
UINTN SectionLen;
BOOLEAN Found;
if ( Handle == NULL
|| HelpText == NULL
|| HelpSize == NULL
){
return (EFI_INVALID_PARAMETER);
}
Status = EFI_SUCCESS;
CurrentlyReading = FALSE;
Size = 1024;
Found = FALSE;
ReadLine = AllocateZeroPool(Size);
if (ReadLine == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
for (;!ShellFileHandleEof(Handle);Size = 1024) {
Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, &Ascii);
if (ReadLine[0] == L'#') {
//
// Skip comment lines
//
continue;
}
//
// ignore too small of buffer...
//
if (Status == EFI_BUFFER_TOO_SMALL) {
Status = EFI_SUCCESS;
}
if (EFI_ERROR(Status)) {
break;
} else if (StrnCmp(ReadLine, L".TH", 3) == 0) {
//
// we hit the end of this commands section so stop.
//
break;
} else if (StrnCmp(ReadLine, L".SH", 3) == 0) {
if (Sections == NULL) {
CurrentlyReading = TRUE;
continue;
}
//
// we found a section
//
if (CurrentlyReading) {
CurrentlyReading = FALSE;
}
//
// is this a section we want to read in?
//
for ( SectionName = ReadLine + 3
; *SectionName == L' '
; SectionName++);
SectionLen = StrLen(SectionName);
SectionName = StrStr(Sections, SectionName);
if (SectionName == NULL) {
continue;
}
if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {
CurrentlyReading = TRUE;
}
} else if (CurrentlyReading) {
Found = TRUE;
//
// copy and save the current line.
//
ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));
StrnCatGrow (HelpText, HelpSize, ReadLine, 0);
StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);
}
}
FreePool(ReadLine);
if (!Found && !EFI_ERROR(Status)) {
return (EFI_NOT_FOUND);
}
return (Status);
}
/**
parses through the MAN file formatted Buffer and returns the
"Brief Description" for the .TH section as specified by Command. If the
command section is not found return EFI_NOT_FOUND.
Upon a sucessful return the caller is responsible to free the memory in *BriefDesc
@param[in] Handle Buffer to read from
@param[in] Command name of command's section to find
@param[in] BriefDesc pointer to pointer to string where description goes.
@param[in] BriefSize pointer to size of allocated BriefDesc
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.
@retval EFI_SUCCESS the section was found and its description sotred in
an alloceted buffer.
**/
EFI_STATUS
EFIAPI
ManBufferFindTitleSection(
IN CHAR16 **Buffer,
IN CONST CHAR16 *Command,
IN CHAR16 **BriefDesc,
IN UINTN *BriefSize
)
{
EFI_STATUS Status;
CHAR16 *TitleString;
CHAR16 *TitleEnd;
CHAR16 *CurrentLocation;
if ( Buffer == NULL
|| Command == NULL
|| (BriefDesc != NULL && BriefSize == NULL)
){
return (EFI_INVALID_PARAMETER);
}
Status = EFI_SUCCESS;
TitleString = AllocatePool((7*sizeof(CHAR16)) + StrSize(Command));
if (TitleString == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
StrCpy(TitleString, L".TH ");
StrCat(TitleString, Command);
StrCat(TitleString, L" 0 ");
CurrentLocation = StrStr(*Buffer, TitleString);
if (CurrentLocation == NULL){
Status = EFI_NOT_FOUND;
} else {
//
// we found it so copy out the rest of the line into BriefDesc
// After skipping any spaces or zeroes
//
for (CurrentLocation += StrLen(TitleString)
; *CurrentLocation == L' ' || *CurrentLocation == L'0' || *CurrentLocation == L'1' || *CurrentLocation == L'\"'
; CurrentLocation++);
TitleEnd = StrStr(CurrentLocation, L"\"");
ASSERT(TitleEnd != NULL);
if (BriefDesc != NULL) {
*BriefSize = StrSize(TitleEnd);
*BriefDesc = AllocateZeroPool(*BriefSize);
if (*BriefDesc == NULL) {
Status = EFI_OUT_OF_RESOURCES;
} else {
StrnCpy(*BriefDesc, CurrentLocation, TitleEnd-CurrentLocation);
}
}
for (CurrentLocation = TitleEnd
; *CurrentLocation != L'\n'
; CurrentLocation++);
for (
; *CurrentLocation == L' ' || *CurrentLocation == L'\n' || *CurrentLocation == L'\r'
; CurrentLocation++);
*Buffer = CurrentLocation;
}
FreePool(TitleString);
return (Status);
}
/**
parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
"Brief Description" for the .TH section as specified by Command. if the
command section is not found return EFI_NOT_FOUND.
Upon a sucessful return the caller is responsible to free the memory in *BriefDesc
@param[in] Handle FileHandle to read from
@param[in] Command name of command's section to find
@param[out] BriefDesc pointer to pointer to string where description goes.
@param[out] BriefSize pointer to size of allocated BriefDesc
@param[in,out] Ascii TRUE if the file is ASCII, FALSE otherwise, will be
set if the file handle is at the 0 position.
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.
@retval EFI_SUCCESS the section was found and its description sotred in
an alloceted buffer.
**/
EFI_STATUS
EFIAPI
ManFileFindTitleSection(
IN SHELL_FILE_HANDLE Handle,
IN CONST CHAR16 *Command,
OUT CHAR16 **BriefDesc OPTIONAL,
OUT UINTN *BriefSize OPTIONAL,
IN OUT BOOLEAN *Ascii
)
{
EFI_STATUS Status;
CHAR16 *TitleString;
CHAR16 *ReadLine;
UINTN Size;
CHAR16 *TitleEnd;
UINTN TitleLen;
BOOLEAN Found;
if ( Handle == NULL
|| Command == NULL
|| (BriefDesc != NULL && BriefSize == NULL)
){
return (EFI_INVALID_PARAMETER);
}
Status = EFI_SUCCESS;
Size = 1024;
Found = FALSE;
ReadLine = AllocateZeroPool(Size);
if (ReadLine == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
TitleString = AllocatePool((4*sizeof(CHAR16)) + StrSize(Command));
if (TitleString == NULL) {
FreePool(ReadLine);
return (EFI_OUT_OF_RESOURCES);
}
StrCpy(TitleString, L".TH ");
StrCat(TitleString, Command);
TitleLen = StrLen(TitleString);
for (;!ShellFileHandleEof(Handle);Size = 1024) {
Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, Ascii);
if (ReadLine[0] == L'#') {
//
// Skip comment lines
//
continue;
}
//
// ignore too small of buffer...
//
if (Status == EFI_BUFFER_TOO_SMALL) {
Status = EFI_SUCCESS;
}
if (EFI_ERROR(Status)) {
break;
}
if (StrnCmp(ReadLine, TitleString, TitleLen) == 0) {
Found = TRUE;
//
// we found it so copy out the rest of the line into BriefDesc
// After skipping any spaces or zeroes
//
for ( TitleEnd = ReadLine+TitleLen
; *TitleEnd == L' ' || *TitleEnd == L'0' || *TitleEnd == L'1'
; TitleEnd++);
if (BriefDesc != NULL) {
*BriefSize = StrSize(TitleEnd);
*BriefDesc = AllocateZeroPool(*BriefSize);
if (*BriefDesc == NULL) {
Status = EFI_OUT_OF_RESOURCES;
break;
}
StrCpy(*BriefDesc, TitleEnd);
}
break;
}
}
FreePool(ReadLine);
FreePool(TitleString);
if (!Found && !EFI_ERROR(Status)) {
return (EFI_NOT_FOUND);
}
return (Status);
}
/**
This function returns the help information for the specified command. The help text
will be parsed from a UEFI Shell manual page. (see UEFI Shell 2.0 Appendix B)
If Sections is specified, then each section name listed will be compared in a casesensitive
manner, to the section names described in Appendix B. If the section exists,
it will be appended to the returned help text. If the section does not exist, no
information will be returned. If Sections is NULL, then all help text information
available will be returned.
if BriefDesc is NULL, then the breif description will not be savedd seperatly,
but placed first in the main HelpText.
@param[in] ManFileName Points to the NULL-terminated UEFI Shell MAN file name.
@param[in] Command Points to the NULL-terminated UEFI Shell command name.
@param[in] Sections Points to the NULL-terminated comma-delimited
section names to return. If NULL, then all
sections will be returned.
@param[out] BriefDesc On return, points to a callee-allocated buffer
containing brief description text.
@param[out] HelpText On return, points to a callee-allocated buffer
containing all specified help text.
@retval EFI_SUCCESS The help text was returned.
@retval EFI_OUT_OF_RESOURCES The necessary buffer could not be allocated to hold the
returned help text.
@retval EFI_INVALID_PARAMETER HelpText is NULL
@retval EFI_NOT_FOUND There is no help text available for Command.
**/
EFI_STATUS
EFIAPI
ProcessManFile(
IN CONST CHAR16 *ManFileName,
IN CONST CHAR16 *Command,
IN CONST CHAR16 *Sections OPTIONAL,
OUT CHAR16 **BriefDesc OPTIONAL,
OUT CHAR16 **HelpText
)
{
CHAR16 *TempString;
SHELL_FILE_HANDLE FileHandle;
EFI_STATUS Status;
UINTN HelpSize;
UINTN BriefSize;
BOOLEAN Ascii;
CHAR16 *TempString2;
EFI_DEVICE_PATH_PROTOCOL *FileDevPath;
EFI_DEVICE_PATH_PROTOCOL *DevPath;
if ( ManFileName == NULL
|| Command == NULL
|| HelpText == NULL
){
return (EFI_INVALID_PARAMETER);
}
HelpSize = 0;
BriefSize = 0;
TempString = NULL;
//
// See if it's in HII first
//
TempString = ShellCommandGetCommandHelp(Command);
if (TempString != NULL) {
TempString2 = TempString;
Status = ManBufferFindTitleSection(&TempString2, Command, BriefDesc, &BriefSize);
if (!EFI_ERROR(Status) && HelpText != NULL){
Status = ManBufferFindSections(TempString2, Sections, HelpText, &HelpSize);
}
} else {
FileHandle = NULL;
TempString = GetManFileName(ManFileName);
Status = SearchPathForFile(TempString, &FileHandle);
if (EFI_ERROR(Status)) {
FileDevPath = FileDevicePath(NULL, TempString);
DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, FileDevPath);
Status = InternalOpenFileDevicePath(DevPath, &FileHandle, EFI_FILE_MODE_READ, 0);
FreePool(FileDevPath);
FreePool(DevPath);
}
if (!EFI_ERROR(Status)) {
HelpSize = 0;
BriefSize = 0;
Status = ManFileFindTitleSection(FileHandle, Command, BriefDesc, &BriefSize, &Ascii);
if (!EFI_ERROR(Status) && HelpText != NULL){
Status = ManFileFindSections(FileHandle, Sections, HelpText, &HelpSize, Ascii);
}
ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
} else {
*HelpText = NULL;
}
}
if (TempString != NULL) {
FreePool(TempString);
}
return (Status);
}

View File

@@ -0,0 +1,86 @@
/** @file
Provides interface to shell MAN file parser.
Copyright (c) 2009 - 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
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.
**/
#ifndef _SHELL_MAN_FILE_PARSER_HEADER_
#define _SHELL_MAN_FILE_PARSER_HEADER_
/**
This function returns the help information for the specified command. The help text
will be parsed from a UEFI Shell manual page. (see UEFI Shell 2.0 Appendix B)
If Sections is specified, then each section name listed will be compared in a casesensitive
manner, to the section names described in Appendix B. If the section exists,
it will be appended to the returned help text. If the section does not exist, no
information will be returned. If Sections is NULL, then all help text information
available will be returned.
if BriefDesc is NULL, then the breif description will not be savedd seperatly,
but placed first in the main HelpText.
@param[in] ManFileName Points to the NULL-terminated UEFI Shell MAN file name.
@param[in] Command Points to the NULL-terminated UEFI Shell command name.
@param[in] Sections Points to the NULL-terminated comma-delimited
section names to return. If NULL, then all
sections will be returned.
@param[out] BriefDesc On return, points to a callee-allocated buffer
containing brief description text.
@param[out] HelpText On return, points to a callee-allocated buffer
containing all specified help text.
@retval EFI_SUCCESS The help text was returned.
@retval EFI_OUT_OF_RESOURCES The necessary buffer could not be allocated to hold the
returned help text.
@retval EFI_INVALID_PARAMETER HelpText is NULL
@retval EFI_NOT_FOUND There is no help text available for Command.
**/
EFI_STATUS
EFIAPI
ProcessManFile(
IN CONST CHAR16 *ManFileName,
IN CONST CHAR16 *Command,
IN CONST CHAR16 *Sections OPTIONAL,
OUT CHAR16 **BriefDesc,
OUT CHAR16 **HelpText
);
/**
parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
detailed help for any sub section specified in the comma seperated list of
sections provided. If the end of the file or a .TH section is found then
return.
Upon a sucessful return the caller is responsible to free the memory in *HelpText
@param[in] Handle FileHandle to read from
@param[in] Sections name of command's sub sections to find
@param[out] HelpText pointer to pointer to string where text goes.
@param[out] HelpSize pointer to size of allocated HelpText (may be updated)
@param[in] Ascii TRUE if the file is ASCII, FALSE otherwise.
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.
@retval EFI_SUCCESS the section was found and its description sotred in
an alloceted buffer.
**/
EFI_STATUS
EFIAPI
ManFileFindSections(
IN SHELL_FILE_HANDLE Handle,
IN CONST CHAR16 *Sections,
OUT CHAR16 **HelpText,
OUT UINTN *HelpSize,
IN BOOLEAN Ascii
);
#endif //_SHELL_MAN_FILE_PARSER_HEADER_

View File

@@ -0,0 +1,949 @@
/** @file
Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,
manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
Copyright (c) 2009 - 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
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 "ShellParametersProtocol.h"
/**
return the next parameter from a command line string;
This function moves the next parameter from Walker into TempParameter and moves
Walker up past that parameter for recursive calling. When the final parameter
is moved *Walker will be set to NULL;
Temp Parameter must be large enough to hold the parameter before calling this
function.
@param[in,out] Walker pointer to string of command line. Adjusted to
reminaing command line on return
@param[in,out] TempParameter pointer to string of command line item extracted.
**/
VOID
EFIAPI
GetNextParameter(
CHAR16 **Walker,
CHAR16 **TempParameter
)
{
CHAR16 *NextDelim;
CHAR16 *TempLoc;
ASSERT(Walker != NULL);
ASSERT(*Walker != NULL);
ASSERT(TempParameter != NULL);
ASSERT(*TempParameter != NULL);
//
// make sure we dont have any leading spaces
//
while ((*Walker)[0] == L' ') {
(*Walker)++;
}
//
// make sure we still have some params now...
//
if (StrLen(*Walker) == 0) {
ASSERT((*Walker)[0] == CHAR_NULL);
*Walker = NULL;
return;
}
//
// we have a quoted parameter
// could be the last parameter, but SHOULD have a trailing quote
//
if ((*Walker)[0] == L'\"') {
NextDelim = NULL;
for (TempLoc = *Walker + 1 ; TempLoc != NULL && *TempLoc != CHAR_NULL ; TempLoc++) {
if (*TempLoc == L'^' && *(TempLoc+1) == L'^') {
TempLoc++;
} else if (*TempLoc == L'^' && *(TempLoc+1) == L'\"') {
TempLoc++;
} else if (*TempLoc == L'^' && *(TempLoc+1) == L'|') {
TempLoc++;
} else if (*TempLoc == L'^') {
*TempLoc = L' ';
} else if (*TempLoc == L'\"') {
NextDelim = TempLoc;
break;
}
}
if (NextDelim - ((*Walker)+1) == 0) {
//
// found ""
//
StrCpy(*TempParameter, L"");
*Walker = NextDelim + 1;
} else if (NextDelim != NULL) {
StrnCpy(*TempParameter, (*Walker)+1, NextDelim - ((*Walker)+1));
*Walker = NextDelim + 1;
} else {
//
// last one... someone forgot the training quote!
//
StrCpy(*TempParameter, *Walker);
*Walker = NULL;
}
for (TempLoc = *TempParameter ; TempLoc != NULL && *TempLoc != CHAR_NULL ; TempLoc++) {
if ((*TempLoc == L'^' && *(TempLoc+1) == L'^')
|| (*TempLoc == L'^' && *(TempLoc+1) == L'|')
|| (*TempLoc == L'^' && *(TempLoc+1) == L'\"')
){
CopyMem(TempLoc, TempLoc+1, StrSize(TempLoc) - sizeof(TempLoc[0]));
}
}
} else {
//
// we have a regular parameter (no quote) OR
// we have the final parameter (no trailing space)
//
NextDelim = StrStr((*Walker), L" ");
if (NextDelim != NULL) {
StrnCpy(*TempParameter, *Walker, NextDelim - (*Walker));
(*TempParameter)[NextDelim - (*Walker)] = CHAR_NULL;
*Walker = NextDelim+1;
} else {
//
// last one.
//
StrCpy(*TempParameter, *Walker);
*Walker = NULL;
}
for (NextDelim = *TempParameter ; NextDelim != NULL && *NextDelim != CHAR_NULL ; NextDelim++) {
if (*NextDelim == L'^' && *(NextDelim+1) == L'^') {
CopyMem(NextDelim, NextDelim+1, StrSize(NextDelim) - sizeof(NextDelim[0]));
} else if (*NextDelim == L'^') {
*NextDelim = L' ';
}
}
while ((*TempParameter)[StrLen(*TempParameter)-1] == L' ') {
(*TempParameter)[StrLen(*TempParameter)-1] = CHAR_NULL;
}
while ((*TempParameter)[0] == L' ') {
CopyMem(*TempParameter, (*TempParameter)+1, StrSize(*TempParameter) - sizeof((*TempParameter)[0]));
}
}
return;
}
/**
function to populate Argc and Argv.
This function parses the CommandLine and divides it into standard C style Argc/Argv
parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space
delimited and quote surrounded parameter definition.
@param[in] CommandLine String of command line to parse
@param[in,out] Argv pointer to array of strings; one for each parameter
@param[in,out] Argc pointer to number of strings in Argv array
@return EFI_SUCCESS the operation was sucessful
@return EFI_OUT_OF_RESOURCES a memory allocation failed.
**/
EFI_STATUS
EFIAPI
ParseCommandLineToArgs(
IN CONST CHAR16 *CommandLine,
IN OUT CHAR16 ***Argv,
IN OUT UINTN *Argc
)
{
UINTN Count;
CHAR16 *TempParameter;
CHAR16 *Walker;
CHAR16 *NewParam;
UINTN Size;
ASSERT(Argc != NULL);
ASSERT(Argv != NULL);
if (CommandLine == NULL || StrLen(CommandLine)==0) {
(*Argc) = 0;
(*Argv) = NULL;
return (EFI_SUCCESS);
}
Size = StrSize(CommandLine);
TempParameter = AllocateZeroPool(Size);
if (TempParameter == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
for ( Count = 0
, Walker = (CHAR16*)CommandLine
; Walker != NULL && *Walker != CHAR_NULL
; GetNextParameter(&Walker, &TempParameter)
, Count++
);
/* Count = 0;
Walker = (CHAR16*)CommandLine;
while(Walker != NULL) {
GetNextParameter(&Walker, &TempParameter);
Count++;
}
*/
//
// lets allocate the pointer array
//
(*Argv) = AllocateZeroPool((Count)*sizeof(CHAR16*));
if (*Argv == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
*Argc = 0;
Walker = (CHAR16*)CommandLine;
while(Walker != NULL && *Walker != CHAR_NULL) {
SetMem16(TempParameter, Size, CHAR_NULL);
GetNextParameter(&Walker, &TempParameter);
NewParam = AllocateZeroPool(StrSize(TempParameter));
ASSERT(NewParam != NULL);
StrCpy(NewParam, TempParameter);
((CHAR16**)(*Argv))[(*Argc)] = NewParam;
(*Argc)++;
}
ASSERT(Count >= (*Argc));
return (EFI_SUCCESS);
}
/**
creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
installs it on our handle and if there is an existing version of the protocol
that one is cached for removal later.
@param[in,out] NewShellParameters on a successful return, a pointer to pointer
to the newly installed interface.
@param[in,out] RootShellInstance on a successful return, pointer to boolean.
TRUE if this is the root shell instance.
@retval EFI_SUCCESS the operation completed successfully.
@return other the operation failed.
@sa ReinstallProtocolInterface
@sa InstallProtocolInterface
@sa ParseCommandLineToArgs
**/
EFI_STATUS
EFIAPI
CreatePopulateInstallShellParametersProtocol (
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL **NewShellParameters,
IN OUT BOOLEAN *RootShellInstance
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
CHAR16 *FullCommandLine;
UINTN Size;
Size = 0;
FullCommandLine = NULL;
LoadedImage = NULL;
//
// Assert for valid parameters
//
ASSERT(NewShellParameters != NULL);
ASSERT(RootShellInstance != NULL);
//
// See if we have a shell parameters placed on us
//
Status = gBS->OpenProtocol (
gImageHandle,
&gEfiShellParametersProtocolGuid,
(VOID **) &ShellInfoObject.OldShellParameters,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
//
// if we don't then we must be the root shell (error is expected)
//
if (EFI_ERROR (Status)) {
*RootShellInstance = TRUE;
}
//
// Allocate the new structure
//
*NewShellParameters = AllocateZeroPool(sizeof(EFI_SHELL_PARAMETERS_PROTOCOL));
ASSERT(NewShellParameters != NULL);
//
// get loaded image protocol
//
Status = gBS->OpenProtocol (
gImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **) &LoadedImage,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
ASSERT_EFI_ERROR(Status);
//
// Build the full command line
//
Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, &FullCommandLine);
if (Status == EFI_BUFFER_TOO_SMALL) {
FullCommandLine = AllocateZeroPool(Size + LoadedImage->LoadOptionsSize);
Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, &FullCommandLine);
}
if (Status == EFI_NOT_FOUND) {
//
// no parameters via environment... ok
//
} else {
ASSERT_EFI_ERROR(Status);
}
if (Size == 0 && LoadedImage->LoadOptionsSize != 0) {
//
// Now we need to include a NULL terminator in the size.
//
Size = LoadedImage->LoadOptionsSize + sizeof(FullCommandLine[0]);
FullCommandLine = AllocateZeroPool(Size);
}
if (LoadedImage->LoadOptionsSize != 0){
StrCpy(FullCommandLine, LoadedImage->LoadOptions);
}
if (FullCommandLine != NULL) {
//
// Populate Argc and Argv
//
Status = ParseCommandLineToArgs(FullCommandLine,
&(*NewShellParameters)->Argv,
&(*NewShellParameters)->Argc);
FreePool(FullCommandLine);
ASSERT_EFI_ERROR(Status);
} else {
(*NewShellParameters)->Argv = NULL;
(*NewShellParameters)->Argc = 0;
}
//
// Populate the 3 faked file systems...
//
if (*RootShellInstance) {
(*NewShellParameters)->StdIn = &FileInterfaceStdIn;
(*NewShellParameters)->StdOut = &FileInterfaceStdOut;
(*NewShellParameters)->StdErr = &FileInterfaceStdErr;
Status = gBS->InstallProtocolInterface(&gImageHandle,
&gEfiShellParametersProtocolGuid,
EFI_NATIVE_INTERFACE,
(VOID*)(*NewShellParameters));
} else {
//
// copy from the existing ones
//
(*NewShellParameters)->StdIn = ShellInfoObject.OldShellParameters->StdIn;
(*NewShellParameters)->StdOut = ShellInfoObject.OldShellParameters->StdOut;
(*NewShellParameters)->StdErr = ShellInfoObject.OldShellParameters->StdErr;
Status = gBS->ReinstallProtocolInterface(gImageHandle,
&gEfiShellParametersProtocolGuid,
(VOID*)ShellInfoObject.OldShellParameters,
(VOID*)(*NewShellParameters));
}
return (Status);
}
/**
frees all memory used by createion and installation of shell parameters protocol
and if there was an old version installed it will restore that one.
@param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
being cleaned up.
@retval EFI_SUCCESS the cleanup was successful
@return other the cleanup failed
@sa ReinstallProtocolInterface
@sa UninstallProtocolInterface
**/
EFI_STATUS
EFIAPI
CleanUpShellParametersProtocol (
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *NewShellParameters
)
{
EFI_STATUS Status;
UINTN LoopCounter;
//
// If the old exists we need to restore it
//
if (ShellInfoObject.OldShellParameters != NULL) {
Status = gBS->ReinstallProtocolInterface(gImageHandle,
&gEfiShellParametersProtocolGuid,
(VOID*)NewShellParameters,
(VOID*)ShellInfoObject.OldShellParameters);
DEBUG_CODE(ShellInfoObject.OldShellParameters = NULL;);
} else {
//
// No old one, just uninstall us...
//
Status = gBS->UninstallProtocolInterface(gImageHandle,
&gEfiShellParametersProtocolGuid,
(VOID*)NewShellParameters);
}
if (NewShellParameters->Argv != NULL) {
for ( LoopCounter = 0
; LoopCounter < NewShellParameters->Argc
; LoopCounter++
){
FreePool(NewShellParameters->Argv[LoopCounter]);
}
FreePool(NewShellParameters->Argv);
}
FreePool(NewShellParameters);
return (Status);
}
/**
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
structure by parsing NewCommandLine. The current values are returned to the
user.
If OldStdIn or OldStdOut is NULL then that value is not returned.
@param[in,out] ShellParameters Pointer to parameter structure to modify.
@param[in] NewCommandLine The new command line to parse and use.
@param[out] OldStdIn Pointer to old StdIn.
@param[out] OldStdOut Pointer to old StdOut.
@param[out] OldStdErr Pointer to old StdErr.
@retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
EFI_STATUS
EFIAPI
UpdateStdInStdOutStdErr(
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
IN CONST CHAR16 *NewCommandLine,
OUT SHELL_FILE_HANDLE *OldStdIn,
OUT SHELL_FILE_HANDLE *OldStdOut,
OUT SHELL_FILE_HANDLE *OldStdErr
)
{
CHAR16 *CommandLineCopy;
CHAR16 *CommandLineWalker;
CHAR16 *StdErrFileName;
CHAR16 *StdOutFileName;
CHAR16 *StdInFileName;
CHAR16 *StdInVarName;
CHAR16 *StdOutVarName;
CHAR16 *StdErrVarName;
EFI_STATUS Status;
SHELL_FILE_HANDLE TempHandle;
UINT64 FileSize;
BOOLEAN OutUnicode;
BOOLEAN InUnicode;
BOOLEAN ErrUnicode;
BOOLEAN OutAppend;
BOOLEAN ErrAppend;
UINTN Size;
CHAR16 TagBuffer[2];
SPLIT_LIST *Split;
ASSERT(ShellParameters != NULL);
OutUnicode = TRUE;
InUnicode = TRUE;
ErrUnicode = TRUE;
StdInVarName = NULL;
StdOutVarName = NULL;
StdErrVarName = NULL;
StdErrFileName = NULL;
StdInFileName = NULL;
StdOutFileName = NULL;
ErrAppend = FALSE;
OutAppend = FALSE;
CommandLineCopy = NULL;
if (OldStdIn != NULL) {
*OldStdIn = ShellParameters->StdIn;
}
if (OldStdOut != NULL) {
*OldStdOut = ShellParameters->StdOut;
}
if (OldStdErr != NULL) {
*OldStdErr = ShellParameters->StdErr;
}
if (NewCommandLine == NULL) {
return (EFI_SUCCESS);
}
CommandLineCopy = StrnCatGrow(&CommandLineCopy, NULL, NewCommandLine, 0);
Status = EFI_SUCCESS;
Split = NULL;
if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
if (Split != NULL && Split->SplitStdIn != NULL) {
ShellParameters->StdIn = Split->SplitStdIn;
}
if (Split != NULL && Split->SplitStdOut != NULL) {
ShellParameters->StdOut = Split->SplitStdOut;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>>v ")) != NULL) {
StdErrVarName = CommandLineWalker += 6;
ErrAppend = TRUE;
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>v ")) != NULL) {
StdOutVarName = CommandLineWalker += 6;
OutAppend = TRUE;
} else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>v ")) != NULL) {
StdOutVarName = CommandLineWalker += 5;
OutAppend = TRUE;
} else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >v ")) != NULL) {
StdOutVarName = CommandLineWalker += 4;
OutAppend = FALSE;
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>a ")) != NULL) {
StdOutFileName = CommandLineWalker += 6;
OutAppend = TRUE;
OutUnicode = FALSE;
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>> ")) != NULL) {
if (StdOutFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdOutFileName = CommandLineWalker += 5;
OutAppend = TRUE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >> ")) != NULL) {
if (StdOutFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdOutFileName = CommandLineWalker += 4;
OutAppend = TRUE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>a ")) != NULL) {
if (StdOutFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdOutFileName = CommandLineWalker += 5;
OutAppend = TRUE;
OutUnicode = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>a ")) != NULL) {
if (StdOutFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdOutFileName = CommandLineWalker += 5;
OutAppend = FALSE;
OutUnicode = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >a ")) != NULL) {
if (StdOutFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdOutFileName = CommandLineWalker += 4;
OutAppend = FALSE;
OutUnicode = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>> ")) != NULL) {
if (StdErrFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdErrFileName = CommandLineWalker += 5;
ErrAppend = TRUE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>v ")) != NULL) {
if (StdErrVarName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdErrVarName = CommandLineWalker += 5;
ErrAppend = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>v ")) != NULL) {
if (StdOutVarName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdOutVarName = CommandLineWalker += 5;
OutAppend = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>a ")) != NULL) {
if (StdErrFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdErrFileName = CommandLineWalker += 5;
ErrAppend = FALSE;
ErrUnicode = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2> ")) != NULL) {
if (StdErrFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdErrFileName = CommandLineWalker += 4;
ErrAppend = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1> ")) != NULL) {
if (StdOutFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdOutFileName = CommandLineWalker += 4;
OutAppend = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" > ")) != NULL) {
if (StdOutFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdOutFileName = CommandLineWalker += 3;
OutAppend = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" < ")) != NULL) {
if (StdInFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdInFileName = CommandLineWalker += 3;
OutAppend = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <a ")) != NULL) {
if (StdInFileName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdInFileName = CommandLineWalker += 4;
OutAppend = FALSE;
}
}
if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <v ")) != NULL) {
if (StdInVarName != NULL) {
Status = EFI_INVALID_PARAMETER;
} else {
StdInVarName = CommandLineWalker += 4;
OutAppend = FALSE;
}
}
if (!EFI_ERROR(Status)) {
if (StdErrFileName != NULL && (CommandLineWalker = StrStr(StdErrFileName, L" ")) != NULL) {
CommandLineWalker[0] = CHAR_NULL;
}
if (StdOutFileName != NULL && (CommandLineWalker = StrStr(StdOutFileName, L" ")) != NULL) {
CommandLineWalker[0] = CHAR_NULL;
}
if (StdInFileName != NULL && (CommandLineWalker = StrStr(StdInFileName , L" ")) != NULL) {
CommandLineWalker[0] = CHAR_NULL;
}
if (StdErrVarName != NULL && (CommandLineWalker = StrStr(StdErrVarName , L" ")) != NULL) {
CommandLineWalker[0] = CHAR_NULL;
}
if (StdOutVarName != NULL && (CommandLineWalker = StrStr(StdOutVarName , L" ")) != NULL) {
CommandLineWalker[0] = CHAR_NULL;
}
if (StdInVarName != NULL && (CommandLineWalker = StrStr(StdInVarName , L" ")) != NULL) {
CommandLineWalker[0] = CHAR_NULL;
}
//
// Verify not the same and not duplicating something from a split
//
if ((StdErrFileName != NULL && StdOutFileName!= NULL && StringNoCaseCompare(&StdErrFileName, &StdOutFileName) == 0)
||(StdErrFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdErrFileName, &StdInFileName ) == 0)
||(StdOutFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdOutFileName, &StdInFileName ) == 0)
||(StdErrVarName != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdInVarName ) == 0)
||(StdOutVarName != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdOutVarName , &StdInVarName ) == 0)
||(StdErrVarName != NULL && StdOutVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdOutVarName ) == 0)
||(Split != NULL && Split->SplitStdIn != NULL && (StdInVarName != NULL || StdInFileName != NULL))
||(Split != NULL && Split->SplitStdOut != NULL && (StdOutVarName != NULL || StdOutFileName != NULL))
||(StdErrFileName != NULL && StdErrVarName != NULL)
||(StdOutFileName != NULL && StdOutVarName != NULL)
||(StdInFileName != NULL && StdInVarName != NULL)
||(StdErrVarName != NULL && !IsVolatileEnv(StdErrVarName))
||(StdOutVarName != NULL && !IsVolatileEnv(StdOutVarName))
){
Status = EFI_INVALID_PARAMETER;
} else {
//
// Open the Std<Whatever> and we should not have conflicts here...
//
//
// StdErr to a file
//
if (StdErrFileName != NULL) {
if (!ErrAppend) {
//
// delete existing file.
//
ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdErrFileName);
}
Status = ShellOpenFileByName(StdErrFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
ASSERT(TempHandle != NULL);
if (!ErrAppend && ErrUnicode && !EFI_ERROR(Status)) {
//
// Write out the UnicodeFileTag
//
Size = sizeof(CHAR16);
TagBuffer[0] = UnicodeFileTag;
TagBuffer[1] = CHAR_NULL;
ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
}
if (!ErrUnicode && !EFI_ERROR(Status)) {
TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
ASSERT(TempHandle != NULL);
}
if (!EFI_ERROR(Status)) {
ShellParameters->StdErr = TempHandle;
}
}
//
// StdOut to a file
//
if (!EFI_ERROR(Status) && StdOutFileName != NULL) {
if (!OutAppend) {
//
// delete existing file.
//
ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdOutFileName);
}
Status = ShellOpenFileByName(StdOutFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
ASSERT(TempHandle != NULL);
if (!OutAppend && OutUnicode && !EFI_ERROR(Status)) {
//
// Write out the UnicodeFileTag
//
Size = sizeof(CHAR16);
TagBuffer[0] = UnicodeFileTag;
TagBuffer[1] = CHAR_NULL;
ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
} else if (OutAppend) {
//
// Move to end of file
//
Status = ShellInfoObject.NewEfiShellProtocol->GetFileSize(TempHandle, &FileSize);
if (!EFI_ERROR(Status)) {
Status = ShellInfoObject.NewEfiShellProtocol->SetFilePosition(TempHandle, FileSize);
}
}
if (!OutUnicode && !EFI_ERROR(Status)) {
TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
ASSERT(TempHandle != NULL);
}
if (!EFI_ERROR(Status)) {
ShellParameters->StdOut = TempHandle;
}
}
//
// StdOut to a var
//
if (!EFI_ERROR(Status) && StdOutVarName != NULL) {
if (!OutAppend) {
//
// delete existing variable.
//
SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName, 0, L"");
}
TempHandle = CreateFileInterfaceEnv(StdOutVarName);
ASSERT(TempHandle != NULL);
if (!OutUnicode) {
TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
ASSERT(TempHandle != NULL);
}
ShellParameters->StdOut = TempHandle;
}
//
// StdErr to a var
//
if (!EFI_ERROR(Status) && StdErrVarName != NULL) {
if (!ErrAppend) {
//
// delete existing variable.
//
SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName, 0, L"");
}
TempHandle = CreateFileInterfaceEnv(StdErrVarName);
ASSERT(TempHandle != NULL);
if (!ErrUnicode) {
TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
ASSERT(TempHandle != NULL);
}
ShellParameters->StdErr = TempHandle;
}
//
// StdIn from a var
//
if (!EFI_ERROR(Status) && StdInVarName != NULL) {
TempHandle = CreateFileInterfaceEnv(StdInVarName);
if (!InUnicode) {
TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
}
Size = 0;
ASSERT(TempHandle != NULL);
if (((EFI_FILE_PROTOCOL*)TempHandle)->Read(TempHandle, &Size, NULL) != EFI_BUFFER_TOO_SMALL) {
Status = EFI_INVALID_PARAMETER;
} else {
ShellParameters->StdIn = TempHandle;
}
}
//
// StdIn from a file
//
if (!EFI_ERROR(Status) && StdInFileName != NULL) {
Status = ShellOpenFileByName(
StdInFileName,
&TempHandle,
EFI_FILE_MODE_READ,
0);
if (!InUnicode && !EFI_ERROR(Status)) {
TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
}
if (!EFI_ERROR(Status)) {
ShellParameters->StdIn = TempHandle;
}
}
}
}
FreePool(CommandLineCopy);
return (Status);
}
/**
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
structure with StdIn and StdOut. The current values are de-allocated.
@param[in,out] ShellParameters pointer to parameter structure to modify
@param[out] OldStdIn Pointer to old StdIn.
@param[out] OldStdOut Pointer to old StdOut.
@param[out] OldStdErr Pointer to old StdErr.
**/
EFI_STATUS
EFIAPI
RestoreStdInStdOutStdErr (
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
OUT SHELL_FILE_HANDLE *OldStdIn OPTIONAL,
OUT SHELL_FILE_HANDLE *OldStdOut OPTIONAL,
OUT SHELL_FILE_HANDLE *OldStdErr OPTIONAL
)
{
SPLIT_LIST *Split;
if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
} else {
Split = NULL;
}
if (OldStdIn != NULL && ShellParameters->StdIn != *OldStdIn) {
if ((Split != NULL && Split->SplitStdIn != ShellParameters->StdIn) || Split == NULL) {
gEfiShellProtocol->CloseFile(ShellParameters->StdIn);
}
ShellParameters->StdIn = OldStdIn==NULL?NULL:*OldStdIn;
}
if (OldStdOut != NULL && ShellParameters->StdOut != *OldStdOut) {
if ((Split != NULL && Split->SplitStdOut != ShellParameters->StdOut) || Split == NULL) {
gEfiShellProtocol->CloseFile(ShellParameters->StdOut);
}
ShellParameters->StdOut = OldStdOut==NULL?NULL:*OldStdOut;
}
return (EFI_SUCCESS);
}
/**
Funcion will replace the current Argc and Argv in the ShellParameters protocol
structure by parsing NewCommandLine. The current values are returned to the
user.
If OldArgv or OldArgc is NULL then that value is not returned.
@param[in,out] ShellParameters Pointer to parameter structure to modify.
@param[in] NewCommandLine The new command line to parse and use.
@param[out] OldArgv Pointer to old list of parameters.
@param[out] OldArgc Pointer to old number of items in Argv list.
@retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
EFI_STATUS
EFIAPI
UpdateArgcArgv(
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
IN CONST CHAR16 *NewCommandLine,
OUT CHAR16 ***OldArgv OPTIONAL,
OUT UINTN *OldArgc OPTIONAL
)
{
ASSERT(ShellParameters != NULL);
if (OldArgc != NULL) {
*OldArgc = ShellParameters->Argc;
}
if (OldArgc != NULL) {
*OldArgv = ShellParameters->Argv;
}
return (ParseCommandLineToArgs(NewCommandLine, &(ShellParameters->Argv), &(ShellParameters->Argc)));
}
/**
Funcion will replace the current Argc and Argv in the ShellParameters protocol
structure with Argv and Argc. The current values are de-allocated and the
OldArgv must not be deallocated by the caller.
@param[in,out] ShellParameters pointer to parameter structure to modify
@param[in] OldArgv pointer to old list of parameters
@param[in] OldArgc pointer to old number of items in Argv list
**/
VOID
EFIAPI
RestoreArgcArgv(
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
IN CHAR16 ***OldArgv,
IN UINTN *OldArgc
)
{
UINTN LoopCounter;
ASSERT(ShellParameters != NULL);
ASSERT(OldArgv != NULL);
ASSERT(OldArgc != NULL);
if (ShellParameters->Argv != NULL) {
for ( LoopCounter = 0
; LoopCounter < ShellParameters->Argc
; LoopCounter++
){
FreePool(ShellParameters->Argv[LoopCounter]);
}
FreePool(ShellParameters->Argv);
}
ShellParameters->Argv = *OldArgv;
*OldArgv = NULL;
ShellParameters->Argc = *OldArgc;
*OldArgc = 0;
}

View File

@@ -0,0 +1,208 @@
/** @file
Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,
manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
Copyright (c) 2009 - 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
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.
**/
#ifndef _SHELL_PARAMETERS_PROTOCOL_PROVIDER_HEADER_
#define _SHELL_PARAMETERS_PROTOCOL_PROVIDER_HEADER_
#include <Uefi.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/EfiShellParameters.h>
#include <Protocol/LoadedImage.h>
#include <Guid/ShellVariableGuid.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/ShellLib.h>
#include <Library/FileHandleLib.h>
#include "ShellEnvVar.h"
#include "FileHandleWrappers.h"
#include "Shell.h"
/**
creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
installs it on our handle and if there is an existing version of the protocol
that one is cached for removal later.
@param[in,out] NewShellParameters on a successful return, a pointer to pointer
to the newly installed interface.
@param[in,out] RootShellInstance on a successful return, pointer to boolean.
TRUE if this is the root shell instance.
@retval EFI_SUCCESS the operation completed successfully.
@return other the operation failed.
@sa ReinstallProtocolInterface
@sa InstallProtocolInterface
@sa ParseCommandLineToArgs
**/
EFI_STATUS
EFIAPI
CreatePopulateInstallShellParametersProtocol (
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL **NewShellParameters,
IN OUT BOOLEAN *RootShellInstance
);
/**
frees all memory used by createion and installation of shell parameters protocol
and if there was an old version installed it will restore that one.
@param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
being cleaned up.
@retval EFI_SUCCESS the cleanup was successful
@return other the cleanup failed
@sa ReinstallProtocolInterface
@sa UninstallProtocolInterface
**/
EFI_STATUS
EFIAPI
CleanUpShellParametersProtocol (
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *NewShellParameters
);
/**
Funcion will replace the current Argc and Argv in the ShellParameters protocol
structure by parsing NewCommandLine. The current values are returned to the
user.
@param[in,out] ShellParameters pointer to parameter structure to modify
@param[in] NewCommandLine the new command line to parse and use
@param[out] OldArgv pointer to old list of parameters
@param[out] OldArgc pointer to old number of items in Argv list
@retval EFI_SUCCESS operation was sucessful, Argv and Argc are valid
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.
**/
EFI_STATUS
EFIAPI
UpdateArgcArgv(
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
IN CONST CHAR16 *NewCommandLine,
OUT CHAR16 ***OldArgv,
OUT UINTN *OldArgc
);
/**
Funcion will replace the current Argc and Argv in the ShellParameters protocol
structure with Argv and Argc. The current values are de-allocated and the
OldArgv must not be deallocated by the caller.
@param[in,out] ShellParameters pointer to parameter structure to modify
@param[in] OldArgv pointer to old list of parameters
@param[in] OldArgc pointer to old number of items in Argv list
**/
VOID
EFIAPI
RestoreArgcArgv(
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
IN CHAR16 ***OldArgv,
IN UINTN *OldArgc
);
/**
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
structure by parsing NewCommandLine. The current values are returned to the
user.
If OldStdIn or OldStdOut is NULL then that value is not returned.
@param[in,out] ShellParameters Pointer to parameter structure to modify.
@param[in] NewCommandLine The new command line to parse and use.
@param[out] OldStdIn Pointer to old StdIn.
@param[out] OldStdOut Pointer to old StdOut.
@param[out] OldStdErr Pointer to old StdErr.
@retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
EFI_STATUS
EFIAPI
UpdateStdInStdOutStdErr(
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
IN CONST CHAR16 *NewCommandLine,
OUT SHELL_FILE_HANDLE *OldStdIn OPTIONAL,
OUT SHELL_FILE_HANDLE *OldStdOut OPTIONAL,
OUT SHELL_FILE_HANDLE *OldStdErr OPTIONAL
);
/**
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
structure with StdIn and StdOut. The current values are de-allocated.
@param[in,out] ShellParameters pointer to parameter structure to modify
@param[out] OldStdIn Pointer to old StdIn.
@param[out] OldStdOut Pointer to old StdOut.
@param[out] OldStdErr Pointer to old StdErr.
**/
EFI_STATUS
EFIAPI
RestoreStdInStdOutStdErr (
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
OUT SHELL_FILE_HANDLE *OldStdIn OPTIONAL,
OUT SHELL_FILE_HANDLE *OldStdOut OPTIONAL,
OUT SHELL_FILE_HANDLE *OldStdErr OPTIONAL
);
/**
function to populate Argc and Argv.
This function parses the CommandLine and divides it into standard C style Argc/Argv
parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space
delimited and quote surrounded parameter definition.
@param[in] CommandLine String of command line to parse
@param[in,out] Argv pointer to array of strings; one for each parameter
@param[in,out] Argc pointer to number of strings in Argv array
@return EFI_SUCCESS the operation was sucessful
@return EFI_OUT_OF_RESOURCES a memory allocation failed.
**/
EFI_STATUS
EFIAPI
ParseCommandLineToArgs(
IN CONST CHAR16 *CommandLine,
IN OUT CHAR16 ***Argv,
IN OUT UINTN *Argc
);
/**
return the next parameter from a command line string;
This function moves the next parameter from Walker into TempParameter and moves
Walker up past that parameter for recursive calling. When the final parameter
is moved *Walker will be set to NULL;
Temp Parameter must be large enough to hold the parameter before calling this
function.
@param[in,out] Walker pointer to string of command line. Adjusted to
reminaing command line on return
@param[in,out] TempParameter pointer to string of command line item extracted.
**/
VOID
EFIAPI
GetNextParameter(
CHAR16 **Walker,
CHAR16 **TempParameter
);
#endif //_SHELL_PARAMETERS_PROTOCOL_PROVIDER_HEADER_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,950 @@
/** @file
Member functions of EFI_SHELL_PROTOCOL and functions for creation,
manipulation, and initialization of EFI_SHELL_PROTOCOL.
Copyright (c) 2009 - 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
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.
**/
#ifndef _SHELL_PROTOCOL_HEADER_
#define _SHELL_PROTOCOL_HEADER_
#include <Uefi.h>
#include <ShellBase.h>
#include <Guid/ShellVariableGuid.h>
#include <Guid/ShellMapGuid.h>
#include <Guid/ShellAliasGuid.h>
#include <Protocol/EfiShell.h>
#include <Protocol/EfiShellParameters.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/DevicePathToText.h>
#include <Protocol/ComponentName2.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/UnicodeCollation.h>
#include <Protocol/DevicePath.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/ShellCommandLib.h>
#include <Library/PrintLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiLib.h>
#include <Library/SortLib.h>
#include <Library/PcdLib.h>
#include <Library/ShellLib.h>
#include "FileHandleWrappers.h"
#include "ShellEnvVar.h"
#include "ShellManParser.h"
typedef struct {
LIST_ENTRY Link;
EFI_SHELL_PROTOCOL *Interface;
EFI_HANDLE Handle;
} SHELL_PROTOCOL_HANDLE_LIST;
// flags values...
#define SHELL_MAP_FLAGS_CONSIST BIT1
/**
Function to create and install on the current handle.
Will overwrite any existing ShellProtocols in the system to be sure that
the current shell is in control.
This must be removed via calling CleanUpShellProtocol().
@param[in,out] NewShell The pointer to the pointer to the structure
to install.
@retval EFI_SUCCESS The operation was successful.
@return An error from LocateHandle, CreateEvent, or other core function.
**/
EFI_STATUS
EFIAPI
CreatePopulateInstallShellProtocol (
IN OUT EFI_SHELL_PROTOCOL **NewShell
);
/**
Opposite of CreatePopulateInstallShellProtocol.
Free all memory and restore the system to the state it was in before calling
CreatePopulateInstallShellProtocol.
@param[in,out] NewShell The pointer to the new shell protocol structure.
@retval EFI_SUCCESS The operation was successful.
**/
EFI_STATUS
EFIAPI
CleanUpShellProtocol (
IN OUT EFI_SHELL_PROTOCOL *NewShell
);
/**
This function creates a mapping for a device path.
@param DevicePath Points to the device path. If this is NULL and Mapping points to a valid mapping,
then the mapping will be deleted.
@param Mapping Points to the NULL-terminated mapping for the device path. Must end with a ':'
@retval EFI_SUCCESS Mapping created or deleted successfully.
@retval EFI_NO_MAPPING There is no handle that corresponds exactly to DevicePath. See the
boot service function LocateDevicePath().
@retval EFI_ACCESS_DENIED The mapping is a built-in alias.
@retval EFI_INVALID_PARAMETER Mapping was NULL
@retval EFI_INVALID_PARAMETER Mapping did not end with a ':'
@retval EFI_INVALID_PARAMETER DevicePath was not pointing at a device that had a SIMPLE_FILE_SYSTEM_PROTOCOL installed.
@retval EFI_NOT_FOUND There was no mapping found to delete
@retval EFI_OUT_OF_RESOURCES Memory allocation failed
**/
EFI_STATUS
EFIAPI
EfiShellSetMap(
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
IN CONST CHAR16 *Mapping
);
/**
Gets the device path from the mapping.
This function gets the device path associated with a mapping.
@param Mapping A pointer to the mapping
@retval !=NULL Pointer to the device path that corresponds to the
device mapping. The returned pointer does not need
to be freed.
@retval NULL There is no device path associated with the
specified mapping.
**/
CONST EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
EfiShellGetDevicePathFromMap(
IN CONST CHAR16 *Mapping
);
/**
Gets the mapping that most closely matches the device path.
This function gets the mapping which corresponds to the device path *DevicePath. If
there is no exact match, then the mapping which most closely matches *DevicePath
is returned, and *DevicePath is updated to point to the remaining portion of the
device path. If there is an exact match, the mapping is returned and *DevicePath
points to the end-of-device-path node.
@param DevicePath On entry, points to a device path pointer. On
exit, updates the pointer to point to the
portion of the device path after the mapping.
@retval NULL No mapping was found.
@return !=NULL Pointer to NULL-terminated mapping. The buffer
is callee allocated and should be freed by the caller.
**/
CONST CHAR16 *
EFIAPI
EfiShellGetMapFromDevicePath(
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
);
/**
Converts a device path to a file system-style path.
This function converts a device path to a file system path by replacing part, or all, of
the device path with the file-system mapping. If there are more than one application
file system mappings, the one that most closely matches Path will be used.
@param Path The pointer to the device path
@retval NULL the device path could not be found.
@return all The pointer of the NULL-terminated file path. The path
is callee-allocated and should be freed by the caller.
**/
CHAR16 *
EFIAPI
EfiShellGetFilePathFromDevicePath(
IN CONST EFI_DEVICE_PATH_PROTOCOL *Path
);
/**
Converts a file system style name to a device path.
This function converts a file system style name to a device path, by replacing any
mapping references to the associated device path.
@param Path the pointer to the path
@return all The pointer of the file path. The file path is callee
allocated and should be freed by the caller.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
EfiShellGetDevicePathFromFilePath(
IN CONST CHAR16 *Path
);
/**
Gets the name of the device specified by the device handle.
This function gets the user-readable name of the device specified by the device
handle. If no user-readable name could be generated, then *BestDeviceName will be
NULL and EFI_NOT_FOUND will be returned.
If EFI_DEVICE_NAME_USE_COMPONENT_NAME is set, then the function will return the
device's name using the EFI_COMPONENT_NAME2_PROTOCOL, if present on
DeviceHandle.
If EFI_DEVICE_NAME_USE_DEVICE_PATH is set, then the function will return the
device's name using the EFI_DEVICE_PATH_PROTOCOL, if present on DeviceHandle.
If both EFI_DEVICE_NAME_USE_COMPONENT_NAME and
EFI_DEVICE_NAME_USE_DEVICE_PATH are set, then
EFI_DEVICE_NAME_USE_COMPONENT_NAME will have higher priority.
@param DeviceHandle The handle of the device.
@param Flags Determines the possible sources of component names.
Valid bits are:
EFI_DEVICE_NAME_USE_COMPONENT_NAME
EFI_DEVICE_NAME_USE_DEVICE_PATH
@param Language A pointer to the language specified for the device
name, in the same format as described in the UEFI
specification, Appendix M
@param BestDeviceName On return, points to the callee-allocated NULL-
terminated name of the device. If no device name
could be found, points to NULL. The name must be
freed by the caller...
@retval EFI_SUCCESS Get the name successfully.
@retval EFI_NOT_FOUND Fail to get the device name.
@retval EFI_INVALID_PARAMETER Flags did not have a valid bit set.
@retval EFI_INVALID_PARAMETER BestDeviceName was NULL
@retval EFI_INVALID_PARAMETER DeviceHandle was NULL
**/
EFI_STATUS
EFIAPI
EfiShellGetDeviceName(
IN EFI_HANDLE DeviceHandle,
IN EFI_SHELL_DEVICE_NAME_FLAGS Flags,
IN CHAR8 *Language,
OUT CHAR16 **BestDeviceName
);
/**
Opens the root directory of a device on a handle
This function opens the root directory of a device and returns a file handle to it.
@param DeviceHandle The handle of the device that contains the volume.
@param FileHandle On exit, points to the file handle corresponding to the root directory on the
device.
@retval EFI_SUCCESS Root opened successfully.
@retval EFI_NOT_FOUND EFI_SIMPLE_FILE_SYSTEM could not be found or the root directory
could not be opened.
@retval EFI_VOLUME_CORRUPTED The data structures in the volume were corrupted.
@retval EFI_DEVICE_ERROR The device had an error
**/
EFI_STATUS
EFIAPI
EfiShellOpenRootByHandle(
IN EFI_HANDLE DeviceHandle,
OUT SHELL_FILE_HANDLE *FileHandle
);
/**
Opens the root directory of a device.
This function opens the root directory of a device and returns a file handle to it.
@param DevicePath Points to the device path corresponding to the device where the
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL is installed.
@param FileHandle On exit, points to the file handle corresponding to the root directory on the
device.
@retval EFI_SUCCESS Root opened successfully.
@retval EFI_NOT_FOUND EFI_SIMPLE_FILE_SYSTEM could not be found or the root directory
could not be opened.
@retval EFI_VOLUME_CORRUPTED The data structures in the volume were corrupted.
@retval EFI_DEVICE_ERROR The device had an error
**/
EFI_STATUS
EFIAPI
EfiShellOpenRoot(
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT SHELL_FILE_HANDLE *FileHandle
);
/**
Returns whether any script files are currently being processed.
@retval TRUE There is at least one script file active.
@retval FALSE No script files are active now.
**/
BOOLEAN
EFIAPI
EfiShellBatchIsActive (
VOID
);
/**
Worker function to open a file based on a device path. this will open the root
of the volume and then traverse down to the file itself.
@param DevicePath2 Device Path of the file
@param FileHandle Pointer to the file upon a successful return
@param OpenMode mode to open file in.
@param Attributes the File Attributes to use when creating a new file
@retval EFI_SUCCESS the file is open and FileHandle is valid
@retval EFI_UNSUPPORTED the device path cotained non-path elements
@retval other an error ocurred.
**/
EFI_STATUS
EFIAPI
InternalOpenFileDevicePath(
IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath2,
OUT SHELL_FILE_HANDLE *FileHandle,
IN UINT64 OpenMode,
IN UINT64 Attributes OPTIONAL
);
/**
Creates a file or directory by name.
This function creates an empty new file or directory with the specified attributes and
returns the new file's handle. If the file already exists and is read-only, then
EFI_INVALID_PARAMETER will be returned.
If the file already existed, it is truncated and its attributes updated. If the file is
created successfully, the FileHandle is the file's handle, else, the FileHandle is NULL.
If the file name begins with >v, then the file handle which is returned refers to the
shell environment variable with the specified name. If the shell environment variable
already exists and is non-volatile then EFI_INVALID_PARAMETER is returned.
@param FileName Pointer to NULL-terminated file path
@param FileAttribs The new file's attrbiutes. the different attributes are
described in EFI_FILE_PROTOCOL.Open().
@param FileHandle On return, points to the created file handle or directory's handle
@retval EFI_SUCCESS The file was opened. FileHandle points to the new file's handle.
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
@retval EFI_UNSUPPORTED could not open the file path
@retval EFI_NOT_FOUND the specified file could not be found on the devide, or could not
file the file system on the device.
@retval EFI_NO_MEDIA the device has no medium.
@retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no
longer supported.
@retval EFI_DEVICE_ERROR The device reported an error or can't get the file path according
the DirName.
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
@retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write
when the media is write-protected.
@retval EFI_ACCESS_DENIED The service denied access to the file.
@retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
@retval EFI_VOLUME_FULL The volume is full.
**/
EFI_STATUS
EFIAPI
EfiShellCreateFile(
IN CONST CHAR16 *FileName,
IN UINT64 FileAttribs,
OUT SHELL_FILE_HANDLE *FileHandle
);
/**
Opens a file or a directory by file name.
This function opens the specified file in the specified OpenMode and returns a file
handle.
If the file name begins with >v, then the file handle which is returned refers to the
shell environment variable with the specified name. If the shell environment variable
exists, is non-volatile and the OpenMode indicates EFI_FILE_MODE_WRITE, then
EFI_INVALID_PARAMETER is returned.
If the file name is >i, then the file handle which is returned refers to the standard
input. If the OpenMode indicates EFI_FILE_MODE_WRITE, then EFI_INVALID_PARAMETER
is returned.
If the file name is >o, then the file handle which is returned refers to the standard
output. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER
is returned.
If the file name is >e, then the file handle which is returned refers to the standard
error. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER
is returned.
If the file name is NUL, then the file handle that is returned refers to the standard NUL
file. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER is
returned.
If return EFI_SUCCESS, the FileHandle is the opened file's handle, else, the
FileHandle is NULL.
@param FileName Points to the NULL-terminated UCS-2 encoded file name.
@param FileHandle On return, points to the file handle.
@param OpenMode File open mode. Either EFI_FILE_MODE_READ or
EFI_FILE_MODE_WRITE from section 12.4 of the UEFI
Specification.
@retval EFI_SUCCESS The file was opened. FileHandle has the opened file's handle.
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. FileHandle is NULL.
@retval EFI_UNSUPPORTED Could not open the file path. FileHandle is NULL.
@retval EFI_NOT_FOUND The specified file could not be found on the device or the file
system could not be found on the device. FileHandle is NULL.
@retval EFI_NO_MEDIA The device has no medium. FileHandle is NULL.
@retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no
longer supported. FileHandle is NULL.
@retval EFI_DEVICE_ERROR The device reported an error or can't get the file path according
the FileName. FileHandle is NULL.
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. FileHandle is NULL.
@retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write
when the media is write-protected. FileHandle is NULL.
@retval EFI_ACCESS_DENIED The service denied access to the file. FileHandle is NULL.
@retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. FileHandle
is NULL.
@retval EFI_VOLUME_FULL The volume is full. FileHandle is NULL.
**/
EFI_STATUS
EFIAPI
EfiShellOpenFileByName(
IN CONST CHAR16 *FileName,
OUT SHELL_FILE_HANDLE *FileHandle,
IN UINT64 OpenMode
);
/**
Deletes the file specified by the file name.
This function deletes a file.
@param FileName Points to the NULL-terminated file name.
@retval EFI_SUCCESS The file was closed and deleted, and the handle was closed.
@retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
@sa EfiShellCreateFile
@sa FileHandleDelete
**/
EFI_STATUS
EFIAPI
EfiShellDeleteFileByName(
IN CONST CHAR16 *FileName
);
/**
Disables the page break output mode.
**/
VOID
EFIAPI
EfiShellDisablePageBreak (
VOID
);
/**
Enables the page break output mode.
**/
VOID
EFIAPI
EfiShellEnablePageBreak (
VOID
);
/**
internal worker function to run a command via Device Path
@param ParentImageHandle A handle of the image that is executing the specified
command line.
@param DevicePath device path of the file to execute
@param CommandLine Points to the NULL-terminated UCS-2 encoded string
containing the command line. If NULL then the command-
line will be empty.
@param Environment Points to a NULL-terminated array of environment
variables with the format 'x=y', where x is the
environment variable name and y is the value. If this
is NULL, then the current shell environment is used.
@param StatusCode Points to the status code returned by the command.
@retval EFI_SUCCESS The command executed successfully. The status code
returned by the command is pointed to by StatusCode.
@retval EFI_INVALID_PARAMETER The parameters are invalid.
@retval EFI_OUT_OF_RESOURCES Out of resources.
@retval EFI_UNSUPPORTED Nested shell invocations are not allowed.
**/
EFI_STATUS
EFIAPI
InternalShellExecuteDevicePath(
IN CONST EFI_HANDLE *ParentImageHandle,
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CONST CHAR16 *CommandLine OPTIONAL,
IN CONST CHAR16 **Environment OPTIONAL,
OUT EFI_STATUS *StatusCode OPTIONAL
);
/**
Execute the command line.
This function creates a nested instance of the shell and executes the specified
command (CommandLine) with the specified environment (Environment). Upon return,
the status code returned by the specified command is placed in StatusCode.
If Environment is NULL, then the current environment is used and all changes made
by the commands executed will be reflected in the current environment. If the
Environment is non-NULL, then the changes made will be discarded.
The CommandLine is executed from the current working directory on the current
device.
@param ParentImageHandle A handle of the image that is executing the specified
command line.
@param CommandLine Points to the NULL-terminated UCS-2 encoded string
containing the command line. If NULL then the command-
line will be empty.
@param Environment Points to a NULL-terminated array of environment
variables with the format 'x=y', where x is the
environment variable name and y is the value. If this
is NULL, then the current shell environment is used.
@param StatusCode Points to the status code returned by the command.
@retval EFI_SUCCESS The command executed successfully. The status code
returned by the command is pointed to by StatusCode.
@retval EFI_INVALID_PARAMETER The parameters are invalid.
@retval EFI_OUT_OF_RESOURCES Out of resources.
@retval EFI_UNSUPPORTED Nested shell invocations are not allowed.
**/
EFI_STATUS
EFIAPI
EfiShellExecute(
IN EFI_HANDLE *ParentImageHandle,
IN CHAR16 *CommandLine OPTIONAL,
IN CHAR16 **Environment OPTIONAL,
OUT EFI_STATUS *StatusCode OPTIONAL
);
/**
Utility cleanup function for EFI_SHELL_FILE_INFO objects.
1) frees all pointers (non-NULL)
2) Closes the SHELL_FILE_HANDLE
@param FileListNode pointer to the list node to free
**/
VOID
EFIAPI
FreeShellFileInfoNode(
IN EFI_SHELL_FILE_INFO *FileListNode
);
/**
Frees the file list.
This function cleans up the file list and any related data structures. It has no
impact on the files themselves.
@param FileList The file list to free. Type EFI_SHELL_FILE_INFO is
defined in OpenFileList()
@retval EFI_SUCCESS Free the file list successfully.
@retval EFI_INVALID_PARAMETER FileList was NULL or *FileList was NULL;
**/
EFI_STATUS
EFIAPI
EfiShellFreeFileList(
IN EFI_SHELL_FILE_INFO **FileList
);
/**
Deletes the duplicate file names files in the given file list.
This function deletes the reduplicate files in the given file list.
@param FileList A pointer to the first entry in the file list.
@retval EFI_SUCCESS Always success.
@retval EFI_INVALID_PARAMETER FileList was NULL or *FileList was NULL;
**/
EFI_STATUS
EFIAPI
EfiShellRemoveDupInFileList(
IN EFI_SHELL_FILE_INFO **FileList
);
/**
Allocates and populates a EFI_SHELL_FILE_INFO structure. if any memory operation
failed it will return NULL.
@param[in] BasePath the Path to prepend onto filename for FullPath
@param[in] Status Status member initial value.
@param[in] FullName FullName member initial value.
@param[in] FileName FileName member initial value.
@param[in] Handle Handle member initial value.
@param[in] Info Info struct to copy.
**/
EFI_SHELL_FILE_INFO *
EFIAPI
CreateAndPopulateShellFileInfo(
IN CONST CHAR16 *BasePath,
IN CONST EFI_STATUS Status,
IN CONST CHAR16 *FullName,
IN CONST CHAR16 *FileName,
IN CONST SHELL_FILE_HANDLE Handle,
IN CONST EFI_FILE_INFO *Info
);
/**
Find all files in a specified directory.
@param FileDirHandle Handle of the directory to search.
@param FileList On return, points to the list of files in the directory
or NULL if there are no files in the directory.
@retval EFI_SUCCESS File information was returned successfully.
@retval EFI_VOLUME_CORRUPTED The file system structures have been corrupted.
@retval EFI_DEVICE_ERROR The device reported an error.
@retval EFI_NO_MEDIA The device media is not present.
@retval EFI_INVALID_PARAMETER The FileDirHandle was not a directory.
**/
EFI_STATUS
EFIAPI
EfiShellFindFilesInDir(
IN SHELL_FILE_HANDLE FileDirHandle,
OUT EFI_SHELL_FILE_INFO **FileList
);
/**
Find files that match a specified pattern.
This function searches for all files and directories that match the specified
FilePattern. The FilePattern can contain wild-card characters. The resulting file
information is placed in the file list FileList.
Wildcards are processed
according to the rules specified in UEFI Shell 2.0 spec section 3.7.1.
The files in the file list are not opened. The OpenMode field is set to 0 and the FileInfo
field is set to NULL.
if *FileList is not NULL then it must be a pre-existing and properly initialized list.
@param FilePattern Points to a NULL-terminated shell file path, including wildcards.
@param FileList On return, points to the start of a file list containing the names
of all matching files or else points to NULL if no matching files
were found. only on a EFI_SUCCESS return will; this be non-NULL.
@retval EFI_SUCCESS Files found. FileList is a valid list.
@retval EFI_NOT_FOUND No files found.
@retval EFI_NO_MEDIA The device has no media
@retval EFI_DEVICE_ERROR The device reported an error
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted
**/
EFI_STATUS
EFIAPI
EfiShellFindFiles(
IN CONST CHAR16 *FilePattern,
OUT EFI_SHELL_FILE_INFO **FileList
);
/**
Opens the files that match the path specified.
This function opens all of the files specified by Path. Wildcards are processed
according to the rules specified in UEFI Shell 2.0 spec section 3.7.1. Each
matching file has an EFI_SHELL_FILE_INFO structure created in a linked list.
@param Path A pointer to the path string.
@param OpenMode Specifies the mode used to open each file, EFI_FILE_MODE_READ or
EFI_FILE_MODE_WRITE.
@param FileList Points to the start of a list of files opened.
@retval EFI_SUCCESS Create the file list successfully.
@return Others Can't create the file list.
**/
EFI_STATUS
EFIAPI
EfiShellOpenFileList(
IN CHAR16 *Path,
IN UINT64 OpenMode,
IN OUT EFI_SHELL_FILE_INFO **FileList
);
/**
Gets the environment variable.
This function returns the current value of the specified environment variable.
@param Name A pointer to the environment variable name
@return !=NULL The environment variable's value. The returned
pointer does not need to be freed by the caller.
@retval NULL The environment variable doesn't exist.
**/
CONST CHAR16 *
EFIAPI
EfiShellGetEnv(
IN CONST CHAR16 *Name
);
/**
Sets the environment variable.
This function changes the current value of the specified environment variable. If the
environment variable exists and the Value is an empty string, then the environment
variable is deleted. If the environment variable exists and the Value is not an empty
string, then the value of the environment variable is changed. If the environment
variable does not exist and the Value is an empty string, there is no action. If the
environment variable does not exist and the Value is a non-empty string, then the
environment variable is created and assigned the specified value.
For a description of volatile and non-volatile environment variables, see UEFI Shell
2.0 specification section 3.6.1.
@param Name Points to the NULL-terminated environment variable name.
@param Value Points to the NULL-terminated environment variable value. If the value is an
empty string then the environment variable is deleted.
@param Volatile Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE).
@retval EFI_SUCCESS The environment variable was successfully updated.
**/
EFI_STATUS
EFIAPI
EfiShellSetEnv(
IN CONST CHAR16 *Name,
IN CONST CHAR16 *Value,
IN BOOLEAN Volatile
);
/**
Returns the current directory on the specified device.
If FileSystemMapping is NULL, it returns the current working directory. If the
FileSystemMapping is not NULL, it returns the current directory associated with the
FileSystemMapping. In both cases, the returned name includes the file system
mapping (i.e. fs0:\current-dir).
@param FileSystemMapping A pointer to the file system mapping. If NULL,
then the current working directory is returned.
@retval !=NULL The current directory.
@retval NULL Current directory does not exist.
**/
CONST CHAR16 *
EFIAPI
EfiShellGetCurDir(
IN CONST CHAR16 *FileSystemMapping OPTIONAL
);
/**
Changes the current directory on the specified device.
If the FileSystem is NULL, and the directory Dir does not contain a file system's
mapped name, this function changes the current working directory. If FileSystem is
NULL and the directory Dir contains a mapped name, then the current file system and
the current directory on that file system are changed.
If FileSystem is not NULL, and Dir is NULL, then this changes the current working file
system.
If FileSystem is not NULL and Dir is not NULL, then this function changes the current
directory on the specified file system.
If the current working directory or the current working file system is changed then the
%cwd% environment variable will be updated
@param FileSystem A pointer to the file system's mapped name. If NULL, then the current working
directory is changed.
@param Dir Points to the NULL-terminated directory on the device specified by FileSystem.
@retval EFI_SUCCESS The operation was sucessful
**/
EFI_STATUS
EFIAPI
EfiShellSetCurDir(
IN CONST CHAR16 *FileSystem OPTIONAL,
IN CONST CHAR16 *Dir
);
/**
Return help information about a specific command.
This function returns the help information for the specified command. The help text
can be internal to the shell or can be from a UEFI Shell manual page.
If Sections is specified, then each section name listed will be compared in a casesensitive
manner, to the section names described in Appendix B. If the section exists,
it will be appended to the returned help text. If the section does not exist, no
information will be returned. If Sections is NULL, then all help text information
available will be returned.
@param Command Points to the NULL-terminated UEFI Shell command name.
@param Sections Points to the NULL-terminated comma-delimited
section names to return. If NULL, then all
sections will be returned.
@param HelpText On return, points to a callee-allocated buffer
containing all specified help text.
@retval EFI_SUCCESS The help text was returned.
@retval EFI_OUT_OF_RESOURCES The necessary buffer could not be allocated to hold the
returned help text.
@retval EFI_INVALID_PARAMETER HelpText is NULL
@retval EFI_NOT_FOUND There is no help text available for Command.
**/
EFI_STATUS
EFIAPI
EfiShellGetHelpText(
IN CONST CHAR16 *Command,
IN CONST CHAR16 *Sections OPTIONAL,
OUT CHAR16 **HelpText
);
/**
Gets the enable status of the page break output mode.
User can use this function to determine current page break mode.
@retval TRUE The page break output mode is enabled
@retval FALSE The page break output mode is disabled
**/
BOOLEAN
EFIAPI
EfiShellGetPageBreak(
VOID
);
/**
Judges whether the active shell is the root shell.
This function makes the user to know that whether the active Shell is the root shell.
@retval TRUE The active Shell is the root Shell.
@retval FALSE The active Shell is NOT the root Shell.
**/
BOOLEAN
EFIAPI
EfiShellIsRootShell(
VOID
);
/**
This function returns the command associated with a alias or a list of all
alias'.
@param[in] Command Points to the NULL-terminated shell alias.
If this parameter is NULL, then all
aliases will be returned in ReturnedData.
@param[out] Volatile upon return of a single command if TRUE indicates
this is stored in a volatile fashion. FALSE otherwise.
@return If Alias is not NULL, it will return a pointer to
the NULL-terminated command for that alias.
If Alias is NULL, ReturnedData points to a ';'
delimited list of alias (e.g.
ReturnedData = "dir;del;copy;mfp") that is NULL-terminated.
@retval NULL an error ocurred
@retval NULL Alias was not a valid Alias
**/
CONST CHAR16 *
EFIAPI
EfiShellGetAlias(
IN CONST CHAR16 *Command,
OUT BOOLEAN *Volatile OPTIONAL
);
/**
Changes a shell command alias.
This function creates an alias for a shell command or if Alias is NULL it will delete an existing alias.
this function does not check for built in alias'.
@param[in] Command Points to the NULL-terminated shell command or existing alias.
@param[in] Alias Points to the NULL-terminated alias for the shell command. If this is NULL, and
Command refers to an alias, that alias will be deleted.
@param[in] Volatile if TRUE the Alias being set will be stored in a volatile fashion. if FALSE the
Alias being set will be stored in a non-volatile fashion.
@retval EFI_SUCCESS Alias created or deleted successfully.
@retval EFI_NOT_FOUND the Alias intended to be deleted was not found
**/
EFI_STATUS
EFIAPI
InternalSetAlias(
IN CONST CHAR16 *Command,
IN CONST CHAR16 *Alias OPTIONAL,
IN BOOLEAN Volatile
);
/**
Changes a shell command alias.
This function creates an alias for a shell command or if Alias is NULL it will delete an existing alias.
@param[in] Command Points to the NULL-terminated shell command or existing alias.
@param[in] Alias Points to the NULL-terminated alias for the shell command. If this is NULL, and
Command refers to an alias, that alias will be deleted.
@param[in] Replace If TRUE and the alias already exists, then the existing alias will be replaced. If
FALSE and the alias already exists, then the existing alias is unchanged and
EFI_ACCESS_DENIED is returned.
@param[in] Volatile if TRUE the Alias being set will be stored in a volatile fashion. if FALSE the
Alias being set will be stored in a non-volatile fashion.
@retval EFI_SUCCESS Alias created or deleted successfully.
@retval EFI_NOT_FOUND the Alias intended to be deleted was not found
@retval EFI_ACCESS_DENIED The alias is a built-in alias or already existed and Replace was set to
FALSE.
**/
EFI_STATUS
EFIAPI
EfiShellSetAlias(
IN CONST CHAR16 *Command,
IN CONST CHAR16 *Alias OPTIONAL,
IN BOOLEAN Replace,
IN BOOLEAN Volatile
);
/**
Utility cleanup function for EFI_SHELL_FILE_INFO objects.
1) frees all pointers (non-NULL)
2) Closes the SHELL_FILE_HANDLE
@param FileListNode pointer to the list node to free
**/
VOID
EFIAPI
InternalFreeShellFileInfoNode(
IN EFI_SHELL_FILE_INFO *FileListNode
);
/**
Internal variable setting function. Allows for setting of the read only variables.
@param Name Points to the NULL-terminated environment variable name.
@param Value Points to the NULL-terminated environment variable value. If the value is an
empty string then the environment variable is deleted.
@param Volatile Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE).
@retval EFI_SUCCESS The environment variable was successfully updated.
**/
EFI_STATUS
EFIAPI
InternalEfiShellSetEnv(
IN CONST CHAR16 *Name,
IN CONST CHAR16 *Value,
IN BOOLEAN Volatile
);
#endif //_SHELL_PROTOCOL_HEADER_