mirror of https://github.com/acidanthera/audk.git
ShellPkg: Manually parse parameters
We can't use ShellCommandLineParse as it would error out when the shell was called with args like "cp -r foo bar", because "-r" is not a recognised shell option A different way to avoid some of this manual parsing would be to prepend '^' to each argument, but that would still require the degree of parsing necessary to work out which words are part of the command and which are shell options. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Brendan Jackman <Brendan.Jackman@arm.com> Reviewed-by: Olivier Martin <olivier.martin@arm.com> Reviewed-by: Jaben Carsey <Jaben.carsey@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15220 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
1eb5cf94a1
commit
23385d6319
|
@ -759,20 +759,6 @@ GetDevicePathsForImageAndFile (
|
|||
return (Status);
|
||||
}
|
||||
|
||||
STATIC CONST SHELL_PARAM_ITEM mShellParamList[] = {
|
||||
{L"-nostartup", TypeFlag},
|
||||
{L"-startup", TypeFlag},
|
||||
{L"-noconsoleout", TypeFlag},
|
||||
{L"-noconsolein", TypeFlag},
|
||||
{L"-nointerrupt", TypeFlag},
|
||||
{L"-nomap", TypeFlag},
|
||||
{L"-noversion", TypeFlag},
|
||||
{L"-startup", TypeFlag},
|
||||
{L"-delay", TypeValue},
|
||||
{L"-_exit", TypeFlag},
|
||||
{NULL, TypeMax}
|
||||
};
|
||||
|
||||
/**
|
||||
Process all Uefi Shell 2.0 command line options.
|
||||
|
||||
|
@ -806,36 +792,143 @@ ProcessCommandLine(
|
|||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
LIST_ENTRY *Package;
|
||||
UINTN Size;
|
||||
CONST CHAR16 *TempConst;
|
||||
UINTN Count;
|
||||
UINTN LoopVar;
|
||||
CHAR16 *ProblemParam;
|
||||
UINT64 Intermediate;
|
||||
CHAR16 *CurrentArg;
|
||||
CHAR16 *DelayValueStr;
|
||||
UINT64 DelayValue;
|
||||
EFI_STATUS Status;
|
||||
EFI_UNICODE_COLLATION_PROTOCOL *UnicodeCollation;
|
||||
|
||||
Package = NULL;
|
||||
ProblemParam = NULL;
|
||||
// `file-name-options` will contain arguments to `file-name` that we don't
|
||||
// know about. This would cause ShellCommandLineParse to error, so we parse
|
||||
// arguments manually, ignoring those after the first thing that doesn't look
|
||||
// like a shell option (which is assumed to be `file-name`).
|
||||
|
||||
Status = ShellCommandLineParse (mShellParamList, &Package, NULL, FALSE);
|
||||
Status = gBS->LocateProtocol (
|
||||
&gEfiUnicodeCollationProtocolGuid,
|
||||
NULL,
|
||||
(VOID **) &UnicodeCollation
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Count = 1;
|
||||
Size = 0;
|
||||
TempConst = ShellCommandLineGetRawValue(Package, Count++);
|
||||
if (TempConst != NULL && StrLen(TempConst)) {
|
||||
ShellInfoObject.ShellInitSettings.FileName = AllocateZeroPool(StrSize(TempConst));
|
||||
// Set default options
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = FALSE;
|
||||
ShellInfoObject.ShellInitSettings.Delay = 5;
|
||||
|
||||
// Start LoopVar at 1 to ignore Argv[0] which is the name of this binary
|
||||
// (probably "Shell.efi")
|
||||
for (LoopVar = 1 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
|
||||
CurrentArg = gEfiShellParametersProtocol->Argv[LoopVar];
|
||||
if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-startup",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup = TRUE;
|
||||
}
|
||||
else if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-nostartup",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = TRUE;
|
||||
}
|
||||
else if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-noconsoleout",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = TRUE;
|
||||
}
|
||||
else if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-noconsolein",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn = TRUE;
|
||||
}
|
||||
else if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-nointerrupt",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt = TRUE;
|
||||
}
|
||||
else if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-nomap",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap = TRUE;
|
||||
}
|
||||
else if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-noversion",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = TRUE;
|
||||
}
|
||||
else if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-delay",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay = TRUE;
|
||||
// Check for optional delay value following "-delay"
|
||||
DelayValueStr = gEfiShellParametersProtocol->Argv[LoopVar + 1];
|
||||
if (DelayValueStr != NULL){
|
||||
if (*DelayValueStr == L':') {
|
||||
DelayValueStr++;
|
||||
}
|
||||
if (!EFI_ERROR(ShellConvertStringToUint64 (
|
||||
DelayValueStr,
|
||||
&DelayValue,
|
||||
FALSE,
|
||||
FALSE
|
||||
))) {
|
||||
ShellInfoObject.ShellInitSettings.Delay = (UINTN)DelayValue;
|
||||
LoopVar++;
|
||||
}
|
||||
}
|
||||
} else if (UnicodeCollation->StriColl (
|
||||
UnicodeCollation,
|
||||
L"-_exit",
|
||||
CurrentArg
|
||||
) == 0) {
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = TRUE;
|
||||
} else if (StrnCmp (L"-", CurrentArg, 1) == 0) {
|
||||
// Unrecognised option
|
||||
ShellPrintHiiEx(-1, -1, NULL,
|
||||
STRING_TOKEN (STR_GEN_PROBLEM),
|
||||
ShellInfoObject.HiiHandle,
|
||||
CurrentArg
|
||||
);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
} else {
|
||||
ShellInfoObject.ShellInitSettings.FileName = AllocateZeroPool(StrSize(CurrentArg));
|
||||
if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
|
||||
return (EFI_OUT_OF_RESOURCES);
|
||||
}
|
||||
StrCpy(ShellInfoObject.ShellInitSettings.FileName, TempConst);
|
||||
//
|
||||
// We found `file-name`.
|
||||
//
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;
|
||||
for (LoopVar = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
|
||||
if (StrCmp(gEfiShellParametersProtocol->Argv[LoopVar], ShellInfoObject.ShellInitSettings.FileName)==0) {
|
||||
|
||||
StrCpy (ShellInfoObject.ShellInitSettings.FileName, CurrentArg);
|
||||
LoopVar++;
|
||||
//
|
||||
// We found the file... add the rest of the params...
|
||||
//
|
||||
|
||||
// Add `file-name-options`
|
||||
for ( ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
|
||||
ASSERT((ShellInfoObject.ShellInitSettings.FileOptions == NULL && Size == 0) || (ShellInfoObject.ShellInitSettings.FileOptions != NULL));
|
||||
StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
|
||||
|
@ -857,44 +950,13 @@ ProcessCommandLine(
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ShellCommandLineFreeVarList(Package);
|
||||
Package = NULL;
|
||||
Status = ShellCommandLineParse (mShellParamList, &Package, &ProblemParam, FALSE);
|
||||
if (EFI_ERROR(Status)) {
|
||||
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), ShellInfoObject.HiiHandle, ProblemParam);
|
||||
FreePool(ProblemParam);
|
||||
ShellCommandLineFreeVarList(Package);
|
||||
return (EFI_INVALID_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup = ShellCommandLineGetFlag(Package, L"-startup");
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = ShellCommandLineGetFlag(Package, L"-nostartup");
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = ShellCommandLineGetFlag(Package, L"-noconsoleout");
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn = ShellCommandLineGetFlag(Package, L"-noconsolein");
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt = ShellCommandLineGetFlag(Package, L"-nointerrupt");
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap = ShellCommandLineGetFlag(Package, L"-nomap");
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = ShellCommandLineGetFlag(Package, L"-noversion");
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay = ShellCommandLineGetFlag(Package, L"-delay");
|
||||
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = ShellCommandLineGetFlag(Package, L"-_exit");
|
||||
|
||||
ShellInfoObject.ShellInitSettings.Delay = 5;
|
||||
|
||||
// "-nointerrupt" overrides "-delay"
|
||||
if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt) {
|
||||
ShellInfoObject.ShellInitSettings.Delay = 0;
|
||||
} else if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay) {
|
||||
TempConst = ShellCommandLineGetValue(Package, L"-delay");
|
||||
if (TempConst != NULL && *TempConst == L':') {
|
||||
TempConst++;
|
||||
}
|
||||
if (TempConst != NULL && !EFI_ERROR(ShellConvertStringToUint64(TempConst, &Intermediate, FALSE, FALSE))) {
|
||||
ShellInfoObject.ShellInitSettings.Delay = (UINTN)Intermediate;
|
||||
}
|
||||
}
|
||||
ShellCommandLineFreeVarList(Package);
|
||||
|
||||
return (Status);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue