]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLib/UefiShellLib.c
ShellPkg/ShellLib: Fix a bug in InternalShellIsHexOrDecimalNumber
[mirror_edk2.git] / ShellPkg / Library / UefiShellLib / UefiShellLib.c
index 8db18b3b210fa53ac842a9f09cdbb79912962565..e53985e2d71406a45970fd618927f36e280dc0a9 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 - 2018, 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
@@ -325,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
@@ -374,6 +388,7 @@ ShellLibDestructor (
 EFI_STATUS\r
 EFIAPI\r
 ShellInitialize (\r
+  VOID\r
   )\r
 {\r
   EFI_STATUS Status;\r
@@ -705,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
@@ -1423,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
@@ -1893,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
@@ -1962,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
@@ -2019,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
@@ -2708,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
@@ -2764,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
@@ -2837,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
@@ -2860,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
@@ -3412,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
@@ -3430,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
@@ -3614,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
@@ -3623,29 +3636,36 @@ InternalShellIsHexOrDecimalNumber (
   )\r
 {\r
   BOOLEAN Hex;\r
+  BOOLEAN LeadingZero;\r
+\r
+  if (String == NULL) {\r
+    return FALSE;\r
+  }\r
 \r
   //\r
   // chop off a single negative sign\r
   //\r
-  if (String != NULL && *String == L'-') {\r
+  if (*String == L'-') {\r
     String++;\r
   }\r
 \r
-  if (String == NULL) {\r
-    return (FALSE);\r
+  if (*String == CHAR_NULL) {\r
+    return FALSE;\r
   }\r
 \r
   //\r
   // chop leading zeroes\r
   //\r
-  while(String != NULL && *String == L'0'){\r
+  LeadingZero = FALSE;\r
+  while(*String == L'0'){\r
     String++;\r
+    LeadingZero = TRUE;\r
   }\r
   //\r
   // allow '0x' or '0X', but not 'x' or 'X'\r
   //\r
-  if (String != NULL && (*String == L'x' || *String == L'X')) {\r
-    if (*(String-1) != L'0') {\r
+  if (*String == L'x' || *String == L'X') {\r
+    if (!LeadingZero) {\r
       //\r
       // we got an x without a preceeding 0\r
       //\r
@@ -3662,7 +3682,7 @@ InternalShellIsHexOrDecimalNumber (
   //\r
   // loop through the remaining characters and use the lib function\r
   //\r
-  for ( ; String != NULL && *String != CHAR_NULL && !(StopAtSpace && *String == L' ') ; String++){\r
+  for ( ; *String != CHAR_NULL && !(StopAtSpace && *String == L' ') ; String++){\r
     if (TimeNumbers && (String[0] == L':')) {\r
       continue;\r
     }\r
@@ -3727,7 +3747,6 @@ ShellFileExists(
 \r
 **/\r
 CHAR16\r
-EFIAPI\r
 InternalShellCharToUpper (\r
   IN      CHAR16                    Char\r
   )\r
@@ -3753,7 +3772,6 @@ InternalShellCharToUpper (
 \r
 **/\r
 UINTN\r
-EFIAPI\r
 InternalShellHexCharToUintn (\r
   IN      CHAR16                    Char\r
   )\r
@@ -3762,7 +3780,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
@@ -3796,7 +3814,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
@@ -3898,7 +3915,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
@@ -4350,7 +4366,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