summaryrefslogtreecommitdiff
path: root/ShellPkg/Application/Shell/ShellParametersProtocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Application/Shell/ShellParametersProtocol.c')
-rw-r--r--ShellPkg/Application/Shell/ShellParametersProtocol.c160
1 files changed, 158 insertions, 2 deletions
diff --git a/ShellPkg/Application/Shell/ShellParametersProtocol.c b/ShellPkg/Application/Shell/ShellParametersProtocol.c
index 0785902b16..3684f9cd82 100644
--- a/ShellPkg/Application/Shell/ShellParametersProtocol.c
+++ b/ShellPkg/Application/Shell/ShellParametersProtocol.c
@@ -20,6 +20,162 @@
BOOLEAN AsciiRedirection = FALSE;
/**
+ Return the next parameter's end from a command line string.
+
+ @param[in] String the string to parse
+**/
+CONST CHAR16*
+EFIAPI
+FindEndOfParameter(
+ IN CONST CHAR16 *String
+ )
+{
+ CONST CHAR16 *First;
+ CONST CHAR16 *CloseQuote;
+
+ First = FindFirstCharacter(String, L" \"", L'^');
+
+ //
+ // nothing, all one parameter remaining
+ //
+ if (*First == CHAR_NULL) {
+ return (First);
+ }
+
+ //
+ // If space before a quote (or neither found, i.e. both CHAR_NULL),
+ // then that's the end.
+ //
+ if (*First == L' ') {
+ return (First);
+ }
+
+ CloseQuote = FindFirstCharacter (First+1, L"\"", L'^');
+
+ //
+ // We did not find a terminator...
+ //
+ if (*CloseQuote == CHAR_NULL) {
+ return (NULL);
+ }
+
+ return (FindEndOfParameter (CloseQuote+1));
+}
+
+/**
+ Return the next parameter from a command line string.
+
+ This function moves the next parameter from Walker into TempParameter and moves
+ Walker up past that parameter for recursive calling. When the final parameter
+ is moved *Walker will be set to NULL;
+
+ Temp Parameter must be large enough to hold the parameter before calling this
+ function.
+
+ This will also remove all remaining ^ characters after processing.
+
+ @param[in, out] Walker pointer to string of command line. Adjusted to
+ reminaing command line on return
+ @param[in, out] TempParameter pointer to string of command line item extracted.
+ @param[in] Length buffer size of TempParameter.
+ @param[in] StripQuotation if TRUE then strip the quotation marks surrounding
+ the parameters.
+
+ @return EFI_INALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string.
+ @return EFI_NOT_FOUND A closing " could not be found on the specified string
+**/
+EFI_STATUS
+EFIAPI
+GetNextParameter(
+ IN OUT CHAR16 **Walker,
+ IN OUT CHAR16 **TempParameter,
+ IN CONST UINTN Length,
+ IN BOOLEAN StripQuotation
+ )
+{
+ CONST CHAR16 *NextDelim;
+
+ if (Walker == NULL
+ ||*Walker == NULL
+ ||TempParameter == NULL
+ ||*TempParameter == NULL
+ ){
+ return (EFI_INVALID_PARAMETER);
+ }
+
+
+ //
+ // make sure we dont have any leading spaces
+ //
+ while ((*Walker)[0] == L' ') {
+ (*Walker)++;
+ }
+
+ //
+ // make sure we still have some params now...
+ //
+ if (StrLen(*Walker) == 0) {
+DEBUG_CODE_BEGIN();
+ *Walker = NULL;
+DEBUG_CODE_END();
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ NextDelim = FindEndOfParameter(*Walker);
+
+ if (NextDelim == NULL){
+DEBUG_CODE_BEGIN();
+ *Walker = NULL;
+DEBUG_CODE_END();
+ return (EFI_NOT_FOUND);
+ }
+
+ StrnCpyS(*TempParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker);
+
+ //
+ // Add a CHAR_NULL if we didnt get one via the copy
+ //
+ if (*NextDelim != CHAR_NULL) {
+ (*TempParameter)[NextDelim - *Walker] = CHAR_NULL;
+ }
+
+ //
+ // Update Walker for the next iteration through the function
+ //
+ *Walker = (CHAR16*)NextDelim;
+
+ //
+ // Remove any non-escaped quotes in the string
+ // Remove any remaining escape characters in the string
+ //
+ for (NextDelim = FindFirstCharacter(*TempParameter, L"\"^", CHAR_NULL)
+ ; *NextDelim != CHAR_NULL
+ ; NextDelim = FindFirstCharacter(NextDelim, L"\"^", CHAR_NULL)
+ ) {
+ if (*NextDelim == L'^') {
+
+ //
+ // eliminate the escape ^
+ //
+ CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
+ NextDelim++;
+ } else if (*NextDelim == L'\"') {
+
+ //
+ // eliminate the unescaped quote
+ //
+ if (StripQuotation) {
+ CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
+ } else{
+ NextDelim++;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
Function to populate Argc and Argv.
This function parses the CommandLine and divides it into standard C style Argc/Argv
@@ -82,7 +238,7 @@ ParseCommandLineToArgs(
; Walker != NULL && *Walker != CHAR_NULL
; Count++
) {
- if (EFI_ERROR (ShellGetNextParameter (&Walker, TempParameter, Size, TRUE))) {
+ if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, TRUE))) {
break;
}
}
@@ -100,7 +256,7 @@ ParseCommandLineToArgs(
Walker = (CHAR16*)NewCommandLine;
while(Walker != NULL && *Walker != CHAR_NULL) {
SetMem16(TempParameter, Size, CHAR_NULL);
- if (EFI_ERROR (ShellGetNextParameter (&Walker, TempParameter, Size, StripQuotation))) {
+ if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, StripQuotation))) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}