]> 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 ac77111ef93c6630e9d53214cd1c527f09e0d989..ddc4bb1567c6e52eab7abd50fc8c0e85a5097bf5 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,199 +72,70 @@ CommandInit(
   VOID\r
   )\r
 {\r
-  EFI_STATUS Status;\r
-  if (gUnicodeCollation == NULL) {\r
-    Status = gBS->LocateProtocol(&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&gUnicodeCollation);\r
-    if (EFI_ERROR(Status)) {\r
-      return (EFI_DEVICE_ERROR);\r
-    }\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
-  return (EFI_SUCCESS);\r
-}\r
-\r
-/**\r
-  Return the pointer to the first occurrence of any character from a list of characters.\r
-\r
-  @param[in] String                 The string to parse\r
-  @param[in] CharacterList          The list of character to look for\r
-  @param[in] IgnoreEscapedCharacter TRUE to ignore escaped characters\r
-\r
-  @return The location of the first character in the String.\r
-  @return Pointer to the ending NULL character of the String.\r
-**/\r
-CONST CHAR16*\r
-EFIAPI\r
-ShellFindFirstCharacter (\r
-  IN CONST CHAR16  *String,\r
-  IN CONST CHAR16  *CharacterList,\r
-  IN CONST BOOLEAN IgnoreEscapedCharacter\r
-  )\r
-{\r
-  UINTN WalkChar;\r
-  UINTN WalkStr;\r
 \r
-  for (WalkStr = 0; WalkStr < StrLen (String); WalkStr++) {\r
-    if (IgnoreEscapedCharacter && (String[WalkStr] == L'^')) {\r
-      WalkStr++;\r
-      continue;\r
-    }\r
-    for (WalkChar = 0; WalkChar < StrLen (CharacterList); WalkChar++) {\r
-      if (String[WalkStr] == CharacterList[WalkChar]) {\r
-        return &String[WalkStr];\r
-      }\r
+  if (gUnicodeCollation == NULL) {\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
-  }\r
-  return &String[WalkStr];\r
-}\r
-\r
-/**\r
-  Return the next parameter's end from a command line string.\r
-\r
-  @param[in] String        the string to parse\r
-**/\r
-CONST CHAR16*\r
-FindEndOfParameter(\r
-  IN CONST CHAR16 *String\r
-  )\r
-{\r
-  CONST CHAR16 *First;\r
-  CONST CHAR16 *CloseQuote;\r
-\r
-  First = ShellFindFirstCharacter (String, L" \"", TRUE);\r
-\r
-  //\r
-  // nothing, all one parameter remaining\r
-  //\r
-  if (*First == CHAR_NULL) {\r
-    return (First);\r
-  }\r
-\r
-  //\r
-  // If space before a quote (or neither found, i.e. both CHAR_NULL),\r
-  // then that's the end.\r
-  //\r
-  if (*First == L' ') {\r
-    return (First);\r
-  }\r
-\r
-  CloseQuote = ShellFindFirstCharacter (First+1, L"\"", TRUE);\r
-\r
-  //\r
-  // We did not find a terminator...\r
-  //\r
-  if (*CloseQuote == CHAR_NULL) {\r
-    return (NULL);\r
-  }\r
-\r
-  return (FindEndOfParameter (CloseQuote+1));\r
-}\r
-\r
-/**\r
-  Return the next parameter from a command line string.\r
-\r
-  This function moves the next parameter from Walker into NextParameter and moves\r
-  Walker up past that parameter for recursive calling.  When the final parameter\r
-  is moved *Walker will be set to NULL;\r
-\r
-  This will also remove all remaining ^ characters after processing.\r
-\r
-  @param[in, out] Walker          pointer to string of command line.  Adjusted to\r
-                                  reminaing command line on return\r
-  @param[in, out] NextParameter   pointer to string of command line item extracted.\r
-  @param[in]      Length          buffer size of TempParameter.\r
-  @param[in]      StripQuotation  if TRUE then strip the quotation marks surrounding\r
-                                  the parameters.\r
-\r
-  @return   EFI_INALID_PARAMETER  A required parameter was NULL or pointed to a NULL or empty string.\r
-  @return   EFI_NOT_FOUND         A closing " could not be found on the specified string\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ShellGetNextParameter (\r
-  IN OUT CHAR16   **Walker,\r
-  IN OUT CHAR16   *NextParameter,\r
-  IN CONST UINTN  Length,\r
-  IN BOOLEAN      StripQuotation\r
-  )\r
-{\r
-  CONST CHAR16 *NextDelim;\r
-\r
-  if (Walker           == NULL\r
-    ||*Walker          == NULL\r
-    ||NextParameter    == NULL\r
-    ){\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // make sure we dont have any leading spaces\r
-  //\r
-  while ((*Walker)[0] == L' ') {\r
-    (*Walker)++;\r
-  }\r
-\r
-  //\r
-  // make sure we still have some params now...\r
-  //\r
-  if (StrLen(*Walker) == 0) {\r
-    DEBUG_CODE (\r
-      *Walker = NULL;\r
-    );\r
-    return (EFI_INVALID_PARAMETER);\r
-  }\r
-\r
-  NextDelim = FindEndOfParameter(*Walker);\r
-\r
-  if (NextDelim == NULL){\r
-    DEBUG_CODE (\r
-      *Walker = NULL;\r
-    );\r
-    return (EFI_NOT_FOUND);\r
-  }\r
-\r
-  StrnCpyS(NextParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker);\r
-\r
-  //\r
-  // Add a CHAR_NULL if we didnt get one via the copy\r
-  //\r
-  if (*NextDelim != CHAR_NULL) {\r
-    NextParameter[NextDelim - *Walker] = CHAR_NULL;\r
-  }\r
-\r
-  //\r
-  // Update Walker for the next iteration through the function\r
-  //\r
-  *Walker = (CHAR16*)NextDelim;\r
-\r
-  //\r
-  // Remove any non-escaped quotes in the string\r
-  // Remove any remaining escape characters in the string\r
-  //\r
-  for (NextDelim = ShellFindFirstCharacter(NextParameter, L"\"^", FALSE)\r
-    ; *NextDelim != CHAR_NULL\r
-    ; NextDelim = ShellFindFirstCharacter(NextDelim, L"\"^", FALSE)\r
-    ) {\r
-    if (*NextDelim == L'^') {\r
-\r
+    for (Index = 0; Index < NumHandles; Index++) {\r
       //\r
-      // eliminate the escape ^\r
+      // Open Unicode Collation Protocol\r
       //\r
-      CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));\r
-      NextDelim++;\r
-    } else if (*NextDelim == L'\"') {\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
-      // eliminate the unescaped quote\r
+      // Find the best matching matching language from the supported languages\r
+      // of Unicode Collation2 protocol.\r
       //\r
-      if (StripQuotation) {\r
-        CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));\r
-      } else {\r
-        NextDelim++;\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
 \r
-  return EFI_SUCCESS;\r
+  return (gUnicodeCollation == NULL) ? EFI_UNSUPPORTED : EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -297,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
@@ -313,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
@@ -415,7 +283,7 @@ ShellCommandLibDestructor (
   }\r
 \r
   gUnicodeCollation            = NULL;\r
-  gShellCurDir                 = NULL;\r
+  gShellCurMapping             = NULL;\r
 \r
   return (RETURN_SUCCESS);\r
 }\r
@@ -429,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
@@ -444,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
@@ -461,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
@@ -478,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
@@ -492,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
@@ -550,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
@@ -565,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
@@ -577,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
@@ -984,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
@@ -1033,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
@@ -1412,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
@@ -1461,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
@@ -1547,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
@@ -1908,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
@@ -1937,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
@@ -1960,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