]> git.proxmox.com Git - mirror_edk2.git/commitdiff
fixes for IPF, CTRL-C support, and file redirection.
authorjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 16 Nov 2010 22:31:47 +0000 (22:31 +0000)
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 16 Nov 2010 22:31:47 +0000 (22:31 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11066 6f19259b-4bc3-4df7-8a09-765794883524

12 files changed:
ShellPkg/Application/Shell/ConsoleLogger.c
ShellPkg/Application/Shell/ConsoleWrappers.c [new file with mode: 0644]
ShellPkg/Application/Shell/ConsoleWrappers.h [new file with mode: 0644]
ShellPkg/Application/Shell/Shell.c
ShellPkg/Application/Shell/Shell.h
ShellPkg/Application/Shell/Shell.inf
ShellPkg/Application/Shell/Shell.uni
ShellPkg/Application/Shell/ShellEnvVar.c
ShellPkg/Application/Shell/ShellParametersProtocol.c
ShellPkg/Application/Shell/ShellParametersProtocol.h
ShellPkg/Application/Shell/ShellProtocol.c
ShellPkg/Application/Shell/ShellProtocol.h

index 2b84d87adb06421c2ad900d80abf7521ceee3b7d..4b237bf6e9cf1fad4163207683f7d246abaa1120 100644 (file)
@@ -76,10 +76,19 @@ ConsoleLoggerInstall(
 \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
diff --git a/ShellPkg/Application/Shell/ConsoleWrappers.c b/ShellPkg/Application/Shell/ConsoleWrappers.c
new file mode 100644 (file)
index 0000000..61b6a5e
--- /dev/null
@@ -0,0 +1,477 @@
+/** @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
diff --git a/ShellPkg/Application/Shell/ConsoleWrappers.h b/ShellPkg/Application/Shell/ConsoleWrappers.h
new file mode 100644 (file)
index 0000000..966a922
--- /dev/null
@@ -0,0 +1,81 @@
+/** @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
index ddd5d1712a704d72580bf9336bad3d6caf2f08ce..b626ec2ac115769d5cc0711da76c1ed59c181af7 100644 (file)
@@ -52,6 +52,10 @@ SHELL_INFO ShellInfoObject = {
   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
@@ -271,9 +275,7 @@ UefiMain (
         //\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
@@ -303,6 +305,11 @@ UefiMain (
           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
@@ -319,11 +326,6 @@ UefiMain (
     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
@@ -337,6 +339,9 @@ UefiMain (
     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
@@ -1186,6 +1191,7 @@ RunCommand(
   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
@@ -1311,7 +1317,7 @@ RunCommand(
 \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
@@ -1430,7 +1436,7 @@ RunCommand(
 \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
index 6f165e551513353ba136901e1d291c02c0301239..ec32355b6c1a7b73e8aedf4b2603c87048a7d563 100644 (file)
@@ -105,6 +105,10 @@ typedef struct {
   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
index e2649a7251c277e1215c014f186d66e5c54755b8..e690e2e7f3594e97279478f35343faecc246c298 100644 (file)
@@ -44,6 +44,8 @@
   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
index 82a87aeb3f6717f0273b5db63c1ae1d655db5492..e7327f3dbb5400649ca413f9fd26dc38bfe25928 100644 (file)
Binary files a/ShellPkg/Application/Shell/Shell.uni and b/ShellPkg/Application/Shell/Shell.uni differ
index cd55fa907be69a6d3f0ac3df4fc066f3ffc3c10f..f22fb705ddec82330397f8d1fa9ce07b8d6fdcb9 100644 (file)
@@ -13,6 +13,7 @@
 **/\r
 \r
 #include <Uefi.h>\r
+#include <ShellBase.h>\r
 \r
 #include <Guid/ShellVariableGuid.h>\r
 \r
@@ -24,7 +25,6 @@
 \r
 #include "ShellEnvVar.h"\r
 \r
-\r
 /**\r
   Reports whether an environment variable is Volatile or Non-Volatile.\r
 \r
@@ -169,18 +169,31 @@ GetEnvironmentVariableList(
     }\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
index 5e3e48b414c4116973c87d51028234a4e702d421..b594d3434f7ad098a5616e17640cb56831247af5 100644 (file)
@@ -14,6 +14,7 @@
 **/\r
 \r
 #include "ShellParametersProtocol.h"\r
+#include "ConsoleWrappers.h"\r
 \r
 /**\r
   return the next parameter from a command line string;\r
@@ -423,13 +424,14 @@ CleanUpShellParametersProtocol (
   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
@@ -441,7 +443,8 @@ UpdateStdInStdOutStdErr(
   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
@@ -464,7 +467,6 @@ UpdateStdInStdOutStdErr(
   CHAR16            TagBuffer[2];\r
   SPLIT_LIST        *Split;\r
 \r
-  ASSERT(ShellParameters != NULL);\r
   OutUnicode      = TRUE;\r
   InUnicode       = TRUE;\r
   ErrUnicode      = TRUE;\r
@@ -478,16 +480,20 @@ UpdateStdInStdOutStdErr(
   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
@@ -726,6 +732,7 @@ UpdateStdInStdOutStdErr(
         }\r
         if (!EFI_ERROR(Status)) {\r
           ShellParameters->StdErr = TempHandle;\r
+          gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);\r
         }\r
       }\r
 \r
@@ -766,6 +773,7 @@ UpdateStdInStdOutStdErr(
           }\r
           if (!EFI_ERROR(Status)) {\r
             ShellParameters->StdOut = TempHandle;\r
+            gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);\r
           }\r
         }\r
       }\r
@@ -787,6 +795,7 @@ UpdateStdInStdOutStdErr(
           ASSERT(TempHandle != NULL);\r
         }\r
         ShellParameters->StdOut = TempHandle;\r
+        gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);\r
       }\r
 \r
       //\r
@@ -806,6 +815,7 @@ UpdateStdInStdOutStdErr(
           ASSERT(TempHandle != NULL);\r
         }\r
         ShellParameters->StdErr = TempHandle;\r
+        gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);\r
       }\r
 \r
       //\r
@@ -822,6 +832,7 @@ UpdateStdInStdOutStdErr(
           Status = EFI_INVALID_PARAMETER;\r
         } else {\r
           ShellParameters->StdIn = TempHandle;\r
+          gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);\r
         }\r
       }\r
 \r
@@ -839,11 +850,16 @@ UpdateStdInStdOutStdErr(
         }\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
@@ -851,38 +867,69 @@ UpdateStdInStdOutStdErr(
   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
index 3a5fc30bcb8049f32d0c77ed75ee2f8a1080df00..2d19587610ea3454d74aa66cc5012517b0e22b24 100644 (file)
@@ -21,6 +21,8 @@
 #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
@@ -116,6 +118,15 @@ RestoreArgcArgv(
   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
@@ -128,6 +139,7 @@ RestoreArgcArgv(
   @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
@@ -137,27 +149,30 @@ EFIAPI
 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
index eaec87971d96277a6152383af8a24f8a5e15cacb..392298989ee6dd7a943deb50453d8a1d09580eef 100644 (file)
@@ -34,7 +34,7 @@ EfiShellClose (
   )\r
 {\r
   ShellFileHandleRemove(FileHandle);\r
-  return (FileHandleClose(FileHandle));\r
+  return (FileHandleClose(ConvertShellHandleToEfiFileProtocol(FileHandle)));\r
 }\r
 \r
 /**\r
@@ -475,8 +475,12 @@ EfiShellGetDevicePathFromFilePath(
   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
@@ -488,7 +492,7 @@ EfiShellGetDevicePathFromFilePath(
     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
@@ -803,6 +807,7 @@ EfiShellOpenRootByHandle(
                                 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
@@ -814,6 +819,10 @@ EfiShellOpenRoot(
   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
@@ -876,11 +885,19 @@ InternalOpenFileDevicePath(
   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
@@ -903,6 +920,8 @@ InternalOpenFileDevicePath(
           ; !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
@@ -926,7 +945,7 @@ InternalOpenFileDevicePath(
           Status = Handle2->Open (\r
                                 Handle2,\r
                                 &Handle1,\r
-                                FilePathNode->PathName,\r
+                                AlignedNode->PathName,\r
                                 OpenMode,\r
                                 Attributes\r
                                );\r
@@ -944,7 +963,7 @@ InternalOpenFileDevicePath(
           Status = Handle2->Open (\r
                                 Handle2,\r
                                 &Handle1,\r
-                                FilePathNode->PathName,\r
+                                AlignedNode->PathName,\r
                                 OpenMode &~EFI_FILE_MODE_CREATE,\r
                                 Attributes\r
                                );\r
@@ -956,7 +975,7 @@ InternalOpenFileDevicePath(
             Status = Handle2->Open (\r
                                   Handle2,\r
                                   &Handle1,\r
-                                  FilePathNode->PathName,\r
+                                  AlignedNode->PathName,\r
                                   OpenMode,\r
                                   Attributes\r
                                  );\r
@@ -965,7 +984,7 @@ InternalOpenFileDevicePath(
         //\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
@@ -976,9 +995,10 @@ InternalOpenFileDevicePath(
       } // 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
@@ -1867,11 +1887,6 @@ UpdateFileName(
   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
@@ -1880,6 +1895,7 @@ UpdateFileName(
   @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
@@ -1892,7 +1908,8 @@ ShellSearchHandle(
   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
@@ -1902,6 +1919,8 @@ ShellSearchHandle(
   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
@@ -1965,7 +1984,20 @@ ShellSearchHandle(
           ; 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
@@ -1991,9 +2023,9 @@ ShellSearchHandle(
               //\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
@@ -2109,18 +2141,14 @@ EfiShellFindFiles(
             ; *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
@@ -2996,23 +3024,26 @@ CreatePopulateInstallShellProtocol (
   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
@@ -3027,13 +3058,18 @@ CreatePopulateInstallShellProtocol (
     // 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
@@ -3056,7 +3092,7 @@ CreatePopulateInstallShellProtocol (
                             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
@@ -3079,7 +3115,7 @@ CreatePopulateInstallShellProtocol (
                       &gImageHandle,\r
                       &gEfiShellProtocolGuid,\r
                       EFI_NATIVE_INTERFACE,\r
-                      (VOID*)(*NewShell));\r
+                      (VOID*)(&mShellProtocol));\r
   }\r
 \r
   if (PcdGetBool(PcdShellSupportOldProtocols)){\r
@@ -3087,6 +3123,9 @@ CreatePopulateInstallShellProtocol (
     ///@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
@@ -3106,8 +3145,9 @@ CleanUpShellProtocol (
   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
@@ -3122,7 +3162,6 @@ CleanUpShellProtocol (
                                                &gEfiShellProtocolGuid,\r
                                                NewShell,\r
                                                Node2->Interface);\r
-      ASSERT_EFI_ERROR(Status);\r
       FreePool(Node2);\r
     }\r
   } else {\r
@@ -3132,11 +3171,116 @@ CleanUpShellProtocol (
     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
index d03a382f6d5f7b2309db308103af30802ef84f14..38e71b40dc754208e18b4edf84403a2acc344d7a 100644 (file)
@@ -31,6 +31,7 @@
 #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
@@ -946,5 +947,17 @@ InternalEfiShellSetEnv(
   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