STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";\r
STATIC CONST CHAR16 mStartupScript[] = L"startup.nsh";\r
\r
+/**\r
+ Cleans off leading and trailing spaces and tabs\r
+\r
+ @param[in] String pointer to the string to trim them off\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TrimSpaces(\r
+ IN CHAR16 **String\r
+ )\r
+{\r
+ ASSERT(String != NULL);\r
+ ASSERT(*String!= NULL);\r
+ //\r
+ // Remove any spaces and tabs at the beginning of the (*String).\r
+ //\r
+ while (((*String)[0] == L' ') || ((*String)[0] == L'\t')) {\r
+ CopyMem((*String), (*String)+1, StrSize((*String)) - sizeof((*String)[0]));\r
+ }\r
+\r
+ //\r
+ // Remove any spaces at the end of the (*String).\r
+ //\r
+ while ((*String)[StrLen((*String))-1] == L' ') {\r
+ (*String)[StrLen((*String))-1] = CHAR_NULL;\r
+ }\r
+\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Find a command line contains a split operation\r
+\r
+ @param[in] CmdLine The command line to parse.\r
+\r
+ @retval A pointer to the | character in CmdLine or NULL if not present.\r
+**/\r
+CONST\r
+CHAR16*\r
+EFIAPI\r
+FindSplit(\r
+ IN CONST CHAR16 *CmdLine\r
+ )\r
+{\r
+ CONST CHAR16 *TempSpot;\r
+ TempSpot = NULL;\r
+ if (StrStr(CmdLine, L"|") != NULL) {\r
+ for (TempSpot = CmdLine ; TempSpot != NULL && *TempSpot != CHAR_NULL ; TempSpot++) {\r
+ if (*TempSpot == L'^' && *(TempSpot+1) == L'|') {\r
+ TempSpot++;\r
+ } else if (*TempSpot == L'|') {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ return (TempSpot);\r
+}\r
+\r
+/**\r
+ Determine if a command line contains a split operation\r
+\r
+ @param[in] CmdLine The command line to parse.\r
+\r
+ @retval TRUE CmdLine has a valid split.\r
+ @retval FALSE CmdLine does not have a valid split.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ContainsSplit(\r
+ IN CONST CHAR16 *CmdLine\r
+ )\r
+{\r
+ CONST CHAR16 *TempSpot;\r
+ TempSpot = FindSplit(CmdLine);\r
+ return (TempSpot != NULL && *TempSpot != CHAR_NULL);\r
+}\r
+\r
/**\r
Function to start monitoring for CTRL-S using SimpleTextInputEx. This \r
feature's enabled state was not known when the shell initially launched.\r
SimpleEx,\r
&KeyData,\r
NotificationFunction,\r
- &ShellInfoObject.CtrlSNotifyHandle2);\r
+ &ShellInfoObject.CtrlSNotifyHandle3);\r
} \r
KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
if (!EFI_ERROR(Status)) {\r
SimpleEx,\r
&KeyData,\r
NotificationFunction,\r
- &ShellInfoObject.CtrlSNotifyHandle2);\r
+ &ShellInfoObject.CtrlSNotifyHandle4);\r
}\r
return (Status);\r
}\r
return (Status);\r
}\r
\r
+/**\r
+ Take the original command line, substitute any variables, free \r
+ the original string, return the modified copy\r
+\r
+ @param[in] CmdLine pointer to the command line to update\r
+ @param[out]CmdName upon successful return the name of the command to be run\r
+\r
+ @retval EFI_SUCCESS the function was successful\r
+ @retval EFI_OUT_OF_RESOURCES a memory allocation failed\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellSubstituteVariables(\r
+ IN CHAR16 **CmdLine\r
+ )\r
+{\r
+ CHAR16 *NewCmdLine;\r
+ NewCmdLine = ShellConvertVariables(*CmdLine);\r
+ SHELL_FREE_NON_NULL(*CmdLine);\r
+ if (NewCmdLine == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ *CmdLine = NewCmdLine;\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+ Take the original command line, substitute any alias in the first group of space delimited characters, free \r
+ the original string, return the modified copy\r
+\r
+ @param[in] CmdLine pointer to the command line to update\r
+ @param[out]CmdName upon successful return the name of the command to be run\r
+\r
+ @retval EFI_SUCCESS the function was successful\r
+ @retval EFI_OUT_OF_RESOURCES a memory allocation failed\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellSubstituteAliases(\r
+ IN CHAR16 **CmdLine\r
+ )\r
+{\r
+ CHAR16 *NewCmdLine;\r
+ CHAR16 *CommandName;\r
+ EFI_STATUS Status;\r
+ UINTN PostAliasSize;\r
+ ASSERT(CmdLine != NULL);\r
+ ASSERT(*CmdLine!= NULL);\r
+\r
+\r
+ CommandName = NULL;\r
+ if (StrStr((*CmdLine), L" ") == NULL){\r
+ StrnCatGrow(&CommandName, NULL, (*CmdLine), 0);\r
+ } else {\r
+ StrnCatGrow(&CommandName, NULL, (*CmdLine), StrStr((*CmdLine), L" ") - (*CmdLine));\r
+ }\r
+\r
+ //\r
+ // This cannot happen 'inline' since the CmdLine can need extra space.\r
+ //\r
+ NewCmdLine = NULL;\r
+ if (!ShellCommandIsCommandOnList(CommandName)) {\r
+ //\r
+ // Convert via alias\r
+ //\r
+ Status = ShellConvertAlias(&CommandName);\r
+ if (EFI_ERROR(Status)){\r
+ return (Status);\r
+ }\r
+ PostAliasSize = 0;\r
+ NewCmdLine = StrnCatGrow(&NewCmdLine, &PostAliasSize, CommandName, 0);\r
+ if (NewCmdLine == NULL) {\r
+ SHELL_FREE_NON_NULL(CommandName);\r
+ SHELL_FREE_NON_NULL(*CmdLine);\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ NewCmdLine = StrnCatGrow(&NewCmdLine, &PostAliasSize, StrStr((*CmdLine), L" "), 0);\r
+ if (NewCmdLine == NULL) {\r
+ SHELL_FREE_NON_NULL(CommandName);\r
+ SHELL_FREE_NON_NULL(*CmdLine);\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ } else {\r
+ NewCmdLine = StrnCatGrow(&NewCmdLine, NULL, (*CmdLine), 0);\r
+ }\r
+\r
+ SHELL_FREE_NON_NULL(*CmdLine);\r
+ SHELL_FREE_NON_NULL(CommandName);\r
+ \r
+ //\r
+ // re-assign the passed in double pointer to point to our newly allocated buffer\r
+ //\r
+ *CmdLine = NewCmdLine;\r
+\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
/**\r
Function will process and run a command line.\r
\r
CHAR16 **Argv;\r
BOOLEAN LastError;\r
CHAR16 LeString[19];\r
- CHAR16 *PostAliasCmdLine;\r
- UINTN PostAliasSize;\r
- CHAR16 *PostVariableCmdLine;\r
CHAR16 *CommandWithPath;\r
CONST EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
CONST CHAR16 *TempLocation;\r
SHELL_FILE_HANDLE OriginalStdOut;\r
SHELL_FILE_HANDLE OriginalStdErr;\r
SYSTEM_TABLE_INFO OriginalSystemTableInfo;\r
- CHAR16 *TempLocation3;\r
UINTN Count;\r
UINTN Count2;\r
CHAR16 *CleanOriginal;\r
}\r
\r
CommandName = NULL;\r
- PostVariableCmdLine = NULL;\r
- PostAliasCmdLine = NULL;\r
CommandWithPath = NULL;\r
DevPath = NULL;\r
Status = EFI_SUCCESS;\r
return (EFI_OUT_OF_RESOURCES);\r
}\r
\r
- //\r
- // Remove any spaces and tabs at the beginning of the string.\r
- //\r
- while ((CleanOriginal[0] == L' ') || (CleanOriginal[0] == L'\t')) {\r
- CopyMem(CleanOriginal, CleanOriginal+1, StrSize(CleanOriginal) - sizeof(CleanOriginal[0]));\r
- }\r
+ TrimSpaces(&CleanOriginal);\r
\r
//\r
// Handle case that passed in command line is just 1 or more " " characters.\r
return (EFI_SUCCESS);\r
}\r
\r
- //\r
- // Remove any spaces at the end of the string.\r
- //\r
- while (CleanOriginal[StrLen(CleanOriginal)-1] == L' ') {\r
- CleanOriginal[StrLen(CleanOriginal)-1] = CHAR_NULL;\r
- }\r
-\r
- CommandName = NULL;\r
- if (StrStr(CleanOriginal, L" ") == NULL){\r
- StrnCatGrow(&CommandName, NULL, CleanOriginal, 0);\r
- } else {\r
- StrnCatGrow(&CommandName, NULL, CleanOriginal, StrStr(CleanOriginal, L" ") - CleanOriginal);\r
- }\r
-\r
- ASSERT(PostAliasCmdLine == NULL);\r
- if (!ShellCommandIsCommandOnList(CommandName)) {\r
- //\r
- // Convert via alias\r
- //\r
- Status = ShellConvertAlias(&CommandName);\r
- PostAliasSize = 0;\r
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, &PostAliasSize, CommandName, 0);\r
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, &PostAliasSize, StrStr(CleanOriginal, L" "), 0);\r
- ASSERT_EFI_ERROR(Status);\r
- } else {\r
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, NULL, CleanOriginal, 0);\r
- }\r
-\r
- if (CleanOriginal != NULL) {\r
- FreePool(CleanOriginal);\r
- CleanOriginal = NULL;\r
- }\r
-\r
- if (CommandName != NULL) {\r
- FreePool(CommandName);\r
- CommandName = NULL;\r
- }\r
-\r
- PostVariableCmdLine = ShellConvertVariables(PostAliasCmdLine);\r
-\r
- //\r
- // we can now free the modified by alias command line\r
- //\r
- if (PostAliasCmdLine != NULL) {\r
- FreePool(PostAliasCmdLine);\r
- PostAliasCmdLine = NULL;\r
+ Status = ShellSubstituteAliases(&CleanOriginal);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
}\r
\r
- if (PostVariableCmdLine == NULL) {\r
- return (EFI_OUT_OF_RESOURCES);\r
+ Status = ShellSubstituteVariables(&CleanOriginal);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
}\r
\r
- while (PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] == L' ') {\r
- PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] = CHAR_NULL;\r
- }\r
- while (PostVariableCmdLine[0] == L' ') {\r
- CopyMem(PostVariableCmdLine, PostVariableCmdLine+1, StrSize(PostVariableCmdLine) - sizeof(PostVariableCmdLine[0]));\r
- }\r
+ TrimSpaces(&CleanOriginal);\r
\r
//\r
// We dont do normal processing with a split command line (output from one command input to another)\r
//\r
- TempLocation3 = NULL;\r
- if (StrStr(PostVariableCmdLine, L"|") != NULL) {\r
- for (TempLocation3 = PostVariableCmdLine ; TempLocation3 != NULL && *TempLocation3 != CHAR_NULL ; TempLocation3++) {\r
- if (*TempLocation3 == L'^' && *(TempLocation3+1) == L'|') {\r
- TempLocation3++;\r
- } else if (*TempLocation3 == L'|') {\r
- break;\r
- }\r
- }\r
- }\r
- if (TempLocation3 != NULL && *TempLocation3 != CHAR_NULL) {\r
+ if (ContainsSplit(CleanOriginal)) {\r
//\r
// are we in an existing split???\r
//\r
}\r
\r
if (Split == NULL) {\r
- Status = RunSplitCommand(PostVariableCmdLine, NULL, NULL);\r
+ Status = RunSplitCommand(CleanOriginal, NULL, NULL);\r
} else {\r
- Status = RunSplitCommand(PostVariableCmdLine, Split->SplitStdIn, Split->SplitStdOut);\r
+ Status = RunSplitCommand(CleanOriginal, Split->SplitStdIn, Split->SplitStdOut);\r
}\r
if (EFI_ERROR(Status)) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, PostVariableCmdLine);\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, CleanOriginal);\r
}\r
} else {\r
\r
//\r
// If this is a mapped drive change handle that...\r
//\r
- if (PostVariableCmdLine[(StrLen(PostVariableCmdLine)-1)] == L':' && StrStr(PostVariableCmdLine, L" ") == NULL) {\r
- Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir(NULL, PostVariableCmdLine);\r
+ if (CleanOriginal[(StrLen(CleanOriginal)-1)] == L':' && StrStr(CleanOriginal, L" ") == NULL) {\r
+ Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir(NULL, CleanOriginal);\r
if (EFI_ERROR(Status)) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, PostVariableCmdLine);\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, CleanOriginal);\r
}\r
- FreePool(PostVariableCmdLine);\r
+ FreePool(CleanOriginal);\r
return (Status);\r
}\r
\r
\r
\r
\r
- Status = UpdateStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);\r
+ Status = UpdateStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, CleanOriginal, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);\r
if (EFI_ERROR(Status)) {\r
if (Status == EFI_NOT_FOUND) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);\r
}\r
} else {\r
- while (PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] == L' ') {\r
- PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] = CHAR_NULL;\r
- }\r
- while (PostVariableCmdLine[0] == L' ') {\r
- CopyMem(PostVariableCmdLine, PostVariableCmdLine+1, StrSize(PostVariableCmdLine) - sizeof(PostVariableCmdLine[0]));\r
- }\r
-\r
+ TrimSpaces(&CleanOriginal);\r
+ \r
//\r
// get the argc and argv updated for internal commands\r
//\r
- Status = UpdateArgcArgv(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &Argv, &Argc);\r
+ Status = UpdateArgcArgv(ShellInfoObject.NewShellParametersProtocol, CleanOriginal, &Argv, &Argc);\r
ASSERT_EFI_ERROR(Status);\r
\r
for (Count = 0 ; Count < ShellInfoObject.NewShellParametersProtocol->Argc ; Count++) {\r
Status = InternalShellExecuteDevicePath(\r
&gImageHandle,\r
DevPath,\r
- PostVariableCmdLine,\r
+ CleanOriginal,\r
NULL,\r
&StatusCode\r
);\r
\r
SHELL_FREE_NON_NULL(CommandName);\r
SHELL_FREE_NON_NULL(CommandWithPath);\r
- SHELL_FREE_NON_NULL(PostVariableCmdLine);\r
+ SHELL_FREE_NON_NULL(CleanOriginal);\r
\r
return (Status);\r
}\r