+\r
+/**\r
+ internal worker function to load and run an image in the current shell.\r
+\r
+ @param CommandLine Points to the NULL-terminated UCS-2 encoded string\r
+ containing the command line. If NULL then the command-\r
+ line will be empty.\r
+ @param Environment Points to a NULL-terminated array of environment\r
+ variables with the format 'x=y', where x is the\r
+ environment variable name and y is the value. If this\r
+ is NULL, then the current shell environment is used.\r
+\r
+ @param[out] StartImageStatus Returned status from the command line.\r
+\r
+ @retval EFI_SUCCESS The command executed successfully. The status code\r
+ returned by the command is pointed to by StatusCode.\r
+ @retval EFI_INVALID_PARAMETER The parameters are invalid.\r
+ @retval EFI_OUT_OF_RESOURCES Out of resources.\r
+ @retval EFI_UNSUPPORTED Nested shell invocations are not allowed.\r
+**/\r
+EFI_STATUS\r
+InternalShellExecute(\r
+ IN CONST CHAR16 *CommandLine OPTIONAL,\r
+ IN CONST CHAR16 **Environment OPTIONAL,\r
+ OUT EFI_STATUS *StartImageStatus OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS CleanupStatus;\r
+ LIST_ENTRY OrigEnvs;\r
+\r
+ InitializeListHead(&OrigEnvs);\r
+\r
+ //\r
+ // Save our current environment settings for later restoration if necessary\r
+ //\r
+ if (Environment != NULL) {\r
+ Status = GetEnvironmentVariableList(&OrigEnvs);\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = SetEnvironmentVariables(Environment);\r
+ } else {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ Status = RunShellCommand(CommandLine, StartImageStatus);\r
+\r
+ // Restore environment variables\r
+ if (!IsListEmpty(&OrigEnvs)) {\r
+ CleanupStatus = SetEnvironmentVariableList(&OrigEnvs);\r
+ ASSERT_EFI_ERROR (CleanupStatus);\r
+ }\r
+\r
+ return(Status);\r
+}\r
+\r
+/**\r
+ Determine if the UEFI Shell is currently running with nesting enabled or disabled.\r
+\r
+ @retval FALSE nesting is required\r
+ @retval other nesting is enabled\r
+**/\r
+STATIC\r
+BOOLEAN\r
+NestingEnabled(\r
+ VOID\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR16 *Temp;\r
+ CHAR16 *Temp2;\r
+ UINTN TempSize;\r
+ BOOLEAN RetVal;\r
+\r
+ RetVal = TRUE;\r
+ Temp = NULL;\r
+ Temp2 = NULL;\r
+\r
+ if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {\r
+ TempSize = 0;\r
+ Temp = NULL;\r
+ Status = SHELL_GET_ENVIRONMENT_VARIABLE(mNoNestingEnvVarName, &TempSize, Temp);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ Temp = AllocateZeroPool(TempSize + sizeof(CHAR16));\r
+ if (Temp != NULL) {\r
+ Status = SHELL_GET_ENVIRONMENT_VARIABLE(mNoNestingEnvVarName, &TempSize, Temp);\r
+ }\r
+ }\r
+ Temp2 = StrnCatGrow(&Temp2, NULL, mNoNestingTrue, 0);\r
+ if (Temp != NULL && Temp2 != NULL && StringNoCaseCompare(&Temp, &Temp2) == 0) {\r
+ //\r
+ // Use the no nesting method.\r
+ //\r
+ RetVal = FALSE;\r
+ }\r
+ }\r
+\r
+ SHELL_FREE_NON_NULL(Temp);\r
+ SHELL_FREE_NON_NULL(Temp2);\r
+ return (RetVal);\r
+}\r
+\r