+ }\r
+ }\r
+\r
+ //\r
+ // This is guaranteed to be called after UpdateArgcArgv no matter what else happened.\r
+ // This is safe even if the update API failed. In this case, it may be a no-op.\r
+ //\r
+ RestoreArgcArgv(ParamProtocol, &Argv, &Argc);\r
+\r
+ //\r
+ // If a script is running and the command is not a script only command, then\r
+ // change return value to success so the script won't halt (unless aborted).\r
+ //\r
+ // Script only commands have to be able halt the script since the script will\r
+ // not operate if they are failing.\r
+ //\r
+ if ( ShellCommandGetCurrentScriptFile() != NULL\r
+ && !IsScriptOnlyCommand(FirstParameter)\r
+ && Status != EFI_ABORTED\r
+ ) {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ FreePool (NewCmdLine);\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Function to run the command or file.\r
+\r
+ @param[in] Type the type of operation being run.\r
+ @param[in] CmdLine the command line to run.\r
+ @param[in] FirstParameter the first parameter on the command line\r
+ @param[in] ParamProtocol the shell parameters protocol pointer\r
+ @param[out] CommandStatus the status from the command line.\r
+\r
+ @retval EFI_SUCCESS The command was completed.\r
+ @retval EFI_ABORTED The command's operation was aborted.\r
+**/\r
+EFI_STATUS\r
+RunCommandOrFile(\r
+ IN SHELL_OPERATION_TYPES Type,\r
+ IN CONST CHAR16 *CmdLine,\r
+ IN CHAR16 *FirstParameter,\r
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,\r
+ OUT EFI_STATUS *CommandStatus\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS StartStatus;\r
+ CHAR16 *CommandWithPath;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
+ SHELL_STATUS CalleeExitStatus;\r
+\r
+ Status = EFI_SUCCESS;\r
+ CommandWithPath = NULL;\r
+ DevPath = NULL;\r
+ CalleeExitStatus = SHELL_INVALID_PARAMETER;\r
+\r
+ switch (Type) {\r
+ case Internal_Command:\r
+ Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol, CommandStatus);\r
+ break;\r
+ case Script_File_Name:\r
+ case Efi_Application:\r
+ //\r
+ // Process a fully qualified path\r
+ //\r
+ if (StrStr(FirstParameter, L":") != NULL) {\r
+ ASSERT (CommandWithPath == NULL);\r
+ if (ShellIsFile(FirstParameter) == EFI_SUCCESS) {\r
+ CommandWithPath = StrnCatGrow(&CommandWithPath, NULL, FirstParameter, 0);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Process a relative path and also check in the path environment variable\r
+ //\r
+ if (CommandWithPath == NULL) {\r
+ CommandWithPath = ShellFindFilePathEx(FirstParameter, mExecutableExtensions);\r
+ }\r
+\r
+ //\r
+ // This should be impossible now.\r
+ //\r
+ ASSERT(CommandWithPath != NULL);\r
+\r
+ //\r
+ // Make sure that path is not just a directory (or not found)\r
+ //\r
+ if (!EFI_ERROR(ShellIsDirectory(CommandWithPath))) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
+ SetLastError(SHELL_NOT_FOUND);\r
+ }\r
+ switch (Type) {\r
+ case Script_File_Name:\r
+ Status = RunScriptFile (CommandWithPath, NULL, CmdLine, ParamProtocol);\r
+ break;\r
+ case Efi_Application:\r
+ //\r
+ // Get the device path of the application image\r
+ //\r
+ DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath(CommandWithPath);\r
+ if (DevPath == NULL){\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Execute the device path\r
+ //\r
+ Status = InternalShellExecuteDevicePath(\r
+ &gImageHandle,\r
+ DevPath,\r
+ CmdLine,\r
+ NULL,\r
+ &StartStatus\r
+ );\r
+\r
+ SHELL_FREE_NON_NULL(DevPath);\r
+\r
+ if(EFI_ERROR (Status)) {\r
+ CalleeExitStatus = (SHELL_STATUS) (Status & (~MAX_BIT));\r
+ } else {\r
+ CalleeExitStatus = (SHELL_STATUS) StartStatus;\r
+ }\r
+\r
+ if (CommandStatus != NULL) {\r
+ *CommandStatus = CalleeExitStatus;\r
+ }\r
+\r
+ //\r
+ // Update last error status.\r
+ //\r
+ // Status is an EFI_STATUS. Clear top bit to convert to SHELL_STATUS\r
+ SetLastError(CalleeExitStatus);\r
+ break;\r
+ default:\r
+ //\r
+ // Do nothing.\r
+ //\r
+ break;\r