]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
ShellPkg: Clean up source files
[mirror_edk2.git] / ShellPkg / Library / UefiShellCommandLib / UefiShellCommandLib.c
index 35e0611a8e4dcf12f0e249e2f976fa79463a9d12..ddc4bb1567c6e52eab7abd50fc8c0e85a5097bf5 100644 (file)
@@ -1,10 +1,10 @@
 /** @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>
-
+  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
   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
@@ -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
@@ -259,7 +311,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 +328,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 +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
@@ -380,7 +429,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 +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
@@ -799,7 +847,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 +896,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 +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
@@ -1764,60 +1845,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