]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLib/UefiShellLib.c
ShellPkg/ShellLib: Fix dynamic command fails to start during boot
[mirror_edk2.git] / ShellPkg / Library / UefiShellLib / UefiShellLib.c
index e47d5350e0eea8db2b98826f1250a79389e06cbb..7f6389f655783a7a68156490c2118b9c0e8cf5d7 100644 (file)
@@ -3,7 +3,7 @@
 \r
   (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
   Copyright 2016 Dell Inc.\r
-  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2017, 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
 **/\r
 \r
 #include "UefiShellLib.h"\r
-#include <ShellBase.h>\r
 #include <Library/SortLib.h>\r
 #include <Library/BaseLib.h>\r
 \r
-#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)\r
-\r
 //\r
 // globals...\r
 //\r
@@ -92,7 +89,6 @@ ShellIsDecimalDigitCharacter (
   @retval EFI_OUT_OF_RESOURCES    Memory allocation failed.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 ShellFindSE2 (\r
   IN EFI_HANDLE        ImageHandle\r
   )\r
@@ -176,7 +172,6 @@ ShellFindSE2 (
   @retval EFI_SUCCESS   The operationw as successful.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 ShellLibConstructorWorker (\r
   IN EFI_HANDLE        ImageHandle,\r
   IN EFI_SYSTEM_TABLE  *SystemTable\r
@@ -184,43 +179,48 @@ ShellLibConstructorWorker (
 {\r
   EFI_STATUS  Status;\r
 \r
-  //\r
-  // UEFI 2.0 shell interfaces (used preferentially)\r
-  //\r
-  Status = gBS->OpenProtocol(\r
-    ImageHandle,\r
-    &gEfiShellProtocolGuid,\r
-    (VOID **)&gEfiShellProtocol,\r
-    ImageHandle,\r
-    NULL,\r
-    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (gEfiShellProtocol == NULL) {\r
     //\r
-    // Search for the shell protocol\r
+    // UEFI 2.0 shell interfaces (used preferentially)\r
     //\r
-    Status = gBS->LocateProtocol(\r
+    Status = gBS->OpenProtocol (\r
+      ImageHandle,\r
       &gEfiShellProtocolGuid,\r
+      (VOID **)&gEfiShellProtocol,\r
+      ImageHandle,\r
       NULL,\r
-      (VOID **)&gEfiShellProtocol\r
-     );\r
-    if (EFI_ERROR(Status)) {\r
-      gEfiShellProtocol = NULL;\r
+      EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+    );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Search for the shell protocol\r
+      //\r
+      Status = gBS->LocateProtocol (\r
+        &gEfiShellProtocolGuid,\r
+        NULL,\r
+        (VOID **)&gEfiShellProtocol\r
+      );\r
+      if (EFI_ERROR (Status)) {\r
+        gEfiShellProtocol = NULL;\r
+      }\r
     }\r
   }\r
-  Status = gBS->OpenProtocol(\r
-    ImageHandle,\r
-    &gEfiShellParametersProtocolGuid,\r
-    (VOID **)&gEfiShellParametersProtocol,\r
-    ImageHandle,\r
-    NULL,\r
-    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-   );\r
-  if (EFI_ERROR(Status)) {\r
-    gEfiShellParametersProtocol = NULL;\r
+\r
+  if (gEfiShellParametersProtocol == NULL) {\r
+    Status = gBS->OpenProtocol (\r
+      ImageHandle,\r
+      &gEfiShellParametersProtocolGuid,\r
+      (VOID **)&gEfiShellParametersProtocol,\r
+      ImageHandle,\r
+      NULL,\r
+      EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+    );\r
+    if (EFI_ERROR (Status)) {\r
+      gEfiShellParametersProtocol = NULL;\r
+    }\r
   }\r
 \r
-  if (gEfiShellParametersProtocol == NULL || gEfiShellProtocol == NULL) {\r
+  if (gEfiShellProtocol == NULL) {\r
     //\r
     // Moved to seperate function due to complexity\r
     //\r
@@ -243,10 +243,14 @@ ShellLibConstructorWorker (
   }\r
 \r
   //\r
-  // only success getting 2 of either the old or new, but no 1/2 and 1/2\r
+  // Getting either EDK Shell's ShellEnvironment2 and ShellInterface protocol\r
+  //  or UEFI Shell's Shell protocol.\r
+  // When ShellLib is linked to a driver producing DynamicCommand protocol,\r
+  //  ShellParameters protocol is set by DynamicCommand.Handler().\r
   //\r
-  if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface          != NULL) ||\r
-      (gEfiShellProtocol     != NULL && gEfiShellParametersProtocol != NULL)   ) {\r
+  if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface != NULL) ||\r
+      (gEfiShellProtocol     != NULL)\r
+      ) {\r
     if (gEfiShellProtocol != NULL) {\r
       FileFunctionMap.GetFileInfo     = gEfiShellProtocol->GetFileInfo;\r
       FileFunctionMap.SetFileInfo     = gEfiShellProtocol->SetFileInfo;\r
@@ -292,18 +296,12 @@ ShellLibConstructor (
   IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-\r
   mEfiShellEnvironment2       = NULL;\r
   gEfiShellProtocol           = NULL;\r
   gEfiShellParametersProtocol = NULL;\r
   mEfiShellInterface          = NULL;\r
   mEfiShellEnvironment2Handle = NULL;\r
-\r
-  if (mUnicodeCollationProtocol == NULL) {\r
-    Status = gBS->LocateProtocol (&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&mUnicodeCollationProtocol);\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
+  mUnicodeCollationProtocol   = NULL;\r
 \r
   //\r
   // verify that auto initialize is not set false\r
@@ -331,35 +329,45 @@ ShellLibDestructor (
   IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
+  EFI_STATUS           Status;\r
+\r
   if (mEfiShellEnvironment2 != NULL) {\r
-    gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
+    Status = gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,\r
                        &gEfiShellEnvironment2Guid,\r
                        ImageHandle,\r
                        NULL);\r
-    mEfiShellEnvironment2 = NULL;\r
+    if (!EFI_ERROR (Status)) {\r
+      mEfiShellEnvironment2       = NULL;\r
+      mEfiShellEnvironment2Handle = NULL;\r
+    }\r
   }\r
   if (mEfiShellInterface != NULL) {\r
-    gBS->CloseProtocol(ImageHandle,\r
+    Status = gBS->CloseProtocol(ImageHandle,\r
                        &gEfiShellInterfaceGuid,\r
                        ImageHandle,\r
                        NULL);\r
-    mEfiShellInterface = NULL;\r
+    if (!EFI_ERROR (Status)) {\r
+      mEfiShellInterface = NULL;\r
+    }\r
   }\r
   if (gEfiShellProtocol != NULL) {\r
-    gBS->CloseProtocol(ImageHandle,\r
+    Status = gBS->CloseProtocol(ImageHandle,\r
                        &gEfiShellProtocolGuid,\r
                        ImageHandle,\r
                        NULL);\r
-    gEfiShellProtocol = NULL;\r
+    if (!EFI_ERROR (Status)) {\r
+      gEfiShellProtocol = NULL;\r
+    }\r
   }\r
   if (gEfiShellParametersProtocol != NULL) {\r
-    gBS->CloseProtocol(ImageHandle,\r
+    Status = gBS->CloseProtocol(ImageHandle,\r
                        &gEfiShellParametersProtocolGuid,\r
                        ImageHandle,\r
                        NULL);\r
-    gEfiShellParametersProtocol = NULL;\r
+    if (!EFI_ERROR (Status)) {\r
+      gEfiShellParametersProtocol = NULL;\r
+    }\r
   }\r
-  mEfiShellEnvironment2Handle = NULL;\r
 \r
   return (EFI_SUCCESS);\r
 }\r
@@ -380,6 +388,7 @@ ShellLibDestructor (
 EFI_STATUS\r
 EFIAPI\r
 ShellInitialize (\r
+  VOID\r
   )\r
 {\r
   EFI_STATUS Status;\r
@@ -711,7 +720,7 @@ ShellOpenFileByName(
       // Create the directory to create the file in\r
       //\r
       FileNameCopy = AllocateCopyPool (StrSize (FileName), FileName);\r
-      if (FileName == NULL) {\r
+      if (FileNameCopy == NULL) {\r
         return (EFI_OUT_OF_RESOURCES);\r
       }\r
       PathCleanUpDirectories (FileNameCopy);\r
@@ -729,6 +738,17 @@ ShellOpenFileByName(
     Status = gEfiShellProtocol->OpenFileByName(FileName,\r
                                                FileHandle,\r
                                                OpenMode);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+\r
+    if (mUnicodeCollationProtocol == NULL) {\r
+      Status = gBS->LocateProtocol (&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&mUnicodeCollationProtocol);\r
+      if (EFI_ERROR (Status)) {\r
+        gEfiShellProtocol->CloseFile (*FileHandle);\r
+        return Status;\r
+      }\r
+    }\r
 \r
     if ((mUnicodeCollationProtocol->StriColl (mUnicodeCollationProtocol, (CHAR16*)FileName, L"NUL") != 0) &&\r
         (mUnicodeCollationProtocol->StriColl (mUnicodeCollationProtocol, (CHAR16*)FileName, L"NULL") != 0) &&\r
@@ -1418,7 +1438,6 @@ typedef struct {
   @retval the resultant head of the double linked new format list;\r
 **/\r
 LIST_ENTRY*\r
-EFIAPI\r
 InternalShellConvertFileListType (\r
   IN LIST_ENTRY                 *FileList,\r
   IN OUT LIST_ENTRY             *ListHead\r
@@ -1888,7 +1907,6 @@ typedef struct {
   @retval FALSE                 the Parameter was not found.  Type is not valid.\r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 InternalIsOnCheckList (\r
   IN CONST CHAR16               *Name,\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
@@ -1957,7 +1975,6 @@ InternalIsOnCheckList (
   @retval FALSE                 the Parameter not a flag.\r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 InternalIsFlag (\r
   IN CONST CHAR16               *Name,\r
   IN CONST BOOLEAN              AlwaysAllowNumbers,\r
@@ -2014,7 +2031,6 @@ InternalIsFlag (
                                 ProblemParam if provided.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InternalCommandLineParse (\r
   IN CONST SHELL_PARAM_ITEM     *CheckList,\r
   OUT LIST_ENTRY                **CheckPackage,\r
@@ -2703,7 +2719,6 @@ ShellCopySearchAndReplace(
   @retval !EFI_SUCCESS    The operation failed.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InternalPrintTo (\r
   IN CONST CHAR16 *String\r
   )\r
@@ -2759,7 +2774,6 @@ InternalPrintTo (
   @return EFI_DEVICE_ERROR      The console device reported an error.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InternalShellPrintWorker(\r
   IN INT32                Col OPTIONAL,\r
   IN INT32                Row OPTIONAL,\r
@@ -2832,7 +2846,7 @@ InternalShellPrintWorker(
     // update the attribute\r
     //\r
     if (ResumeLocation != NULL) {\r
-      if (*(ResumeLocation-1) == L'^') {\r
+      if ((ResumeLocation != mPostReplaceFormat2) && (*(ResumeLocation-1) == L'^')) {\r
         //\r
         // Move cursor back 1 position to overwrite the ^\r
         //\r
@@ -2855,10 +2869,10 @@ InternalShellPrintWorker(
             gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
             break;\r
           case (L'B'):\r
-            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_LIGHTBLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
             break;\r
           case (L'V'):\r
-            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
+            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_LIGHTGREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));\r
             break;\r
           default:\r
             //\r
@@ -3407,7 +3421,8 @@ ShellPromptForResponse (
             break;\r
         }\r
       }\r
-      break;    case ShellPromptResponseTypeYesNoAllCancel:\r
+      break;\r
+      case ShellPromptResponseTypeYesNoAllCancel:\r
        if (Prompt != NULL) {\r
         ShellPrintEx(-1, -1, L"%s", Prompt);\r
       }\r
@@ -3425,7 +3440,11 @@ ShellPromptForResponse (
         if (EFI_ERROR(Status)) {\r
           break;\r
         }\r
-        ShellPrintEx(-1, -1, L"%c", Key.UnicodeChar);\r
+\r
+        if (Key.UnicodeChar <= 127 && Key.UnicodeChar >= 32) {\r
+          ShellPrintEx (-1, -1, L"%c", Key.UnicodeChar);\r
+        }\r
+\r
         switch (Key.UnicodeChar) {\r
           case L'Y':\r
           case L'y':\r
@@ -3609,7 +3628,6 @@ ShellPromptForResponseHii (
   @retval FALSE       There is a non-numeric character.\r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 InternalShellIsHexOrDecimalNumber (\r
   IN CONST CHAR16   *String,\r
   IN CONST BOOLEAN  ForceHex,\r
@@ -3722,7 +3740,6 @@ ShellFileExists(
 \r
 **/\r
 CHAR16\r
-EFIAPI\r
 InternalShellCharToUpper (\r
   IN      CHAR16                    Char\r
   )\r
@@ -3748,7 +3765,6 @@ InternalShellCharToUpper (
 \r
 **/\r
 UINTN\r
-EFIAPI\r
 InternalShellHexCharToUintn (\r
   IN      CHAR16                    Char\r
   )\r
@@ -3757,7 +3773,7 @@ InternalShellHexCharToUintn (
     return Char - L'0';\r
   }\r
 \r
-  return (UINTN) (10 + InternalShellCharToUpper (Char) - L'A');\r
+  return (10 + InternalShellCharToUpper (Char) - L'A');\r
 }\r
 \r
 /**\r
@@ -3791,7 +3807,6 @@ InternalShellHexCharToUintn (
   @retval EFI_DEVICE_ERROR        An overflow occured.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InternalShellStrHexToUint64 (\r
   IN CONST CHAR16   *String,\r
      OUT   UINT64   *Value,\r
@@ -3893,7 +3908,6 @@ InternalShellStrHexToUint64 (
   @retval EFI_DEVICE_ERROR        An overflow occured.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InternalShellStrDecimalToUint64 (\r
   IN CONST CHAR16 *String,\r
      OUT   UINT64 *Value,\r
@@ -4345,7 +4359,6 @@ ShellDeleteFileByName(
   @retval EFI_SUCCESS   The operation was successful.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 InternalShellStripQuotes (\r
   IN  CONST CHAR16     *OriginalString,\r
   OUT CHAR16           **CleanString\r