]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
ShellPkg/CommandLib: Locate proper UnicodeCollation instance
[mirror_edk2.git] / ShellPkg / Library / UefiShellCommandLib / UefiShellCommandLib.c
index a97361c407d479eb660be24097716ee5bb9f6e61..0df252b42036901458cd7168c27c4f88e00531c6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Provides interface to shell internal functions for shell commands.\r
 \r
-  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\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
@@ -53,7 +53,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 +72,70 @@ 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
+  GetEfiGlobalVariable2 (EFI_PLATFORM_LANG_VARIABLE_NAME, (VOID**)&PlatformLang, NULL);\r
+  if (PlatformLang == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   if (gUnicodeCollation == NULL) {\r
-    Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&gUnicodeCollation);\r
-    if (EFI_ERROR(Status)) {\r
-      return (EFI_DEVICE_ERROR);\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
+      // 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
+    FreePool (PlatformLang);\r
   }\r
-  return (EFI_SUCCESS);\r
+\r
+  return (gUnicodeCollation == NULL) ? EFI_UNSUPPORTED : EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -112,11 +168,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 +182,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 +283,7 @@ ShellCommandLibDestructor (
   }\r
 \r
   gUnicodeCollation            = NULL;\r
-  gShellCurDir                 = NULL;\r
+  gShellCurMapping             = NULL;\r
 \r
   return (RETURN_SUCCESS);\r
 }\r
@@ -244,7 +297,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
@@ -293,7 +345,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 +358,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 +415,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
@@ -392,7 +441,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
@@ -1227,10 +1275,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 +1322,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 +1415,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 +1803,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 +1833,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
@@ -1775,6 +1856,7 @@ DumpHex (
   @param[in] UserData   The data to print out.\r
 **/\r
 CHAR16*\r
+EFIAPI\r
 CatSDumpHex (\r
   IN CHAR16  *Buffer,\r
   IN UINTN   Indent,\r