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
return (EFI_SUCCESS);\r
}\r
\r
+/**\r
+ Takes the Argv[0] part of the command line and determine the meaning of it.\r
+**/\r
+SHELL_OPERATION_TYPES\r
+EFIAPI\r
+GetOperationType(\r
+ IN CONST CHAR16 *CmdName\r
+ )\r
+{\r
+ CHAR16* FileWithPath;\r
+ CONST CHAR16* TempLocation;\r
+ CONST CHAR16* TempLocation2;\r
+\r
+ FileWithPath = NULL;\r
+ //\r
+ // test for an internal command.\r
+ //\r
+ if (ShellCommandIsCommandOnList(CmdName)) {\r
+ return (INTERNAL_COMMAND);\r
+ }\r
+\r
+ //\r
+ // Test for file system change request. anything ending with : and cant have spaces.\r
+ //\r
+ if (CmdName[(StrLen(CmdName)-1)] == L':') {\r
+ if (StrStr(CmdName, L" ") != NULL) {\r
+ return (UNKNOWN_INVALID);\r
+ }\r
+ return (FILE_SYS_CHANGE);\r
+ }\r
+\r
+ //\r
+ // Test for a file\r
+ //\r
+ if ((FileWithPath = ShellFindFilePathEx(CmdName, mExecutableExtensions)) != NULL) {\r
+ //\r
+ // See if that file has a script file extension\r
+ //\r
+ if (StrLen(FileWithPath) > 4) {\r
+ TempLocation = FileWithPath+StrLen(FileWithPath)-4;\r
+ TempLocation2 = mScriptExtension;\r
+ if (StringNoCaseCompare((VOID*)(&TempLocation), (VOID*)(&TempLocation2)) == 0) {\r
+ SHELL_FREE_NON_NULL(FileWithPath);\r
+ return (SCRIPT_FILE_NAME);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Was a file, but not a script. we treat this as an application.\r
+ //\r
+ SHELL_FREE_NON_NULL(FileWithPath);\r
+ return (EFI_APPLICATION);\r
+ }\r
+ \r
+ SHELL_FREE_NON_NULL(FileWithPath);\r
+ //\r
+ // No clue what this is... return invalid flag...\r
+ //\r
+ return (UNKNOWN_INVALID);\r
+}\r
+\r
+/**\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ProcessNewSplitCommandLine(\r
+ IN CONST CHAR16 *CmdLine\r
+ )\r
+{\r
+ SPLIT_LIST *Split;\r
+ EFI_STATUS Status;\r
+\r
+ Split = NULL;\r
+\r
+ //\r
+ // are we in an existing split???\r
+ //\r
+ if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {\r
+ Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);\r
+ }\r
+\r
+ if (Split == NULL) {\r
+ Status = RunSplitCommand(CmdLine, NULL, NULL);\r
+ } else {\r
+ Status = RunSplitCommand(CmdLine, Split->SplitStdIn, Split->SplitStdOut);\r
+ }\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, CmdLine);\r
+ }\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Handle a request to change the current file system\r
+\r
+ @param[in] CmdLine The passed in command line\r
+\r
+ @retval EFI_SUCCESS The operation was successful\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ChangeMappedDrive(\r
+ IN CONST CHAR16 *CmdLine\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // make sure we are the right operation\r
+ //\r
+ ASSERT(CmdLine[(StrLen(CmdLine)-1)] == L':' && StrStr(CmdLine, L" ") == NULL);\r
+ \r
+ //\r
+ // Call the protocol API to do the work\r
+ //\r
+ Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir(NULL, CmdLine);\r
+\r
+ //\r
+ // Report any errors\r
+ //\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, CmdLine);\r
+ }\r
+\r
+ return (Status);\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 *PostVariableCmdLine;\r
CHAR16 *CommandWithPath;\r
CONST EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
CONST CHAR16 *TempLocation;\r
UINTN Count;\r
UINTN Count2;\r
CHAR16 *CleanOriginal;\r
- SPLIT_LIST *Split;\r
\r
ASSERT(CmdLine != NULL);\r
if (StrLen(CmdLine) == 0) {\r
}\r
\r
CommandName = NULL;\r
- PostVariableCmdLine = NULL;\r
CommandWithPath = NULL;\r
DevPath = NULL;\r
Status = EFI_SUCCESS;\r
CleanOriginal = NULL;\r
- Split = NULL;\r
\r
CleanOriginal = StrnCatGrow(&CleanOriginal, NULL, CmdLine, 0);\r
if (CleanOriginal == NULL) {\r
return (Status);\r
}\r
\r
- PostVariableCmdLine = ShellConvertVariables(CleanOriginal);\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
- TrimSpaces(&PostVariableCmdLine);\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
- if (ContainsSplit(PostVariableCmdLine)) {\r
- //\r
- // are we in an existing split???\r
- //\r
- if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {\r
- Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);\r
- }\r
-\r
- if (Split == NULL) {\r
- Status = RunSplitCommand(PostVariableCmdLine, NULL, NULL);\r
- } else {\r
- Status = RunSplitCommand(PostVariableCmdLine, 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
- }\r
+ if (ContainsSplit(CleanOriginal)) {\r
+ Status = ProcessNewSplitCommandLine(CleanOriginal);\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 (EFI_ERROR(Status)) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, PostVariableCmdLine);\r
- }\r
- FreePool(PostVariableCmdLine);\r
+ if (CleanOriginal[(StrLen(CleanOriginal)-1)] == L':' && StrStr(CleanOriginal, L" ") == NULL) {\r
+ Status = ChangeMappedDrive(CleanOriginal);\r
+ SHELL_FREE_NON_NULL(CleanOriginal);\r
return (Status);\r
}\r
\r
+\r
///@todo update this section to divide into 3 ways - run internal command, run split (above), and run an external file...\r
/// We waste a lot of time doing processing like StdIn,StdOut,Argv,Argc for things that are external files...\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
- TrimSpaces(&PostVariableCmdLine);\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