\r
Status = ConsoleLoggerResetBuffers(*ConsoleInfo);\r
if (EFI_ERROR(Status)) {\r
+ SHELL_FREE_NON_NULL((*ConsoleInfo));\r
+ *ConsoleInfo = NULL;\r
return (Status);\r
}\r
\r
Status = gBS->InstallProtocolInterface(&gImageHandle, &gEfiSimpleTextOutProtocolGuid, EFI_NATIVE_INTERFACE, (VOID*)&((*ConsoleInfo)->OurConOut));\r
+ if (EFI_ERROR(Status)) {\r
+ SHELL_FREE_NON_NULL((*ConsoleInfo)->Buffer);\r
+ SHELL_FREE_NON_NULL((*ConsoleInfo)->Attributes);\r
+ SHELL_FREE_NON_NULL((*ConsoleInfo));\r
+ *ConsoleInfo = NULL;\r
+ return (Status);\r
+ }\r
\r
(*ConsoleInfo)->OldConOut = gST->ConOut;\r
(*ConsoleInfo)->OldConHandle = gST->ConsoleOutHandle;\r
--- /dev/null
+/** @file\r
+ Function definitions for shell simple text in and out on top of file handles.\r
+\r
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <ShellBase.h>\r
+\r
+#include "ConsoleWrappers.h"\r
+#include "Shell.h"\r
+\r
+typedef struct {\r
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn;\r
+ SHELL_FILE_HANDLE FileHandle;\r
+ EFI_HANDLE TheHandle;\r
+} SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL;\r
+\r
+typedef struct {\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL SimpleTextOut;\r
+ SHELL_FILE_HANDLE FileHandle;\r
+ EFI_HANDLE TheHandle;\r
+} SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;\r
+\r
+/**\r
+ Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event\r
+ Signal the event if there is key available\r
+\r
+ @param Event Indicates the event that invoke this function.\r
+ @param Context Indicates the calling context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ConInWaitForKey (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ UINT64 Position;\r
+ UINT64 Size;\r
+ //\r
+ // Someone is waiting on the keystroke event, if there's\r
+ // a key pending, signal the event\r
+ //\r
+ // Context is the pointer to EFI_SIMPLE_TEXT_INPUT_PROTOCOL\r
+ //\r
+ ShellInfoObject.NewEfiShellProtocol->GetFilePosition(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Context)->FileHandle, &Position);\r
+ ShellInfoObject.NewEfiShellProtocol->GetFileSize (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Context)->FileHandle, &Size );\r
+ if (Position < Size) {\r
+ gBS->SignalEvent (Event);\r
+ }\r
+}\r
+\r
+/**\r
+ Reset function for the fake simple text input.\r
+\r
+ @param[in] This A pointer to the SimpleTextIn structure.\r
+ @param[in] ExtendedVerification TRUE for extra validation, FALSE otherwise.\r
+\r
+ @retval EFI_SUCCESS The reset was successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextInReset(\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ ReadKeyStroke function for the fake simple text input.\r
+\r
+ @param[in] This A pointer to the SimpleTextIn structure.\r
+ @param[out] Key A pointer to the Key structure to fill.\r
+\r
+ @retval EFI_SUCCESS The read was successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextInReadKeyStroke(\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ IN EFI_INPUT_KEY *Key\r
+ )\r
+{\r
+ UINTN Size;\r
+ Size = sizeof(CHAR16);\r
+ if (Key == NULL || This == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ Key->ScanCode = 0;\r
+ return (ShellInfoObject.NewEfiShellProtocol->ReadFile(\r
+ ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->FileHandle,\r
+ &Size,\r
+ &Key->UnicodeChar));\r
+}\r
+\r
+/**\r
+ Function to create a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a \r
+ SHELL_FILE_HANDLE to support redirecting input from a file.\r
+\r
+ @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.\r
+ @param[in] HandleLocation The pointer of a location to copy handle with protocol to.\r
+\r
+ @retval NULL There was insufficient memory available.\r
+ @return A pointer to the allocated protocol structure;\r
+**/\r
+EFI_SIMPLE_TEXT_INPUT_PROTOCOL*\r
+EFIAPI\r
+CreateSimpleTextInOnFile(\r
+ IN SHELL_FILE_HANDLE FileHandleToUse,\r
+ IN EFI_HANDLE *HandleLocation\r
+ )\r
+{\r
+ SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ProtocolToReturn;\r
+ EFI_STATUS Status;\r
+\r
+ if (HandleLocation == NULL || FileHandleToUse == NULL) {\r
+ return (NULL);\r
+ }\r
+\r
+ ProtocolToReturn = AllocateZeroPool(sizeof(SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL));\r
+ if (ProtocolToReturn == NULL) {\r
+ return (NULL);\r
+ }\r
+ ProtocolToReturn->FileHandle = FileHandleToUse;\r
+ ProtocolToReturn->SimpleTextIn.Reset = FileBasedSimpleTextInReset;\r
+ ProtocolToReturn->SimpleTextIn.ReadKeyStroke = FileBasedSimpleTextInReadKeyStroke;\r
+ \r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_NOTIFY,\r
+ ConInWaitForKey,\r
+ &ProtocolToReturn->SimpleTextIn,\r
+ &ProtocolToReturn->SimpleTextIn.WaitForKey\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ FreePool(ProtocolToReturn);\r
+ return (NULL);\r
+ }\r
+ ///@todo possibly also install SimpleTextInputEx on the handle at this point.\r
+ Status = gBS->InstallProtocolInterface(\r
+ &(ProtocolToReturn->TheHandle), \r
+ &gEfiSimpleTextInProtocolGuid, \r
+ EFI_NATIVE_INTERFACE, \r
+ &(ProtocolToReturn->SimpleTextIn));\r
+ if (!EFI_ERROR(Status)) {\r
+ *HandleLocation = ProtocolToReturn->TheHandle;\r
+ return ((EFI_SIMPLE_TEXT_INPUT_PROTOCOL*)ProtocolToReturn);\r
+ } else {\r
+ FreePool(ProtocolToReturn);\r
+ return (NULL);\r
+ }\r
+}\r
+\r
+/**\r
+ Function to close a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a \r
+ SHELL_FILE_HANDLE to support redirecting input from a file.\r
+\r
+ @param[in] SimpleTextIn The pointer to the SimpleTextIn to close.\r
+\r
+ @retval EFI_SUCCESS The object was closed.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CloseSimpleTextInOnFile(\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTextIn\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS Status1;\r
+\r
+ if (SimpleTextIn == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
+ Status = gBS->CloseEvent(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)SimpleTextIn)->SimpleTextIn.WaitForKey);\r
+\r
+ Status1 = gBS->UninstallProtocolInterface(\r
+ ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL*)SimpleTextIn)->TheHandle, \r
+ &gEfiSimpleTextInProtocolGuid, \r
+ &(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL*)SimpleTextIn)->SimpleTextIn));\r
+\r
+ FreePool(SimpleTextIn);\r
+ if (!EFI_ERROR(Status)) {\r
+ return (Status1);\r
+ } else {\r
+ return (Status);\r
+ }\r
+}\r
+\r
+/**\r
+ Reset the text output device hardware and optionaly run diagnostics.\r
+\r
+ @param This pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL\r
+ @param ExtendedVerification Indicates that a more extensive test may be performed\r
+\r
+ @retval EFI_SUCCESS The text output device was reset.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutReset (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Verifies that all characters in a Unicode string can be output to the\r
+ target device.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] WString The NULL-terminated Unicode string to be examined.\r
+\r
+ @retval EFI_SUCCESS The device(s) are capable of rendering the output string.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutTestString (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
+ IN CHAR16 *WString\r
+ )\r
+{\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Returns information for an available text mode that the output device(s)\r
+ supports.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] ModeNumber The mode number to return information on.\r
+ @param[out] Columns Upon return, the number of columns in the selected geometry\r
+ @param[out] Rows Upon return, the number of rows in the selected geometry\r
+\r
+ @retval EFI_UNSUPPORTED The mode number was not valid.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutQueryMode (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
+ IN UINTN ModeNumber,\r
+ OUT UINTN *Columns,\r
+ OUT UINTN *Rows\r
+ )\r
+{\r
+ return (EFI_UNSUPPORTED);\r
+}\r
+\r
+/**\r
+ Sets the output device(s) to a specified mode.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] ModeNumber The mode number to set.\r
+\r
+ @retval EFI_UNSUPPORTED The mode number was not valid.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutSetMode (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
+ IN UINTN ModeNumber\r
+ )\r
+{\r
+ return (EFI_UNSUPPORTED);\r
+}\r
+\r
+/**\r
+ Sets the background and foreground colors for the OutputString () and\r
+ ClearScreen () functions.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] Attribute The attribute to set. Bits 0..3 are the foreground color, and\r
+ bits 4..6 are the background color. All other bits are undefined\r
+ and must be zero. The valid Attributes are defined in this file.\r
+\r
+ @retval EFI_SUCCESS The attribute was set.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutSetAttribute (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
+ IN UINTN Attribute\r
+ )\r
+{\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Clears the output device(s) display to the currently selected background\r
+ color.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+\r
+ @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutClearScreen (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
+ )\r
+{\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Sets the current coordinates of the cursor position\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] Column Column to put the cursor in. Must be between zero and Column returned from QueryMode\r
+ @param[in] Row Row to put the cursor in. Must be between zero and Row returned from QueryMode\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutSetCursorPosition (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
+ IN UINTN Column,\r
+ IN UINTN Row\r
+ )\r
+{\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Makes the cursor visible or invisible\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is\r
+ set to be invisible.\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutEnableCursor (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
+ IN BOOLEAN Visible\r
+ )\r
+{\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Write a Unicode string to the output device.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] WString The NULL-terminated Unicode string to be displayed on the output\r
+ device(s). All output devices must also support the Unicode\r
+ drawing defined in this file.\r
+ @retval EFI_SUCCESS The string was output to the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
+ the text.\r
+ @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
+ defined text mode.\r
+ @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
+ characters in the Unicode string could not be\r
+ rendered and were skipped.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileBasedSimpleTextOutOutputString (\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
+ IN CHAR16 *WString\r
+ )\r
+{\r
+ UINTN Size;\r
+ Size = StrLen(WString) * sizeof(CHAR16);\r
+ return (ShellInfoObject.NewEfiShellProtocol->WriteFile(\r
+ ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->FileHandle,\r
+ &Size,\r
+ WString));\r
+}\r
+\r
+/**\r
+ Function to create a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a \r
+ SHELL_FILE_HANDLE to support redirecting output from a file.\r
+\r
+ @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.\r
+ @param[in] HandleLocation The pointer of a location to copy handle with protocol to.\r
+\r
+ @retval NULL There was insufficient memory available.\r
+ @return A pointer to the allocated protocol structure;\r
+**/\r
+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*\r
+EFIAPI\r
+CreateSimpleTextOutOnFile(\r
+ IN SHELL_FILE_HANDLE FileHandleToUse,\r
+ IN EFI_HANDLE *HandleLocation\r
+ )\r
+{\r
+ SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ProtocolToReturn;\r
+ EFI_STATUS Status;\r
+\r
+ if (HandleLocation == NULL || FileHandleToUse == NULL) {\r
+ return (NULL);\r
+ }\r
+\r
+ ProtocolToReturn = AllocateZeroPool(sizeof(SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL));\r
+ if (ProtocolToReturn == NULL) {\r
+ return (NULL);\r
+ }\r
+ ProtocolToReturn->FileHandle = FileHandleToUse;\r
+ ProtocolToReturn->SimpleTextOut.Reset = FileBasedSimpleTextOutReset;\r
+ ProtocolToReturn->SimpleTextOut.TestString = FileBasedSimpleTextOutTestString;\r
+ ProtocolToReturn->SimpleTextOut.QueryMode = FileBasedSimpleTextOutQueryMode;\r
+ ProtocolToReturn->SimpleTextOut.SetMode = FileBasedSimpleTextOutSetMode;\r
+ ProtocolToReturn->SimpleTextOut.SetAttribute = FileBasedSimpleTextOutSetAttribute;\r
+ ProtocolToReturn->SimpleTextOut.ClearScreen = FileBasedSimpleTextOutClearScreen;\r
+ ProtocolToReturn->SimpleTextOut.SetCursorPosition = FileBasedSimpleTextOutSetCursorPosition;\r
+ ProtocolToReturn->SimpleTextOut.EnableCursor = FileBasedSimpleTextOutEnableCursor;\r
+ ProtocolToReturn->SimpleTextOut.OutputString = FileBasedSimpleTextOutOutputString;\r
+ ProtocolToReturn->SimpleTextOut.Mode = AllocateZeroPool(sizeof(EFI_SIMPLE_TEXT_OUTPUT_MODE));\r
+ if (ProtocolToReturn->SimpleTextOut.Mode == NULL) {\r
+ FreePool(ProtocolToReturn);\r
+ return (NULL);\r
+ }\r
+ ProtocolToReturn->SimpleTextOut.Mode->MaxMode = 0;\r
+ ProtocolToReturn->SimpleTextOut.Mode->Mode = 0;\r
+ ProtocolToReturn->SimpleTextOut.Mode->Attribute = 0;\r
+ ProtocolToReturn->SimpleTextOut.Mode->CursorColumn = 0;\r
+ ProtocolToReturn->SimpleTextOut.Mode->CursorRow = 0;\r
+ ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = FALSE;\r
+\r
+ Status = gBS->InstallProtocolInterface(\r
+ &(ProtocolToReturn->TheHandle), \r
+ &gEfiSimpleTextOutProtocolGuid, \r
+ EFI_NATIVE_INTERFACE, \r
+ &(ProtocolToReturn->SimpleTextOut));\r
+ if (!EFI_ERROR(Status)) {\r
+ *HandleLocation = ProtocolToReturn->TheHandle;\r
+ return ((EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)ProtocolToReturn);\r
+ } else {\r
+ FreePool(ProtocolToReturn);\r
+ return (NULL);\r
+ }\r
+}\r
+\r
+/**\r
+ Function to close a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a \r
+ SHELL_FILE_HANDLE to support redirecting output from a file.\r
+\r
+ @param[in] SimpleTextOut The pointer to the SimpleTextOUT to close.\r
+\r
+ @retval EFI_SUCCESS The object was closed.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CloseSimpleTextOutOnFile(\r
+ OUT EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ if (SimpleTextOut == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ Status = gBS->UninstallProtocolInterface(\r
+ ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)SimpleTextOut)->TheHandle, \r
+ &gEfiSimpleTextOutProtocolGuid, \r
+ &(((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)SimpleTextOut)->SimpleTextOut));\r
+ FreePool(SimpleTextOut);\r
+ return (Status);\r
+}\r
--- /dev/null
+/** @file\r
+ Function definitions for shell simple text in and out on top of file handles.\r
+\r
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _SHELL_CONSOLE_WRAPPERS_HEADER_\r
+#define _SHELL_CONSOLE_WRAPPERS_HEADER_\r
+\r
+/**\r
+ Function to create a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a \r
+ SHELL_FILE_HANDLE to support redirecting input from a file.\r
+\r
+ @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.\r
+ @param[in] HandleLocation The pointer of a location to copy handle with protocol to.\r
+\r
+ @retval NULL There was insufficient memory available.\r
+ @return A pointer to the allocated protocol structure;\r
+**/\r
+EFI_SIMPLE_TEXT_INPUT_PROTOCOL*\r
+EFIAPI\r
+CreateSimpleTextInOnFile(\r
+ IN SHELL_FILE_HANDLE FileHandleToUse,\r
+ IN EFI_HANDLE *HandleLocation\r
+ );\r
+\r
+/**\r
+ Function to close a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a \r
+ SHELL_FILE_HANDLE to support redirecting input from a file.\r
+\r
+ @param[in] SimpleTextIn The pointer to the SimpleTextIn to close.\r
+\r
+ @retval EFI_SUCCESS The object was closed.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CloseSimpleTextInOnFile(\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTextIn\r
+ );\r
+\r
+/**\r
+ Function to create a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a \r
+ SHELL_FILE_HANDLE to support redirecting output from a file.\r
+\r
+ @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.\r
+ @param[in] HandleLocation The pointer of a location to copy handle with protocol to.\r
+\r
+ @retval NULL There was insufficient memory available.\r
+ @return A pointer to the allocated protocol structure;\r
+**/\r
+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*\r
+EFIAPI\r
+CreateSimpleTextOutOnFile(\r
+ IN SHELL_FILE_HANDLE FileHandleToUse,\r
+ IN EFI_HANDLE *HandleLocation\r
+ );\r
+\r
+/**\r
+ Function to close a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a \r
+ SHELL_FILE_HANDLE to support redirecting output from a file.\r
+\r
+ @param[in] SimpleTextOut The pointer to the SimpleTextOUT to close.\r
+\r
+ @retval EFI_SUCCESS The object was closed.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CloseSimpleTextOutOnFile(\r
+ OUT EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut\r
+ );\r
+\r
+#endif //_SHELL_CONSOLE_WRAPPERS_HEADER_\r
+\r
NULL,\r
{0,0,NULL,NULL},\r
{0,0},\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
};\r
\r
STATIC CONST CHAR16 mScriptExtension[] = L".NSH";\r
//\r
// Set up the event for CTRL-C monitoring...\r
//\r
-\r
- ///@todo add support for using SimpleInputEx here\r
- // if SimpleInputEx is not available display a warning.\r
+ Status = InernalEfiShellStartMonitor();\r
}\r
\r
if (!EFI_ERROR(Status) && PcdGet8(PcdShellSupportLevel) >= 1) {\r
ShellInfoObject.ConsoleInfo->Enabled = TRUE;\r
ShellInfoObject.ConsoleInfo->RowCounter = 0;\r
\r
+ //\r
+ // Reset the CTRL-C event (yes we ignore the return values)\r
+ //\r
+ Status = gBS->CheckEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);\r
+\r
//\r
// Display Prompt\r
//\r
gBS->CloseEvent(ShellInfoObject.UserBreakTimer);\r
DEBUG_CODE(ShellInfoObject.UserBreakTimer = NULL;);\r
}\r
-\r
- if (ShellInfoObject.NewEfiShellProtocol->IsRootShell()){\r
- ShellInfoObject.NewEfiShellProtocol->SetEnv(L"cwd", L"", TRUE);\r
- }\r
-\r
if (ShellInfoObject.ImageDevPath != NULL) {\r
FreePool(ShellInfoObject.ImageDevPath);\r
DEBUG_CODE(ShellInfoObject.ImageDevPath = NULL;);\r
DEBUG_CODE(ShellInfoObject.NewShellParametersProtocol = NULL;);\r
}\r
if (ShellInfoObject.NewEfiShellProtocol != NULL){\r
+ if (ShellInfoObject.NewEfiShellProtocol->IsRootShell()){\r
+ ShellInfoObject.NewEfiShellProtocol->SetEnv(L"cwd", L"", TRUE);\r
+ }\r
CleanUpShellProtocol(ShellInfoObject.NewEfiShellProtocol);\r
DEBUG_CODE(ShellInfoObject.NewEfiShellProtocol = NULL;);\r
}\r
SHELL_FILE_HANDLE OriginalStdIn;\r
SHELL_FILE_HANDLE OriginalStdOut;\r
SHELL_FILE_HANDLE OriginalStdErr;\r
+ SYSTEM_TABLE_INFO OriginalSystemTableInfo;\r
CHAR16 *TempLocation3;\r
UINTN Count;\r
UINTN Count2;\r
\r
\r
\r
- Status = UpdateStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr);\r
+ Status = UpdateStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);\r
if (EFI_ERROR(Status)) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);\r
} else {\r
\r
RestoreArgcArgv(ShellInfoObject.NewShellParametersProtocol, &Argv, &Argc);\r
\r
- RestoreStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr);\r
+ RestoreStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);\r
}\r
if (CommandName != NULL) {\r
if (ShellCommandGetCurrentScriptFile() != NULL && !IsScriptOnlyCommand(CommandName)) {\r
EFI_SHELL_PARAMETERS_PROTOCOL *OldShellParameters; ///< old shell parameters to reinstall upon exiting.\r
SHELL_PROTOCOL_HANDLE_LIST OldShellList; ///< List of other instances to reinstall when closing.\r
SPLIT_LIST SplitList; ///< List of Splits in FILO stack.\r
+ EFI_HANDLE CtrlCNotifyHandle1; ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.\r
+ EFI_HANDLE CtrlCNotifyHandle2; ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.\r
+ EFI_HANDLE CtrlCNotifyHandle3; ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.\r
+ EFI_HANDLE CtrlCNotifyHandle4; ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.\r
} SHELL_INFO;\r
\r
extern SHELL_INFO ShellInfoObject;\r
Shell.uni\r
ConsoleLogger.c\r
ConsoleLogger.h\r
+ ConsoleWrappers.c\r
+ ConsoleWrappers.h\r
\r
[Packages]\r
MdePkg/MdePkg.dec\r
\r
[Protocols]\r
gEfiShellProtocolGuid # ALWAYS_PRODUCED\r
+ # SOMETIMES_CONSUMED\r
gEfiShellParametersProtocolGuid # ALWAYS_PRODUCED\r
- gEfiShellEnvironment2Guid # SOMETIMES_PRODUCED\r
- gEfiShellInterfaceGuid # SOMETIMES_PRODUCED\r
+ # SOMETIMES_CONSUMED\r
+\r
+# gEfiShellEnvironment2Guid # SOMETIMES_PRODUCED\r
+# gEfiShellInterfaceGuid # SOMETIMES_PRODUCED\r
\r
gEfiLoadedImageProtocolGuid # ALWAYS_CONSUMED\r
gEfiSimpleTextInputExProtocolGuid # ALWAYS_CONSUMED\r
+ gEfiSimpleTextInProtocolGuid # ALWAYS_CONSUMED\r
gEfiSimpleTextOutProtocolGuid # ALWAYS_CONSUMED\r
gEfiSimpleFileSystemProtocolGuid # ALWAYS_CONSUMED\r
gEfiLoadedImageProtocolGuid # ALWAYS_CONSUMED\r
**/\r
\r
#include <Uefi.h>\r
+#include <ShellBase.h>\r
\r
#include <Guid/ShellVariableGuid.h>\r
\r
\r
#include "ShellEnvVar.h"\r
\r
-\r
/**\r
Reports whether an environment variable is Volatile or Non-Volatile.\r
\r
}\r
if (!EFI_ERROR(Status) && CompareGuid(&Guid, &gShellVariableGuid)){\r
VarList = AllocateZeroPool(sizeof(ENV_VAR_LIST));\r
- ValSize = 0;\r
- Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);\r
- if (Status == EFI_BUFFER_TOO_SMALL){\r
- VarList->Val = AllocatePool(ValSize);\r
- ASSERT(VarList->Val != NULL);\r
+ if (VarList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ ValSize = 0;\r
Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);\r
- }\r
- if (!EFI_ERROR(Status)) {\r
- VarList->Key = AllocatePool(StrSize(VariableName));\r
- ASSERT(VarList->Key != NULL);\r
- StrCpy(VarList->Key, VariableName);\r
- InsertTailList(ListHead, &VarList->Link);\r
+ if (Status == EFI_BUFFER_TOO_SMALL){\r
+ VarList->Val = AllocatePool(ValSize);\r
+ if (VarList->Val == NULL) {\r
+ SHELL_FREE_NON_NULL(VarList);\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(VariableName, &VarList->Atts, &ValSize, VarList->Val);\r
+ }\r
+ }\r
+ if (!EFI_ERROR(Status)) {\r
+ VarList->Key = AllocatePool(StrSize(VariableName));\r
+ if (VarList->Key == NULL) {\r
+ SHELL_FREE_NON_NULL(VarList->Val);\r
+ SHELL_FREE_NON_NULL(VarList);\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ StrCpy(VarList->Key, VariableName);\r
+ InsertTailList(ListHead, &VarList->Link);\r
+ }\r
+ }\r
}\r
} // compare guid\r
} // while\r
**/\r
\r
#include "ShellParametersProtocol.h"\r
+#include "ConsoleWrappers.h"\r
\r
/**\r
return the next parameter from a command line string;\r
structure by parsing NewCommandLine. The current values are returned to the\r
user.\r
\r
- If OldStdIn or OldStdOut is NULL then that value is not returned.\r
+ This will also update the system table.\r
\r
@param[in,out] ShellParameters Pointer to parameter structure to modify.\r
@param[in] NewCommandLine The new command line to parse and use.\r
@param[out] OldStdIn Pointer to old StdIn.\r
@param[out] OldStdOut Pointer to old StdOut.\r
@param[out] OldStdErr Pointer to old StdErr.\r
+ @param[out] SystemTableInfo Pointer to old system table information.\r
\r
@retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.\r
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
IN CONST CHAR16 *NewCommandLine,\r
OUT SHELL_FILE_HANDLE *OldStdIn,\r
OUT SHELL_FILE_HANDLE *OldStdOut,\r
- OUT SHELL_FILE_HANDLE *OldStdErr\r
+ OUT SHELL_FILE_HANDLE *OldStdErr,\r
+ OUT SYSTEM_TABLE_INFO *SystemTableInfo\r
)\r
{\r
CHAR16 *CommandLineCopy;\r
CHAR16 TagBuffer[2];\r
SPLIT_LIST *Split;\r
\r
- ASSERT(ShellParameters != NULL);\r
OutUnicode = TRUE;\r
InUnicode = TRUE;\r
ErrUnicode = TRUE;\r
OutAppend = FALSE;\r
CommandLineCopy = NULL;\r
\r
- if (OldStdIn != NULL) {\r
- *OldStdIn = ShellParameters->StdIn;\r
- }\r
- if (OldStdOut != NULL) {\r
- *OldStdOut = ShellParameters->StdOut;\r
- }\r
- if (OldStdErr != NULL) {\r
- *OldStdErr = ShellParameters->StdErr;\r
+ if (ShellParameters == NULL || SystemTableInfo == NULL || OldStdIn == NULL || OldStdOut == NULL || OldStdErr == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
}\r
\r
+ SystemTableInfo->ConIn = gST->ConIn;\r
+ SystemTableInfo->ConInHandle = gST->ConsoleInHandle;\r
+ SystemTableInfo->ConOut = gST->ConOut;\r
+ SystemTableInfo->ConOutHandle = gST->ConsoleOutHandle;\r
+ SystemTableInfo->ConErr = gST->StdErr;\r
+ SystemTableInfo->ConErrHandle = gST->StandardErrorHandle;\r
+ *OldStdIn = ShellParameters->StdIn;\r
+ *OldStdOut = ShellParameters->StdOut;\r
+ *OldStdErr = ShellParameters->StdErr;\r
+\r
if (NewCommandLine == NULL) {\r
return (EFI_SUCCESS);\r
}\r
}\r
if (!EFI_ERROR(Status)) {\r
ShellParameters->StdErr = TempHandle;\r
+ gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);\r
}\r
}\r
\r
}\r
if (!EFI_ERROR(Status)) {\r
ShellParameters->StdOut = TempHandle;\r
+ gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);\r
}\r
}\r
}\r
ASSERT(TempHandle != NULL);\r
}\r
ShellParameters->StdOut = TempHandle;\r
+ gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);\r
}\r
\r
//\r
ASSERT(TempHandle != NULL);\r
}\r
ShellParameters->StdErr = TempHandle;\r
+ gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);\r
}\r
\r
//\r
Status = EFI_INVALID_PARAMETER;\r
} else {\r
ShellParameters->StdIn = TempHandle;\r
+ gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);\r
}\r
}\r
\r
}\r
if (!EFI_ERROR(Status)) {\r
ShellParameters->StdIn = TempHandle;\r
+ gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);\r
}\r
}\r
}\r
}\r
FreePool(CommandLineCopy);\r
+\r
+ if (gST->ConIn == NULL ||gST->ConOut == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
return (Status);\r
}\r
\r
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol\r
structure with StdIn and StdOut. The current values are de-allocated.\r
\r
- @param[in,out] ShellParameters pointer to parameter structure to modify\r
- @param[out] OldStdIn Pointer to old StdIn.\r
- @param[out] OldStdOut Pointer to old StdOut.\r
- @param[out] OldStdErr Pointer to old StdErr.\r
+ @param[in,out] ShellParameters Pointer to parameter structure to modify.\r
+ @param[in] OldStdIn Pointer to old StdIn.\r
+ @param[in] OldStdOut Pointer to old StdOut.\r
+ @param[in] OldStdErr Pointer to old StdErr.\r
+ @param[in] SystemTableInfo Pointer to old system table information.\r
**/\r
EFI_STATUS\r
EFIAPI\r
RestoreStdInStdOutStdErr (\r
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
- OUT SHELL_FILE_HANDLE *OldStdIn OPTIONAL,\r
- OUT SHELL_FILE_HANDLE *OldStdOut OPTIONAL,\r
- OUT SHELL_FILE_HANDLE *OldStdErr OPTIONAL\r
+ IN SHELL_FILE_HANDLE *OldStdIn,\r
+ IN SHELL_FILE_HANDLE *OldStdOut,\r
+ IN SHELL_FILE_HANDLE *OldStdErr,\r
+ IN SYSTEM_TABLE_INFO *SystemTableInfo\r
)\r
{\r
SPLIT_LIST *Split;\r
+\r
+ if (ShellParameters == NULL \r
+ ||OldStdIn == NULL\r
+ ||OldStdOut == NULL\r
+ ||OldStdErr == NULL\r
+ ||SystemTableInfo == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {\r
Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);\r
} else {\r
Split = NULL;\r
}\r
- if (OldStdIn != NULL && ShellParameters->StdIn != *OldStdIn) {\r
+ if (ShellParameters->StdIn != *OldStdIn) {\r
if ((Split != NULL && Split->SplitStdIn != ShellParameters->StdIn) || Split == NULL) {\r
gEfiShellProtocol->CloseFile(ShellParameters->StdIn);\r
}\r
- ShellParameters->StdIn = OldStdIn==NULL?NULL:*OldStdIn;\r
+ ShellParameters->StdIn = *OldStdIn;\r
}\r
- if (OldStdOut != NULL && ShellParameters->StdOut != *OldStdOut) {\r
+ if (ShellParameters->StdOut != *OldStdOut) {\r
if ((Split != NULL && Split->SplitStdOut != ShellParameters->StdOut) || Split == NULL) {\r
gEfiShellProtocol->CloseFile(ShellParameters->StdOut);\r
}\r
- ShellParameters->StdOut = OldStdOut==NULL?NULL:*OldStdOut;\r
+ ShellParameters->StdOut = *OldStdOut;\r
+ }\r
+ if (ShellParameters->StdErr != *OldStdErr) {\r
+ gEfiShellProtocol->CloseFile(ShellParameters->StdErr);\r
+ ShellParameters->StdErr = *OldStdErr;\r
+ }\r
+\r
+ if (gST->ConIn != SystemTableInfo->ConIn) {\r
+ CloseSimpleTextInOnFile(gST->ConIn);\r
+ gST->ConIn = SystemTableInfo->ConIn;\r
+ gST->ConsoleInHandle = SystemTableInfo->ConInHandle;\r
+ }\r
+ if (gST->ConOut != SystemTableInfo->ConOut) {\r
+ CloseSimpleTextOutOnFile(gST->ConOut);\r
+ gST->ConOut = SystemTableInfo->ConOut;\r
+ gST->ConsoleOutHandle = SystemTableInfo->ConOutHandle;\r
}\r
+ if (gST->StdErr != SystemTableInfo->ConErr) {\r
+ CloseSimpleTextOutOnFile(gST->StdErr);\r
+ gST->StdErr = SystemTableInfo->ConErr;\r
+ gST->StandardErrorHandle = SystemTableInfo->ConErrHandle;\r
+ }\r
+\r
return (EFI_SUCCESS);\r
}\r
/**\r
#include <Protocol/SimpleFileSystem.h>\r
#include <Protocol/EfiShellParameters.h>\r
#include <Protocol/LoadedImage.h>\r
+#include <Protocol/SimpleTextOut.h>\r
+#include <Protocol/SimpleTextIn.h>\r
\r
#include <Guid/ShellVariableGuid.h>\r
\r
IN UINTN *OldArgc\r
);\r
\r
+typedef struct {\r
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;\r
+ EFI_HANDLE ConInHandle;\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;\r
+ EFI_HANDLE ConOutHandle;\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConErr;\r
+ EFI_HANDLE ConErrHandle;\r
+} SYSTEM_TABLE_INFO;\r
+\r
/**\r
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol\r
structure by parsing NewCommandLine. The current values are returned to the\r
@param[out] OldStdIn Pointer to old StdIn.\r
@param[out] OldStdOut Pointer to old StdOut.\r
@param[out] OldStdErr Pointer to old StdErr.\r
+ @param[out] SystemTableInfo Pointer to old system table information.\r
\r
@retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.\r
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
UpdateStdInStdOutStdErr(\r
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
IN CONST CHAR16 *NewCommandLine,\r
- OUT SHELL_FILE_HANDLE *OldStdIn OPTIONAL,\r
- OUT SHELL_FILE_HANDLE *OldStdOut OPTIONAL,\r
- OUT SHELL_FILE_HANDLE *OldStdErr OPTIONAL\r
+ OUT SHELL_FILE_HANDLE *OldStdIn,\r
+ OUT SHELL_FILE_HANDLE *OldStdOut,\r
+ OUT SHELL_FILE_HANDLE *OldStdErr,\r
+ OUT SYSTEM_TABLE_INFO *SystemTableInfo\r
);\r
\r
/**\r
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol\r
structure with StdIn and StdOut. The current values are de-allocated.\r
\r
- @param[in,out] ShellParameters pointer to parameter structure to modify\r
- @param[out] OldStdIn Pointer to old StdIn.\r
- @param[out] OldStdOut Pointer to old StdOut.\r
- @param[out] OldStdErr Pointer to old StdErr.\r
+ @param[in,out] ShellParameters Pointer to parameter structure to modify.\r
+ @param[in] OldStdIn Pointer to old StdIn.\r
+ @param[in] OldStdOut Pointer to old StdOut.\r
+ @param[in] OldStdErr Pointer to old StdErr.\r
+ @param[in] SystemTableInfo Pointer to old system table information.\r
**/\r
EFI_STATUS\r
EFIAPI\r
RestoreStdInStdOutStdErr (\r
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
- OUT SHELL_FILE_HANDLE *OldStdIn OPTIONAL,\r
- OUT SHELL_FILE_HANDLE *OldStdOut OPTIONAL,\r
- OUT SHELL_FILE_HANDLE *OldStdErr OPTIONAL\r
+ IN SHELL_FILE_HANDLE *OldStdIn,\r
+ IN SHELL_FILE_HANDLE *OldStdOut,\r
+ IN SHELL_FILE_HANDLE *OldStdErr,\r
+ IN SYSTEM_TABLE_INFO *SystemTableInfo\r
);\r
\r
/**\r
)\r
{\r
ShellFileHandleRemove(FileHandle);\r
- return (FileHandleClose(FileHandle));\r
+ return (FileHandleClose(ConvertShellHandleToEfiFileProtocol(FileHandle)));\r
}\r
\r
/**\r
EFI_HANDLE Handle;\r
EFI_STATUS Status;\r
\r
+ if (Path == NULL) {\r
+ return (NULL);\r
+ }\r
+\r
MapName = NULL;\r
- ASSERT(Path != NULL);\r
+ NewPath = NULL;\r
\r
if (StrStr(Path, L":") == NULL) {\r
Cwd = EfiShellGetCurDir(NULL);\r
NewPath = AllocateZeroPool(Size);\r
ASSERT(NewPath != NULL);\r
StrCpy(NewPath, Cwd);\r
- if ((NewPath[0] == (CHAR16)L'\\') &&\r
+ if ((Path[0] == (CHAR16)L'\\') &&\r
(NewPath[StrLen(NewPath)-1] == (CHAR16)L'\\')\r
) {\r
((CHAR16*)NewPath)[StrLen(NewPath)-1] = CHAR_NULL;\r
could not be opened.\r
@retval EFI_VOLUME_CORRUPTED The data structures in the volume were corrupted.\r
@retval EFI_DEVICE_ERROR The device had an error\r
+ @retval EFI_INVALID_PARAMETER FileHandle is NULL.\r
**/\r
EFI_STATUS\r
EFIAPI\r
EFI_STATUS Status;\r
EFI_HANDLE Handle;\r
\r
+ if (FileHandle == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
//\r
// find the handle of the device with that device handle and the file system\r
//\r
EFI_FILE_PROTOCOL *Handle1;\r
EFI_FILE_PROTOCOL *Handle2;\r
EFI_DEVICE_PATH_PROTOCOL *DpCopy;\r
+ FILEPATH_DEVICE_PATH *AlignedNode;\r
\r
- ASSERT(FileHandle != NULL);\r
- *FileHandle = NULL;\r
- Handle1 = NULL;\r
- DpCopy = DevicePath;\r
+ if (FileHandle == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ *FileHandle = NULL;\r
+ Handle1 = NULL;\r
+ Handle2 = NULL;\r
+ Handle = NULL;\r
+ DpCopy = DevicePath;\r
+ ShellHandle = NULL;\r
+ FilePathNode = NULL;\r
+ AlignedNode = NULL;\r
\r
Status = EfiShellOpenRoot(DevicePath, &ShellHandle);\r
\r
; !IsDevicePathEnd (&FilePathNode->Header)\r
; FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header)\r
){\r
+ SHELL_FREE_NON_NULL(AlignedNode);\r
+ AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePathNode), FilePathNode);\r
//\r
// For file system access each node should be a file path component\r
//\r
Status = Handle2->Open (\r
Handle2,\r
&Handle1,\r
- FilePathNode->PathName,\r
+ AlignedNode->PathName,\r
OpenMode,\r
Attributes\r
);\r
Status = Handle2->Open (\r
Handle2,\r
&Handle1,\r
- FilePathNode->PathName,\r
+ AlignedNode->PathName,\r
OpenMode &~EFI_FILE_MODE_CREATE,\r
Attributes\r
);\r
Status = Handle2->Open (\r
Handle2,\r
&Handle1,\r
- FilePathNode->PathName,\r
+ AlignedNode->PathName,\r
OpenMode,\r
Attributes\r
);\r
//\r
// Close the last node\r
//\r
- Handle2->Close (Handle2);\r
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Handle2);\r
\r
//\r
// If there's been an error, stop\r
} // for loop\r
}\r
}\r
+ SHELL_FREE_NON_NULL(AlignedNode);\r
if (EFI_ERROR(Status)) {\r
if (Handle1 != NULL) {\r
- Handle1->Close(Handle1);\r
+ ShellInfoObject.NewEfiShellProtocol->CloseFile(Handle1);\r
}\r
} else {\r
*FileHandle = ConvertEfiFileProtocolToShellHandle(Handle1, ShellFileHandleGetPath(ShellHandle));\r
If FileHandle is a file and matches all of the remaining Pattern (which would be\r
on its last node), then add a EFI_SHELL_FILE_INFO object for this file to fileList.\r
\r
- if FileList is NULL, then ASSERT\r
- if FilePattern is NULL, then ASSERT\r
- if UnicodeCollation is NULL, then ASSERT\r
- if FileHandle is NULL, then ASSERT\r
-\r
Upon a EFI_SUCCESS return fromt he function any the caller is responsible to call\r
FreeFileList with FileList.\r
\r
@param[in] FileHandle The FileHandle to start with\r
@param[in,out] FileList pointer to pointer to list of found files.\r
@param[in] ParentNode The node for the parent. Same file as identified by HANDLE.\r
+ @param[in] MapName The file system name this file is on.\r
\r
@retval EFI_SUCCESS all files were found and the FileList contains a list.\r
@retval EFI_NOT_FOUND no files were found\r
IN EFI_UNICODE_COLLATION_PROTOCOL *UnicodeCollation,\r
IN SHELL_FILE_HANDLE FileHandle,\r
IN OUT EFI_SHELL_FILE_INFO **FileList,\r
- IN CONST EFI_SHELL_FILE_INFO *ParentNode OPTIONAL\r
+ IN CONST EFI_SHELL_FILE_INFO *ParentNode OPTIONAL,\r
+ IN CONST CHAR16 *MapName\r
)\r
{\r
EFI_STATUS Status;\r
EFI_SHELL_FILE_INFO *ShellInfoNode;\r
EFI_SHELL_FILE_INFO *NewShellNode;\r
BOOLEAN Directory;\r
+ CHAR16 *NewFullName;\r
+ UINTN Size;\r
\r
if ( FilePattern == NULL\r
|| UnicodeCollation == NULL\r
; ShellInfoNode = (EFI_SHELL_FILE_INFO*)GetNextNode(&ShellInfo->Link, &ShellInfoNode->Link)\r
){\r
if (UnicodeCollation->MetaiMatch(UnicodeCollation, (CHAR16*)ShellInfoNode->FileName, CurrentFilePattern)){\r
- if (Directory){\r
+ if (ShellInfoNode->FullName != NULL && StrStr(ShellInfoNode->FullName, L":") == NULL) {\r
+ Size = StrSize(ShellInfoNode->FullName);\r
+ Size += StrSize(MapName) + sizeof(CHAR16);\r
+ NewFullName = AllocateZeroPool(Size);\r
+ if (NewFullName == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ StrCpy(NewFullName, MapName);\r
+ StrCat(NewFullName, ShellInfoNode->FullName+1);\r
+ FreePool((VOID*)ShellInfoNode->FullName);\r
+ ShellInfoNode->FullName = NewFullName;\r
+ }\r
+ }\r
+ if (Directory && !EFI_ERROR(Status)){\r
//\r
// should be a directory\r
//\r
//\r
// recurse with the next part of the pattern\r
//\r
- Status = ShellSearchHandle(NextFilePatternStart, UnicodeCollation, ShellInfoNode->Handle, FileList, ShellInfoNode);\r
+ Status = ShellSearchHandle(NextFilePatternStart, UnicodeCollation, ShellInfoNode->Handle, FileList, ShellInfoNode, MapName);\r
}\r
- } else {\r
+ } else if (!EFI_ERROR(Status)) {\r
//\r
// should be a file\r
//\r
; *PatternCurrentLocation != ':'\r
; PatternCurrentLocation++);\r
PatternCurrentLocation++;\r
- Status = ShellSearchHandle(PatternCurrentLocation, gUnicodeCollation, RootFileHandle, FileList, NULL);\r
+ Status = ShellSearchHandle(PatternCurrentLocation, gUnicodeCollation, RootFileHandle, FileList, NULL, MapName);\r
}\r
FreePool(RootDevicePath);\r
}\r
}\r
\r
- if (PatternCopy != NULL) {\r
- FreePool(PatternCopy);\r
- }\r
- if (MapName != NULL) {\r
- FreePool(MapName);\r
- }\r
+ SHELL_FREE_NON_NULL(PatternCopy);\r
+ SHELL_FREE_NON_NULL(MapName);\r
\r
return(Status);\r
}\r
UINTN HandleCounter;\r
SHELL_PROTOCOL_HANDLE_LIST *OldProtocolNode;\r
\r
+ if (NewShell == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
BufferSize = 0;\r
Buffer = NULL;\r
OldProtocolNode = NULL;\r
InitializeListHead(&ShellInfoObject.OldShellList.Link);\r
\r
- ASSERT(NewShell != NULL);\r
-\r
//\r
// Initialize EfiShellProtocol object...\r
//\r
- *NewShell = &mShellProtocol;\r
Status = gBS->CreateEvent(0,\r
0,\r
NULL,\r
NULL,\r
&mShellProtocol.ExecutionBreak);\r
- ASSERT_EFI_ERROR(Status);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\r
\r
//\r
// Get the size of the buffer we need.\r
// Allocate and recall with buffer of correct size\r
//\r
Buffer = AllocateZeroPool(BufferSize);\r
- ASSERT(Buffer != NULL);\r
+ if (Buffer == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
Status = gBS->LocateHandle(ByProtocol,\r
&gEfiShellProtocolGuid,\r
NULL,\r
&BufferSize,\r
Buffer);\r
- ASSERT_EFI_ERROR(Status);\r
+ if (EFI_ERROR(Status)) {\r
+ FreePool(Buffer);\r
+ return (Status);\r
+ }\r
//\r
// now overwrite each of them, but save the info to restore when we end.\r
//\r
OldProtocolNode->Handle,\r
&gEfiShellProtocolGuid,\r
OldProtocolNode->Interface,\r
- (VOID*)(*NewShell));\r
+ (VOID*)(&mShellProtocol));\r
if (!EFI_ERROR(Status)) {\r
//\r
// we reinstalled sucessfully. log this so we can reverse it later.\r
&gImageHandle,\r
&gEfiShellProtocolGuid,\r
EFI_NATIVE_INTERFACE,\r
- (VOID*)(*NewShell));\r
+ (VOID*)(&mShellProtocol));\r
}\r
\r
if (PcdGetBool(PcdShellSupportOldProtocols)){\r
///@todo do we need to support ShellEnvironment (not ShellEnvironment2) also?\r
}\r
\r
+ if (!EFI_ERROR(Status)) {\r
+ *NewShell = &mShellProtocol;\r
+ }\r
return (Status);\r
}\r
\r
IN OUT EFI_SHELL_PROTOCOL *NewShell\r
)\r
{\r
- EFI_STATUS Status;\r
- SHELL_PROTOCOL_HANDLE_LIST *Node2;\r
+ EFI_STATUS Status;\r
+ SHELL_PROTOCOL_HANDLE_LIST *Node2;\r
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
\r
//\r
// if we need to restore old protocols...\r
&gEfiShellProtocolGuid,\r
NewShell,\r
Node2->Interface);\r
- ASSERT_EFI_ERROR(Status);\r
FreePool(Node2);\r
}\r
} else {\r
Status = gBS->UninstallProtocolInterface(gImageHandle,\r
&gEfiShellProtocolGuid,\r
NewShell);\r
- ASSERT_EFI_ERROR(Status);\r
}\r
Status = gBS->CloseEvent(NewShell->ExecutionBreak);\r
+ NewShell->ExecutionBreak = NULL;\r
+\r
+ Status = gBS->OpenProtocol(\r
+ gST->ConsoleInHandle,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ (VOID**)&SimpleEx,\r
+ gImageHandle,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+\r
+ Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle1);\r
+ Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle2);\r
\r
return (Status);\r
}\r
\r
+/**\r
+ Notification function for keystrokes.\r
+\r
+ @param[in] KeyData The key that was pressed.\r
+\r
+ @retval EFI_SUCCESS The operation was successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NotificationFunction(\r
+ IN EFI_KEY_DATA *KeyData\r
+ )\r
+{\r
+ if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {\r
+ return (EFI_UNSUPPORTED);\r
+ }\r
+ return (gBS->SignalEvent(ShellInfoObject.NewEfiShellProtocol->ExecutionBreak));\r
+}\r
+\r
+/**\r
+ Function to start monitoring for CTRL-C using SimpleTextInputEx. This \r
+ feature's enabled state was not known when the shell initially launched.\r
+\r
+ @retval EFI_SUCCESS The feature is enabled.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InernalEfiShellStartMonitor(\r
+ VOID\r
+ )\r
+{\r
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;\r
+ EFI_KEY_DATA KeyData;\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->OpenProtocol(\r
+ gST->ConsoleInHandle,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ (VOID**)&SimpleEx,\r
+ gImageHandle,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(\r
+ -1, \r
+ -1, \r
+ NULL,\r
+ STRING_TOKEN (STR_SHELL_NO_IN_EX),\r
+ ShellInfoObject.HiiHandle);\r
+ return (EFI_SUCCESS);\r
+ }\r
\r
+ if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {\r
+ return (EFI_UNSUPPORTED);\r
+ }\r
+\r
+ KeyData.KeyState.KeyToggleState = 0;\r
+ KeyData.Key.ScanCode = 0;\r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;\r
+ KeyData.Key.UnicodeChar = L'c';\r
+\r
+ Status = SimpleEx->RegisterKeyNotify(\r
+ SimpleEx,\r
+ &KeyData,\r
+ NotificationFunction,\r
+ &ShellInfoObject.CtrlCNotifyHandle1);\r
+ \r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = SimpleEx->RegisterKeyNotify(\r
+ SimpleEx,\r
+ &KeyData,\r
+ NotificationFunction,\r
+ &ShellInfoObject.CtrlCNotifyHandle2);\r
+ }\r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;\r
+ KeyData.Key.UnicodeChar = 3;\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = SimpleEx->RegisterKeyNotify(\r
+ SimpleEx,\r
+ &KeyData,\r
+ NotificationFunction,\r
+ &ShellInfoObject.CtrlCNotifyHandle3);\r
+ }\r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = SimpleEx->RegisterKeyNotify(\r
+ SimpleEx,\r
+ &KeyData,\r
+ NotificationFunction,\r
+ &ShellInfoObject.CtrlCNotifyHandle4);\r
+ }\r
+ return (Status);\r
+}\r
#include <Protocol/LoadedImage.h>\r
#include <Protocol/UnicodeCollation.h>\r
#include <Protocol/DevicePath.h>\r
+#include <Protocol/SimpleTextInEx.h>\r
\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/BaseLib.h>\r
IN BOOLEAN Volatile\r
);\r
\r
+/**\r
+ Function to start monitoring for CTRL-C using SimpleTextInputEx. This \r
+ feature's enabled state was not known when the shell initially launched.\r
+\r
+ @retval EFI_SUCCESS The feature is enabled.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InernalEfiShellStartMonitor(\r
+ VOID\r
+ );\r
#endif //_SHELL_PROTOCOL_HEADER_\r
\r