]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
ShellPkg: stop using EFI_HANDLE in place of EFI_HII_HANDLE
[mirror_edk2.git] / ShellPkg / Library / UefiShellCommandLib / UefiShellCommandLib.c
index 35e0611a8e4dcf12f0e249e2f976fa79463a9d12..4c48b65fbc1de21f5f200ab06ca5c56714a6a78c 100644 (file)
@@ -1,17 +1,11 @@
 /** @file\r
   Provides interface to shell internal functions for shell commands.\r
 \r
-  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-  (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
-  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
-
-  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
+  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
+  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -53,7 +47,7 @@ STATIC CONST CHAR8 Hex[] = {
 // global variables required by library class.\r
 EFI_UNICODE_COLLATION_PROTOCOL    *gUnicodeCollation            = NULL;\r
 SHELL_MAP_LIST                    gShellMapList;\r
-SHELL_MAP_LIST                    *gShellCurDir                 = NULL;\r
+SHELL_MAP_LIST                    *gShellCurMapping             = NULL;\r
 \r
 CONST CHAR16* SupportLevel[] = {\r
   L"Minimal",\r
@@ -72,14 +66,78 @@ CommandInit(
   VOID\r
   )\r
 {\r
-  EFI_STATUS Status;\r
+  UINTN                           NumHandles;\r
+  EFI_HANDLE                      *Handles;\r
+  EFI_UNICODE_COLLATION_PROTOCOL  *Uc;\r
+  CHAR8                           *BestLanguage;\r
+  UINTN                           Index;\r
+  EFI_STATUS                      Status;\r
+  CHAR8                           *PlatformLang;\r
+\r
   if (gUnicodeCollation == NULL) {\r
-    Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&gUnicodeCollation);\r
-    if (EFI_ERROR(Status)) {\r
-      return (EFI_DEVICE_ERROR);\r
+\r
+    GetEfiGlobalVariable2 (EFI_PLATFORM_LANG_VARIABLE_NAME, (VOID**)&PlatformLang, NULL);\r
+\r
+    Status = gBS->LocateHandleBuffer (\r
+                    ByProtocol,\r
+                    &gEfiUnicodeCollation2ProtocolGuid,\r
+                    NULL,\r
+                    &NumHandles,\r
+                    &Handles\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      NumHandles = 0;\r
+      Handles    = NULL;\r
+    }\r
+    for (Index = 0; Index < NumHandles; Index++) {\r
+      //\r
+      // Open Unicode Collation Protocol\r
+      //\r
+      Status = gBS->OpenProtocol (\r
+                      Handles[Index],\r
+                      &gEfiUnicodeCollation2ProtocolGuid,\r
+                      (VOID **) &Uc,\r
+                      gImageHandle,\r
+                      NULL,\r
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Without clue provided use the first Unicode Collation2 protocol.\r
+      //\r
+      if (PlatformLang == NULL) {\r
+        gUnicodeCollation = Uc;\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Find the best matching matching language from the supported languages\r
+      // of Unicode Collation2 protocol.\r
+      //\r
+      BestLanguage = GetBestLanguage (\r
+                       Uc->SupportedLanguages,\r
+                       FALSE,\r
+                       PlatformLang,\r
+                       NULL\r
+                       );\r
+      if (BestLanguage != NULL) {\r
+        FreePool (BestLanguage);\r
+        gUnicodeCollation = Uc;\r
+        break;\r
+      }\r
+    }\r
+    if (Handles != NULL) {\r
+      FreePool (Handles);\r
+    }\r
+    if (PlatformLang != NULL) {\r
+      FreePool (PlatformLang);\r
     }\r
   }\r
-  return (EFI_SUCCESS);\r
+\r
+  return (gUnicodeCollation == NULL) ? EFI_UNSUPPORTED : EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -112,11 +170,9 @@ ShellCommandLibConstructor (
   mProfileListSize  = 0;\r
   mProfileList      = NULL;\r
 \r
-  if (gUnicodeCollation == NULL) {\r
-    Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&gUnicodeCollation);\r
-    if (EFI_ERROR(Status)) {\r
-      return (EFI_DEVICE_ERROR);\r
-    }\r
+  Status = CommandInit ();\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
   return (RETURN_SUCCESS);\r
@@ -128,7 +184,6 @@ ShellCommandLibConstructor (
   @param[in] List     The list to free.\r
 **/\r
 VOID\r
-EFIAPI\r
 FreeFileHandleList (\r
   IN BUFFER_LIST *List\r
   )\r
@@ -230,7 +285,7 @@ ShellCommandLibDestructor (
   }\r
 \r
   gUnicodeCollation            = NULL;\r
-  gShellCurDir                 = NULL;\r
+  gShellCurMapping             = NULL;\r
 \r
   return (RETURN_SUCCESS);\r
 }\r
@@ -244,7 +299,6 @@ ShellCommandLibDestructor (
   @retval NULL          no dynamic command protocol instance found for name\r
 **/\r
 CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *\r
-EFIAPI\r
 ShellCommandFindDynamicCommand (\r
   IN CONST CHAR16 *CommandString\r
   )\r
@@ -259,7 +313,7 @@ ShellCommandFindDynamicCommand (
     //\r
     // not found or out of resources\r
     //\r
-    return NULL; \r
+    return NULL;\r
   }\r
 \r
   for (NextCommand = CommandHandleList; *NextCommand != NULL; NextCommand++) {\r
@@ -276,7 +330,7 @@ ShellCommandFindDynamicCommand (
     if (gUnicodeCollation->StriColl(\r
           gUnicodeCollation,\r
           (CHAR16*)CommandString,\r
-          (CHAR16*)DynamicCommand->CommandName) == 0 \r
+          (CHAR16*)DynamicCommand->CommandName) == 0\r
           ){\r
         FreePool(CommandHandleList);\r
         return (DynamicCommand);\r
@@ -293,7 +347,6 @@ ShellCommandFindDynamicCommand (
   @param[in] CommandString        The command string to check for on the list.\r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 ShellCommandDynamicCommandExists (\r
   IN CONST CHAR16 *CommandString\r
   )\r
@@ -307,7 +360,6 @@ ShellCommandDynamicCommandExists (
   @param[in] CommandString        The command string to check for on the list.\r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 ShellCommandIsCommandOnInternalList(\r
   IN CONST  CHAR16 *CommandString\r
   )\r
@@ -365,7 +417,6 @@ ShellCommandIsCommandOnList(
   @return       String of help text. Caller required to free.\r
 **/\r
 CHAR16*\r
-EFIAPI\r
 ShellCommandGetDynamicCommandHelp(\r
   IN CONST  CHAR16                      *CommandString\r
   )\r
@@ -380,7 +431,7 @@ ShellCommandGetDynamicCommandHelp(
   //\r
   // TODO: how to get proper language?\r
   //\r
-  return DynamicCommand->GetHelp(DynamicCommand, "en"); \r
+  return DynamicCommand->GetHelp(DynamicCommand, "en");\r
 }\r
 \r
 /**\r
@@ -392,7 +443,6 @@ ShellCommandGetDynamicCommandHelp(
   @return       String of help text. Caller reuiqred to free.\r
 **/\r
 CHAR16*\r
-EFIAPI\r
 ShellCommandGetInternalCommandHelp(\r
   IN CONST  CHAR16                      *CommandString\r
   )\r
@@ -504,7 +554,7 @@ ShellCommandRegisterCommandName (
   IN        UINT32                      ShellMinSupportLevel,\r
   IN CONST  CHAR16                      *ProfileName,\r
   IN CONST  BOOLEAN                     CanAffectLE,\r
-  IN CONST  EFI_HANDLE                  HiiHandle,\r
+  IN CONST  EFI_HII_HANDLE              HiiHandle,\r
   IN CONST  EFI_STRING_ID               ManFormatHelp\r
   )\r
 {\r
@@ -799,7 +849,7 @@ ShellCommandRegisterAlias (
 {\r
   ALIAS_LIST *Node;\r
   ALIAS_LIST *CommandAlias;\r
-  ALIAS_LIST *PrevCommandAlias; \r
+  ALIAS_LIST *PrevCommandAlias;\r
   INTN       LexicalMatchValue;\r
 \r
   //\r
@@ -848,7 +898,7 @@ ShellCommandRegisterAlias (
     //\r
     // Swap PrevCommandAlias and CommandAlias list entry if PrevCommandAlias list entry\r
     // is alphabetically greater than CommandAlias list entry\r
-    // \r
+    //\r
     if (LexicalMatchValue > 0) {\r
       CommandAlias = (ALIAS_LIST *) SwapListEntries (&PrevCommandAlias->Link, &CommandAlias->Link);\r
     } else if (LexicalMatchValue < 0) {\r
@@ -1227,10 +1277,8 @@ ShellCommandAddMapItemAndUpdatePath(
     ASSERT((NewPath == NULL && NewPathSize == 0) || (NewPath != NULL));\r
     if (OriginalPath != NULL) {\r
       StrnCatGrow(&NewPath, &NewPathSize, OriginalPath, 0);\r
-    } else {\r
-      StrnCatGrow(&NewPath, &NewPathSize, L".\\", 0);\r
+      StrnCatGrow(&NewPath, &NewPathSize, L";", 0);\r
     }\r
-    StrnCatGrow(&NewPath, &NewPathSize, L";", 0);\r
     StrnCatGrow(&NewPath, &NewPathSize, Name, 0);\r
     StrnCatGrow(&NewPath, &NewPathSize, L"\\efi\\tools\\;", 0);\r
     StrnCatGrow(&NewPath, &NewPathSize, Name, 0);\r
@@ -1276,7 +1324,14 @@ ShellCommandCreateInitialMappingsAndPaths(
   CHAR16                    *NewConsistName;\r
   EFI_DEVICE_PATH_PROTOCOL  **ConsistMappingTable;\r
   SHELL_MAP_LIST            *MapListNode;\r
-\r
+  CONST CHAR16              *CurDir;\r
+  CHAR16                    *SplitCurDir;\r
+  CHAR16                    *MapName;\r
+  SHELL_MAP_LIST            *MapListItem;\r
+\r
+  SplitCurDir = NULL;\r
+  MapName     = NULL;\r
+  MapListItem = NULL;\r
   HandleList  = NULL;\r
 \r
   //\r
@@ -1362,6 +1417,33 @@ ShellCommandCreateInitialMappingsAndPaths(
     SHELL_FREE_NON_NULL(DevicePathList);\r
 \r
     HandleList = NULL;\r
+\r
+    //\r
+    //gShellCurMapping point to node of current file system in the gShellMapList. When reset all mappings,\r
+    //all nodes in the gShellMapList will be free. Then gShellCurMapping will be a dangling pointer, So,\r
+    //after created new mappings, we should reset the gShellCurMapping pointer back to node of current file system.\r
+    //\r
+    if (gShellCurMapping != NULL) {\r
+      gShellCurMapping = NULL;\r
+      CurDir = gEfiShellProtocol->GetEnv(L"cwd");\r
+      if (CurDir != NULL) {\r
+        MapName = AllocateCopyPool (StrSize(CurDir), CurDir);\r
+        if (MapName == NULL) {\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+        SplitCurDir = StrStr (MapName, L":");\r
+        if (SplitCurDir == NULL) {\r
+          SHELL_FREE_NON_NULL (MapName);\r
+          return EFI_UNSUPPORTED;\r
+        }\r
+        *(SplitCurDir + 1) = CHAR_NULL;\r
+        MapListItem = ShellCommandFindMapItem (MapName);\r
+        if (MapListItem != NULL) {\r
+          gShellCurMapping = MapListItem;\r
+        }\r
+        SHELL_FREE_NON_NULL (MapName);\r
+      }\r
+    }\r
   } else {\r
     Count = (UINTN)-1;\r
   }\r
@@ -1723,6 +1805,7 @@ FreeBufferList (
   @param[in] UserData   The data to print out.\r
 **/\r
 VOID\r
+EFIAPI\r
 DumpHex (\r
   IN UINTN        Indent,\r
   IN UINTN        Offset,\r
@@ -1752,7 +1835,7 @@ DumpHex (
       Val[Index * 3 + 0]  = Hex[TempByte >> 4];\r
       Val[Index * 3 + 1]  = Hex[TempByte & 0xF];\r
       Val[Index * 3 + 2]  = (CHAR8) ((Index == 7) ? '-' : ' ');\r
-      Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r
+      Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > '~') ? '.' : TempByte);\r
     }\r
 \r
     Val[Index * 3]  = 0;\r
@@ -1764,60 +1847,61 @@ DumpHex (
     DataSize -= Size;\r
   }\r
 }\r
-
-/**
-  Dump HEX data into buffer.
-   
-  @param[in] Buffer     HEX data to be dumped in Buffer.
-  @param[in] Indent     How many spaces to indent the output.
-  @param[in] Offset     The offset of the printing.
-  @param[in] DataSize   The size in bytes of UserData.
-  @param[in] UserData   The data to print out.
-**/
-CHAR16*
-CatSDumpHex (
-  IN CHAR16  *Buffer,
-  IN UINTN   Indent,
-  IN UINTN   Offset,
-  IN UINTN   DataSize,
-  IN VOID    *UserData
-  )
-{
-  UINT8   *Data;
-  UINT8   TempByte;
-  UINTN   Size;
-  UINTN   Index;
-  CHAR8   Val[50];
-  CHAR8   Str[20];
-  CHAR16  *RetVal;
-  CHAR16  *TempRetVal;
-
-  Data = UserData;
-  RetVal = Buffer;
-  while (DataSize != 0) {
-    Size = 16;
-    if (Size > DataSize) {
-      Size = DataSize;
-    }
-
-    for (Index = 0; Index < Size; Index += 1) {
-      TempByte            = Data[Index];
-      Val[Index * 3 + 0]  = Hex[TempByte >> 4];
-      Val[Index * 3 + 1]  = Hex[TempByte & 0xF];
-      Val[Index * 3 + 2]  = (CHAR8) ((Index == 7) ? '-' : ' ');
-      Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
-    }
-
-    Val[Index * 3]  = 0;
-    Str[Index]      = 0;
-    TempRetVal = CatSPrint (RetVal, L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);
-    SHELL_FREE_NON_NULL (RetVal);
-    RetVal = TempRetVal;
-
-    Data += Size;
-    Offset += Size;
-    DataSize -= Size;
-  }
-
-  return RetVal;
-}
+\r
+/**\r
+  Dump HEX data into buffer.\r
+\r
+  @param[in] Buffer     HEX data to be dumped in Buffer.\r
+  @param[in] Indent     How many spaces to indent the output.\r
+  @param[in] Offset     The offset of the printing.\r
+  @param[in] DataSize   The size in bytes of UserData.\r
+  @param[in] UserData   The data to print out.\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+CatSDumpHex (\r
+  IN CHAR16  *Buffer,\r
+  IN UINTN   Indent,\r
+  IN UINTN   Offset,\r
+  IN UINTN   DataSize,\r
+  IN VOID    *UserData\r
+  )\r
+{\r
+  UINT8   *Data;\r
+  UINT8   TempByte;\r
+  UINTN   Size;\r
+  UINTN   Index;\r
+  CHAR8   Val[50];\r
+  CHAR8   Str[20];\r
+  CHAR16  *RetVal;\r
+  CHAR16  *TempRetVal;\r
+\r
+  Data = UserData;\r
+  RetVal = Buffer;\r
+  while (DataSize != 0) {\r
+    Size = 16;\r
+    if (Size > DataSize) {\r
+      Size = DataSize;\r
+    }\r
+\r
+    for (Index = 0; Index < Size; Index += 1) {\r
+      TempByte            = Data[Index];\r
+      Val[Index * 3 + 0]  = Hex[TempByte >> 4];\r
+      Val[Index * 3 + 1]  = Hex[TempByte & 0xF];\r
+      Val[Index * 3 + 2]  = (CHAR8) ((Index == 7) ? '-' : ' ');\r
+      Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r
+    }\r
+\r
+    Val[Index * 3]  = 0;\r
+    Str[Index]      = 0;\r
+    TempRetVal = CatSPrint (RetVal, L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);\r
+    SHELL_FREE_NON_NULL (RetVal);\r
+    RetVal = TempRetVal;\r
+\r
+    Data += Size;\r
+    Offset += Size;\r
+    DataSize -= Size;\r
+  }\r
+\r
+  return RetVal;\r
+}\r