]> 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 5b4c6d3fb7e392468aa1a79b79c193779d865d48..e53985e2d71406a45970fd618927f36e280dc0a9 100644 (file)
@@ -1,7 +1,9 @@
 /** @file\r
   Provides interface to shell functionality for shell commands and applications.\r
 \r
-  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+  Copyright 2016 Dell Inc.\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
@@ -35,6 +34,7 @@ EFI_SHELL_PROTOCOL            *gEfiShellProtocol;
 EFI_SHELL_PARAMETERS_PROTOCOL *gEfiShellParametersProtocol;\r
 EFI_HANDLE                    mEfiShellEnvironment2Handle;\r
 FILE_HANDLE_FUNCTION_MAP      FileFunctionMap;\r
+EFI_UNICODE_COLLATION_PROTOCOL  *mUnicodeCollationProtocol;\r
 \r
 /**\r
   Check if a Unicode character is a hexadecimal character.\r
@@ -89,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
@@ -173,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
@@ -181,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
@@ -240,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
@@ -294,6 +301,7 @@ ShellLibConstructor (
   gEfiShellParametersProtocol = NULL;\r
   mEfiShellInterface          = NULL;\r
   mEfiShellEnvironment2Handle = NULL;\r
+  mUnicodeCollationProtocol   = NULL;\r
 \r
   //\r
   // verify that auto initialize is not set false\r
@@ -321,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
@@ -370,8 +388,11 @@ ShellLibDestructor (
 EFI_STATUS\r
 EFIAPI\r
 ShellInitialize (\r
+  VOID\r
   )\r
 {\r
+  EFI_STATUS Status;\r
+\r
   //\r
   // if auto initialize is not false then skip\r
   //\r
@@ -382,7 +403,8 @@ ShellInitialize (
   //\r
   // deinit the current stuff\r
   //\r
-  ASSERT_EFI_ERROR(ShellLibDestructor(gImageHandle, gST));\r
+  Status = ShellLibDestructor (gImageHandle, gST);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   // init the new stuff\r
@@ -673,6 +695,7 @@ ShellOpenFileByName(
   EFI_STATUS                    Status;\r
   EFI_FILE_INFO                 *FileInfo;\r
   CHAR16                        *FileNameCopy;\r
+  EFI_STATUS                    Status2;\r
 \r
   //\r
   // ASSERT if FileName is NULL\r
@@ -697,13 +720,14 @@ 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
       if (PathRemoveLastItem (FileNameCopy)) {\r
-        ShellCreateDirectory (FileNameCopy, FileHandle);\r
-        ShellCloseFile (FileHandle);\r
+        if (!EFI_ERROR(ShellCreateDirectory (FileNameCopy, FileHandle))) {\r
+          ShellCloseFile (FileHandle);\r
+        }\r
       }\r
       SHELL_FREE_NON_NULL (FileNameCopy);\r
     }\r
@@ -714,12 +738,30 @@ ShellOpenFileByName(
     Status = gEfiShellProtocol->OpenFileByName(FileName,\r
                                                FileHandle,\r
                                                OpenMode);\r
-    if (StrCmp(FileName, L"NUL") != 0 && !EFI_ERROR(Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)){\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
+         !EFI_ERROR(Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)){\r
       FileInfo = FileFunctionMap.GetFileInfo(*FileHandle);\r
       ASSERT(FileInfo != NULL);\r
       FileInfo->Attribute = Attributes;\r
-      Status = FileFunctionMap.SetFileInfo(*FileHandle, FileInfo);\r
+      Status2 = FileFunctionMap.SetFileInfo(*FileHandle, FileInfo);\r
       FreePool(FileInfo);\r
+      if (EFI_ERROR (Status2)) {\r
+        gEfiShellProtocol->CloseFile(*FileHandle);\r
+      }\r
+      Status = Status2;\r
     }\r
     return (Status);\r
   }\r
@@ -1275,6 +1317,8 @@ ShellExecute (
   name. If the DeviceName is not NULL, it returns the current directory name\r
   on specified drive.\r
 \r
+  Note that the current directory string should exclude the tailing backslash character.\r
+\r
   @param DeviceName             the name of the drive to get directory on\r
 \r
   @retval NULL                  the directory does not exist\r
@@ -1394,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
@@ -1707,13 +1750,14 @@ ShellFindFilePath (
 \r
   Path = ShellGetEnvironmentVariable(L"cwd");\r
   if (Path != NULL) {\r
-    Size = StrSize(Path);\r
+    Size = StrSize(Path) + sizeof(CHAR16);\r
     Size += StrSize(FileName);\r
     TestPath = AllocateZeroPool(Size);\r
     if (TestPath == NULL) {\r
       return (NULL);\r
     }\r
     StrCpyS(TestPath, Size/sizeof(CHAR16), Path);\r
+    StrCatS(TestPath, Size/sizeof(CHAR16), L"\\");\r
     StrCatS(TestPath, Size/sizeof(CHAR16), FileName);\r
     Status = ShellOpenFileByName(TestPath, &Handle, EFI_FILE_MODE_READ, 0);\r
     if (!EFI_ERROR(Status)){\r
@@ -1863,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
@@ -1932,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
@@ -1989,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
@@ -2008,6 +2049,7 @@ InternalCommandLineParse (
   UINTN                         Count;\r
   CONST CHAR16                  *TempPointer;\r
   UINTN                         CurrentValueSize;\r
+  CHAR16                        *NewValue;\r
 \r
   CurrentItemPackage = NULL;\r
   GetItemValue = 0;\r
@@ -2106,8 +2148,15 @@ InternalCommandLineParse (
       // get the item VALUE for a previous flag\r
       //\r
       CurrentValueSize = ValueSize + StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
-      CurrentItemPackage->Value = ReallocatePool(ValueSize, CurrentValueSize, CurrentItemPackage->Value);\r
-      ASSERT(CurrentItemPackage->Value != NULL);\r
+      NewValue = ReallocatePool(ValueSize, CurrentValueSize, CurrentItemPackage->Value);\r
+      if (NewValue == NULL) {\r
+        SHELL_FREE_NON_NULL (CurrentItemPackage->Value);\r
+        SHELL_FREE_NON_NULL (CurrentItemPackage);\r
+        ShellCommandLineFreeVarList (*CheckPackage);\r
+        *CheckPackage = NULL;\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+      CurrentItemPackage->Value = NewValue;\r
       if (ValueSize == 0) {\r
         StrCpyS( CurrentItemPackage->Value, \r
                   CurrentValueSize/sizeof(CHAR16), \r
@@ -2521,7 +2570,7 @@ ShellCommandLineGetCount(
 }\r
 \r
 /**\r
-  Determins if a parameter is duplicated.\r
+  Determines if a parameter is duplicated.\r
 \r
   If Param is not NULL then it will point to a callee allocated string buffer\r
   with the parameter value if a duplicate is found.\r
@@ -2670,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
@@ -2726,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
@@ -2799,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
@@ -2822,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
@@ -2955,13 +3002,14 @@ ShellPrintHiiEx(
   CHAR16            *HiiFormatString;\r
   EFI_STATUS        RetVal;\r
 \r
+  RetVal = EFI_DEVICE_ERROR;\r
+\r
   VA_START (Marker, HiiFormatHandle);\r
   HiiFormatString = HiiGetString(HiiFormatHandle, HiiFormatStringId, Language);\r
-  ASSERT(HiiFormatString != NULL);\r
-\r
-  RetVal = InternalShellPrintWorker(Col, Row, HiiFormatString, Marker);\r
-\r
-  SHELL_FREE_NON_NULL(HiiFormatString);\r
+  if (HiiFormatString != NULL) {\r
+    RetVal = InternalShellPrintWorker (Col, Row, HiiFormatString, Marker);\r
+    SHELL_FREE_NON_NULL (HiiFormatString);\r
+  }\r
   VA_END(Marker);\r
 \r
   return (RetVal);\r
@@ -3254,7 +3302,8 @@ StrnCatGrow (
       *CurrentSize = NewSize;\r
     }\r
   } else {\r
-    *Destination = AllocateZeroPool((Count+1)*sizeof(CHAR16));\r
+    NewSize = (Count+1)*sizeof(CHAR16);\r
+    *Destination = AllocateZeroPool(NewSize);\r
   }\r
 \r
   //\r
@@ -3264,7 +3313,7 @@ StrnCatGrow (
     return (NULL);\r
   }\r
   \r
-  StrCatS(*Destination, Count + 1, Source);\r
+  StrnCatS(*Destination, NewSize/sizeof(CHAR16), Source, Count);\r
   return *Destination;\r
 }\r
 \r
@@ -3272,7 +3321,7 @@ StrnCatGrow (
   Prompt the user and return the resultant answer to the requestor.\r
 \r
   This function will display the requested question on the shell prompt and then\r
-  wait for an apropriate answer to be input from the console.\r
+  wait for an appropriate answer to be input from the console.\r
 \r
   if the SHELL_PROMPT_REQUEST_TYPE is SHELL_PROMPT_REQUEST_TYPE_YESNO, ShellPromptResponseTypeQuitContinue\r
   or SHELL_PROMPT_REQUEST_TYPE_YESNOCANCEL then *Response is of type SHELL_PROMPT_RESPONSE.\r
@@ -3372,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
@@ -3390,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
@@ -3574,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
@@ -3583,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
@@ -3622,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
@@ -3687,7 +3747,6 @@ ShellFileExists(
 \r
 **/\r
 CHAR16\r
-EFIAPI\r
 InternalShellCharToUpper (\r
   IN      CHAR16                    Char\r
   )\r
@@ -3713,7 +3772,6 @@ InternalShellCharToUpper (
 \r
 **/\r
 UINTN\r
-EFIAPI\r
 InternalShellHexCharToUintn (\r
   IN      CHAR16                    Char\r
   )\r
@@ -3722,13 +3780,13 @@ 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
   Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
 \r
-  This function returns a value of type UINTN by interpreting the contents\r
+  This function returns a value of type UINT64 by interpreting the contents\r
   of the Unicode string specified by String as a hexadecimal number.\r
   The format of the input Unicode string String is:\r
 \r
@@ -3756,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
@@ -3796,16 +3853,16 @@ InternalShellStrHexToUint64 (
   Result = 0;\r
 \r
   //\r
-  // Skip spaces if requested\r
+  // there is a space where there should't be\r
   //\r
-  while (StopAtSpace && *String == L' ') {\r
-    String++;\r
+  if (*String == L' ') {\r
+    return (EFI_INVALID_PARAMETER);\r
   }\r
 \r
   while (ShellIsHexaDecimalDigitCharacter (*String)) {\r
     //\r
     // If the Hex Number represented by String overflows according\r
-    // to the range defined by UINTN, then ASSERT().\r
+    // to the range defined by UINT64, then return EFI_DEVICE_ERROR.\r
     //\r
     if (!(Result <= (RShiftU64((((UINT64) ~0) - InternalShellHexCharToUintn (*String)), 4)))) {\r
 //    if (!(Result <= ((((UINT64) ~0) - InternalShellHexCharToUintn (*String)) >> 4))) {\r
@@ -3858,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
@@ -3888,15 +3944,18 @@ InternalShellStrDecimalToUint64 (
   Result = 0;\r
 \r
   //\r
-  // Skip spaces if requested\r
+  // Stop upon space if requested \r
+  // (if the whole value was 0)\r
   //\r
-  while (StopAtSpace && *String == L' ') {\r
-    String++;\r
+  if (StopAtSpace && *String == L' ') {\r
+    *Value = Result;\r
+    return (EFI_SUCCESS);\r
   }\r
+\r
   while (ShellIsDecimalDigitCharacter (*String)) {\r
     //\r
     // If the number represented by String overflows according\r
-    // to the range defined by UINT64, then ASSERT().\r
+    // to the range defined by UINT64, then return EFI_DEVICE_ERROR.\r
     //\r
 \r
     if (!(Result <= (DivU64x32((((UINT64) ~0) - (*String - L'0')),10)))) {\r
@@ -4057,6 +4116,9 @@ ShellFileHandleReturnLine(
     Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
 \r
   }\r
+  if (Status == EFI_END_OF_FILE && RetVal != NULL && *RetVal != CHAR_NULL) {\r
+    Status = EFI_SUCCESS;\r
+  }\r
   if (EFI_ERROR(Status) && (RetVal != NULL)) {\r
     FreePool(RetVal);\r
     RetVal = NULL;\r
@@ -4070,9 +4132,20 @@ ShellFileHandleReturnLine(
   If the position upon start is 0, then the Ascii Boolean will be set.  This should be\r
   maintained and not changed for all operations with the same file.\r
 \r
+  NOTE: LINES THAT ARE RETURNED BY THIS FUNCTION ARE UCS2, EVEN IF THE FILE BEING READ\r
+        IS IN ASCII FORMAT.\r
+\r
   @param[in]       Handle        SHELL_FILE_HANDLE to read from.\r
-  @param[in, out]  Buffer        The pointer to buffer to read into.\r
-  @param[in, out]  Size          The pointer to number of bytes in Buffer.\r
+  @param[in, out]  Buffer        The pointer to buffer to read into. If this function\r
+                                 returns EFI_SUCCESS, then on output Buffer will\r
+                                 contain a UCS2 string, even if the file being\r
+                                 read is ASCII.\r
+  @param[in, out]  Size          On input, pointer to number of bytes in Buffer.\r
+                                 On output, unchanged unless Buffer is too small\r
+                                 to contain the next line of the file. In that\r
+                                 case Size is set to the number of bytes needed\r
+                                 to hold the next line of the file (as a UCS2\r
+                                 string, even if it is an ASCII file).\r
   @param[in]       Truncate      If the buffer is large enough, this has no effect.\r
                                  If the buffer is is too small and Truncate is TRUE,\r
                                  the line will be truncated.\r
@@ -4084,6 +4157,7 @@ ShellFileHandleReturnLine(
 \r
   @retval EFI_SUCCESS           The operation was successful.  The line is stored in\r
                                 Buffer.\r
+  @retval EFI_END_OF_FILE       There are no more lines in the file.\r
   @retval EFI_INVALID_PARAMETER Handle was NULL.\r
   @retval EFI_INVALID_PARAMETER Size was NULL.\r
   @retval EFI_BUFFER_TOO_SMALL  Size was not large enough to store the line.\r
@@ -4129,19 +4203,22 @@ ShellFileHandleReadLine(
     }\r
   }\r
 \r
+  if (*Ascii) {\r
+    CharSize = sizeof(CHAR8);\r
+  } else {\r
+    CharSize = sizeof(CHAR16);\r
+  }\r
   for (CountSoFar = 0;;CountSoFar++){\r
     CharBuffer = 0;\r
-    if (*Ascii) {\r
-      CharSize = sizeof(CHAR8);\r
-    } else {\r
-      CharSize = sizeof(CHAR16);\r
-    }\r
     Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);\r
     if (  EFI_ERROR(Status)\r
        || CharSize == 0\r
        || (CharBuffer == L'\n' && !(*Ascii))\r
        || (CharBuffer ==  '\n' && *Ascii)\r
      ){\r
+      if (CharSize == 0) {\r
+        Status = EFI_END_OF_FILE;\r
+      }\r
       break;\r
     }\r
     //\r
@@ -4289,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