/** @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
- 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
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
// 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
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
- }\r
- return (EFI_SUCCESS);\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
-/**\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
+ if (gUnicodeCollation == NULL) {\r
\r
- for (WalkStr = 0; WalkStr < StrLen (String); WalkStr++) {\r
- if (IgnoreEscapedCharacter && (String[WalkStr] == L'^')) {\r
- WalkStr++;\r
- continue;\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 (WalkChar = 0; WalkChar < StrLen (CharacterList); WalkChar++) {\r
- if (String[WalkStr] == CharacterList[WalkChar]) {\r
- return &String[WalkStr];\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
- 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
//\r
- // eliminate the escape ^\r
+ // Without clue provided use the first Unicode Collation2 protocol.\r
//\r
- CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));\r
- NextDelim++;\r
- } else if (*NextDelim == L'\"') {\r
+ if (PlatformLang == NULL) {\r
+ gUnicodeCollation = Uc;\r
+ break;\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
+ if (PlatformLang != NULL) {\r
+ FreePool (PlatformLang);\r
+ }\r
}\r
\r
- return EFI_SUCCESS;\r
+ return (gUnicodeCollation == NULL) ? EFI_UNSUPPORTED : EFI_SUCCESS;\r
}\r
\r
/**\r
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
@param[in] List The list to free.\r
**/\r
VOID\r
-EFIAPI\r
FreeFileHandleList (\r
IN BUFFER_LIST *List\r
)\r
}\r
\r
gUnicodeCollation = NULL;\r
- gShellCurDir = NULL;\r
+ gShellCurMapping = NULL;\r
\r
return (RETURN_SUCCESS);\r
}\r
@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
//\r
// not found or out of resources\r
//\r
- return NULL; \r
+ return NULL;\r
}\r
\r
for (NextCommand = CommandHandleList; *NextCommand != NULL; NextCommand++) {\r
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
@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
@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
@return String of help text. Caller required to free.\r
**/\r
CHAR16*\r
-EFIAPI\r
ShellCommandGetDynamicCommandHelp(\r
IN CONST CHAR16 *CommandString\r
)\r
//\r
// TODO: how to get proper language?\r
//\r
- return DynamicCommand->GetHelp(DynamicCommand, "en"); \r
+ return DynamicCommand->GetHelp(DynamicCommand, "en");\r
}\r
\r
/**\r
@return String of help text. Caller reuiqred to free.\r
**/\r
CHAR16*\r
-EFIAPI\r
ShellCommandGetInternalCommandHelp(\r
IN CONST CHAR16 *CommandString\r
)\r
{\r
ALIAS_LIST *Node;\r
ALIAS_LIST *CommandAlias;\r
- ALIAS_LIST *PrevCommandAlias; \r
+ ALIAS_LIST *PrevCommandAlias;\r
INTN LexicalMatchValue;\r
\r
//\r
//\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
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
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
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
@param[in] UserData The data to print out.\r
**/\r
VOID\r
+EFIAPI\r
DumpHex (\r
IN UINTN Indent,\r
IN UINTN Offset,\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
+ Str[Index] = (CHAR8) ((TempByte < ' ' || TempByte > '~') ? '.' : TempByte);\r
}\r
\r
Val[Index * 3] = 0;\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