+ @retval EFI_SUCCESS The item is valid.\r
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
+ @retval EFI_NOT_FOUND The operation type is unknown or invalid.\r
+**/\r
+EFI_STATUS \r
+EFIAPI\r
+IsValidSplit(\r
+ IN CONST CHAR16 *CmdLine\r
+ )\r
+{\r
+ CHAR16 *Temp;\r
+ CHAR16 *FirstParameter;\r
+ CHAR16 *TempWalker;\r
+ EFI_STATUS Status;\r
+\r
+ Temp = NULL;\r
+\r
+ Temp = StrnCatGrow(&Temp, NULL, CmdLine, 0);\r
+ if (Temp == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+\r
+ FirstParameter = StrStr(Temp, L"|");\r
+ if (FirstParameter != NULL) {\r
+ *FirstParameter = CHAR_NULL;\r
+ }\r
+\r
+ FirstParameter = NULL;\r
+\r
+ //\r
+ // Process the command line\r
+ //\r
+ Status = ProcessCommandLineToFinal(&Temp);\r
+\r
+ if (!EFI_ERROR(Status)) {\r
+ FirstParameter = AllocateZeroPool(StrSize(CmdLine));\r
+ if (FirstParameter == NULL) {\r
+ SHELL_FREE_NON_NULL(Temp);\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ TempWalker = (CHAR16*)Temp;\r
+ GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine));\r
+\r
+ if (GetOperationType(FirstParameter) == Unknown_Invalid) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
+ SetLastError(SHELL_NOT_FOUND);\r
+ Status = EFI_NOT_FOUND;\r
+ }\r
+ }\r
+\r
+ SHELL_FREE_NON_NULL(Temp);\r
+ SHELL_FREE_NON_NULL(FirstParameter);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Determine if a command line contains with a split contains only valid commands.\r
+\r
+ @param[in] CmdLine The command line to parse.\r
+\r
+ @retval EFI_SUCCESS CmdLine has only valid commands, application, or has no split.\r
+ @retval EFI_ABORTED CmdLine has at least one invalid command or application.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VerifySplit(\r
+ IN CONST CHAR16 *CmdLine\r
+ )\r
+{\r
+ CONST CHAR16 *TempSpot;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Verify up to the pipe or end character\r
+ //\r
+ Status = IsValidSplit(CmdLine);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\r
+\r
+ //\r
+ // If this was the only item, then get out\r
+ //\r
+ if (!ContainsSplit(CmdLine)) {\r
+ return (EFI_SUCCESS);\r
+ }\r
+\r
+ //\r
+ // recurse to verify the next item\r
+ //\r
+ TempSpot = FindSplit(CmdLine)+1;\r
+ return (VerifySplit(TempSpot));\r
+}\r
+\r
+/**\r
+ Process a split based operation.\r
+\r
+ @param[in] CmdLine pointer to the command line to process\r
+\r
+ @retval EFI_SUCCESS The operation was successful\r
+ @return an error occured.\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
+ Status = VerifySplit(CmdLine);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\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
+ Reprocess the command line to direct all -? to the help command.\r
+\r
+ if found, will add "help" as argv[0], and move the rest later.\r
+\r
+ @param[in,out] CmdLine pointer to the command line to update\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DoHelpUpdate(\r
+ IN OUT CHAR16 **CmdLine\r
+ )\r
+{\r
+ CHAR16 *CurrentParameter;\r
+ CHAR16 *Walker;\r
+ CHAR16 *LastWalker;\r
+ CHAR16 *NewCommandLine;\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ CurrentParameter = AllocateZeroPool(StrSize(*CmdLine));\r
+ if (CurrentParameter == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+\r
+ Walker = *CmdLine;\r
+ while(Walker != NULL && *Walker != CHAR_NULL) {\r
+ LastWalker = Walker;\r
+ GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine));\r
+ if (StrStr(CurrentParameter, L"-?") == CurrentParameter) {\r
+ LastWalker[0] = L' ';\r
+ LastWalker[1] = L' ';\r
+ NewCommandLine = AllocateZeroPool(StrSize(L"help ") + StrSize(*CmdLine));\r
+ if (NewCommandLine == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ break;\r