2 Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,
3 manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 Copyright (C) 2014, Red Hat, Inc.
7 (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
8 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
15 BOOLEAN AsciiRedirection
= FALSE
;
18 Return the next parameter's end from a command line string.
20 @param[in] String the string to parse
24 IN CONST CHAR16
*String
28 CONST CHAR16
*CloseQuote
;
30 First
= FindFirstCharacter (String
, L
" \"", L
'^');
33 // nothing, all one parameter remaining
35 if (*First
== CHAR_NULL
) {
40 // If space before a quote (or neither found, i.e. both CHAR_NULL),
41 // then that's the end.
47 CloseQuote
= FindFirstCharacter (First
+1, L
"\"", L
'^');
50 // We did not find a terminator...
52 if (*CloseQuote
== CHAR_NULL
) {
56 return (FindEndOfParameter (CloseQuote
+1));
60 Return the next parameter from a command line string.
62 This function moves the next parameter from Walker into TempParameter and moves
63 Walker up past that parameter for recursive calling. When the final parameter
64 is moved *Walker will be set to NULL;
66 Temp Parameter must be large enough to hold the parameter before calling this
69 This will also remove all remaining ^ characters after processing.
71 @param[in, out] Walker pointer to string of command line. Adjusted to
72 remaining command line on return
73 @param[in, out] TempParameter pointer to string of command line item extracted.
74 @param[in] Length buffer size of TempParameter.
75 @param[in] StripQuotation if TRUE then strip the quotation marks surrounding
78 @return EFI_INVALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string.
79 @return EFI_NOT_FOUND A closing " could not be found on the specified string
83 IN OUT CHAR16
**Walker
,
84 IN OUT CHAR16
**TempParameter
,
85 IN CONST UINTN Length
,
86 IN BOOLEAN StripQuotation
89 CONST CHAR16
*NextDelim
;
93 || (TempParameter
== NULL
)
94 || (*TempParameter
== NULL
)
97 return (EFI_INVALID_PARAMETER
);
101 // make sure we dont have any leading spaces
103 while ((*Walker
)[0] == L
' ') {
108 // make sure we still have some params now...
110 if (StrLen (*Walker
) == 0) {
114 return (EFI_INVALID_PARAMETER
);
117 NextDelim
= FindEndOfParameter (*Walker
);
119 if (NextDelim
== NULL
) {
123 return (EFI_NOT_FOUND
);
126 StrnCpyS (*TempParameter
, Length
/ sizeof (CHAR16
), (*Walker
), NextDelim
- *Walker
);
129 // Add a CHAR_NULL if we didn't get one via the copy
131 if (*NextDelim
!= CHAR_NULL
) {
132 (*TempParameter
)[NextDelim
- *Walker
] = CHAR_NULL
;
136 // Update Walker for the next iteration through the function
138 *Walker
= (CHAR16
*)NextDelim
;
141 // Remove any non-escaped quotes in the string
142 // Remove any remaining escape characters in the string
144 for (NextDelim
= FindFirstCharacter (*TempParameter
, L
"\"^", CHAR_NULL
)
145 ; *NextDelim
!= CHAR_NULL
146 ; NextDelim
= FindFirstCharacter (NextDelim
, L
"\"^", CHAR_NULL
)
149 if (*NextDelim
== L
'^') {
151 // eliminate the escape ^
153 CopyMem ((CHAR16
*)NextDelim
, NextDelim
+ 1, StrSize (NextDelim
+ 1));
155 } else if (*NextDelim
== L
'\"') {
157 // eliminate the unescaped quote
159 if (StripQuotation
) {
160 CopyMem ((CHAR16
*)NextDelim
, NextDelim
+ 1, StrSize (NextDelim
+ 1));
171 Function to populate Argc and Argv.
173 This function parses the CommandLine and divides it into standard C style Argc/Argv
174 parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space
175 delimited and quote surrounded parameter definition.
177 All special character processing (alias, environment variable, redirection,
178 etc... must be complete before calling this API.
180 @param[in] CommandLine String of command line to parse
181 @param[in] StripQuotation if TRUE then strip the quotation marks surrounding
183 @param[in, out] Argv pointer to array of strings; one for each parameter
184 @param[in, out] Argc pointer to number of strings in Argv array
186 @return EFI_SUCCESS the operation was successful
187 @return EFI_INVALID_PARAMETER some parameters are invalid
188 @return EFI_OUT_OF_RESOURCES a memory allocation failed.
191 ParseCommandLineToArgs (
192 IN CONST CHAR16
*CommandLine
,
193 IN BOOLEAN StripQuotation
,
194 IN OUT CHAR16
***Argv
,
199 CHAR16
*TempParameter
;
202 CHAR16
*NewCommandLine
;
206 ASSERT (Argc
!= NULL
);
207 ASSERT (Argv
!= NULL
);
209 if ((CommandLine
== NULL
) || (StrLen (CommandLine
) == 0)) {
212 return (EFI_SUCCESS
);
215 NewCommandLine
= AllocateCopyPool (StrSize (CommandLine
), CommandLine
);
216 if (NewCommandLine
== NULL
) {
217 return (EFI_OUT_OF_RESOURCES
);
220 TrimSpaces (&NewCommandLine
);
221 Size
= StrSize (NewCommandLine
);
222 TempParameter
= AllocateZeroPool (Size
);
223 if (TempParameter
== NULL
) {
224 SHELL_FREE_NON_NULL (NewCommandLine
);
225 return (EFI_OUT_OF_RESOURCES
);
229 Walker
= (CHAR16
*)NewCommandLine
230 ; Walker
!= NULL
&& *Walker
!= CHAR_NULL
234 if (EFI_ERROR (GetNextParameter (&Walker
, &TempParameter
, Size
, TRUE
))) {
240 // lets allocate the pointer array
242 (*Argv
) = AllocateZeroPool ((Count
)*sizeof (CHAR16
*));
244 Status
= EFI_OUT_OF_RESOURCES
;
249 Walker
= (CHAR16
*)NewCommandLine
;
250 while (Walker
!= NULL
&& *Walker
!= CHAR_NULL
) {
251 SetMem16 (TempParameter
, Size
, CHAR_NULL
);
252 if (EFI_ERROR (GetNextParameter (&Walker
, &TempParameter
, Size
, StripQuotation
))) {
253 Status
= EFI_INVALID_PARAMETER
;
257 NewParam
= AllocateCopyPool (StrSize (TempParameter
), TempParameter
);
258 if (NewParam
== NULL
) {
259 Status
= EFI_OUT_OF_RESOURCES
;
263 ((CHAR16
**)(*Argv
))[(*Argc
)] = NewParam
;
267 ASSERT (Count
>= (*Argc
));
268 Status
= EFI_SUCCESS
;
271 SHELL_FREE_NON_NULL (TempParameter
);
272 SHELL_FREE_NON_NULL (NewCommandLine
);
277 creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
278 installs it on our handle and if there is an existing version of the protocol
279 that one is cached for removal later.
281 @param[in, out] NewShellParameters on a successful return, a pointer to pointer
282 to the newly installed interface.
283 @param[in, out] RootShellInstance on a successful return, pointer to boolean.
284 TRUE if this is the root shell instance.
286 @retval EFI_SUCCESS the operation completed successfully.
287 @return other the operation failed.
288 @sa ReinstallProtocolInterface
289 @sa InstallProtocolInterface
290 @sa ParseCommandLineToArgs
293 CreatePopulateInstallShellParametersProtocol (
294 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
**NewShellParameters
,
295 IN OUT BOOLEAN
*RootShellInstance
299 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
300 CHAR16
*FullCommandLine
;
304 FullCommandLine
= NULL
;
308 // Assert for valid parameters
310 ASSERT (NewShellParameters
!= NULL
);
311 ASSERT (RootShellInstance
!= NULL
);
314 // See if we have a shell parameters placed on us
316 Status
= gBS
->OpenProtocol (
318 &gEfiShellParametersProtocolGuid
,
319 (VOID
**)&ShellInfoObject
.OldShellParameters
,
322 EFI_OPEN_PROTOCOL_GET_PROTOCOL
325 // if we don't then we must be the root shell (error is expected)
327 if (EFI_ERROR (Status
)) {
328 *RootShellInstance
= TRUE
;
332 // Allocate the new structure
334 *NewShellParameters
= AllocateZeroPool (sizeof (EFI_SHELL_PARAMETERS_PROTOCOL
));
335 if ((*NewShellParameters
) == NULL
) {
336 return (EFI_OUT_OF_RESOURCES
);
340 // get loaded image protocol
342 Status
= gBS
->OpenProtocol (
344 &gEfiLoadedImageProtocolGuid
,
345 (VOID
**)&LoadedImage
,
348 EFI_OPEN_PROTOCOL_GET_PROTOCOL
350 ASSERT_EFI_ERROR (Status
);
352 // Build the full command line
354 Status
= SHELL_GET_ENVIRONMENT_VARIABLE (L
"ShellOpt", &Size
, FullCommandLine
);
355 if (Status
== EFI_BUFFER_TOO_SMALL
) {
356 FullCommandLine
= AllocateZeroPool (Size
+ LoadedImage
->LoadOptionsSize
);
357 Status
= SHELL_GET_ENVIRONMENT_VARIABLE (L
"ShellOpt", &Size
, FullCommandLine
);
360 if (Status
== EFI_NOT_FOUND
) {
362 // no parameters via environment... ok
365 if (EFI_ERROR (Status
)) {
370 if ((Size
== 0) && (LoadedImage
->LoadOptionsSize
!= 0)) {
371 ASSERT (FullCommandLine
== NULL
);
373 // Now we need to include a NULL terminator in the size.
375 Size
= LoadedImage
->LoadOptionsSize
+ sizeof (FullCommandLine
[0]);
376 FullCommandLine
= AllocateZeroPool (Size
);
379 if (FullCommandLine
!= NULL
) {
380 CopyMem (FullCommandLine
, LoadedImage
->LoadOptions
, LoadedImage
->LoadOptionsSize
);
382 // Populate Argc and Argv
384 Status
= ParseCommandLineToArgs (
387 &(*NewShellParameters
)->Argv
,
388 &(*NewShellParameters
)->Argc
391 FreePool (FullCommandLine
);
393 ASSERT_EFI_ERROR (Status
);
395 (*NewShellParameters
)->Argv
= NULL
;
396 (*NewShellParameters
)->Argc
= 0;
400 // Populate the 3 faked file systems...
402 if (*RootShellInstance
) {
403 (*NewShellParameters
)->StdIn
= &FileInterfaceStdIn
;
404 (*NewShellParameters
)->StdOut
= &FileInterfaceStdOut
;
405 (*NewShellParameters
)->StdErr
= &FileInterfaceStdErr
;
406 Status
= gBS
->InstallProtocolInterface (
408 &gEfiShellParametersProtocolGuid
,
409 EFI_NATIVE_INTERFACE
,
410 (VOID
*)(*NewShellParameters
)
414 // copy from the existing ones
416 (*NewShellParameters
)->StdIn
= ShellInfoObject
.OldShellParameters
->StdIn
;
417 (*NewShellParameters
)->StdOut
= ShellInfoObject
.OldShellParameters
->StdOut
;
418 (*NewShellParameters
)->StdErr
= ShellInfoObject
.OldShellParameters
->StdErr
;
419 Status
= gBS
->ReinstallProtocolInterface (
421 &gEfiShellParametersProtocolGuid
,
422 (VOID
*)ShellInfoObject
.OldShellParameters
,
423 (VOID
*)(*NewShellParameters
)
431 frees all memory used by creation and installation of shell parameters protocol
432 and if there was an old version installed it will restore that one.
434 @param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
437 @retval EFI_SUCCESS the cleanup was successful
438 @return other the cleanup failed
439 @sa ReinstallProtocolInterface
440 @sa UninstallProtocolInterface
443 CleanUpShellParametersProtocol (
444 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*NewShellParameters
451 // If the old exists we need to restore it
453 if (ShellInfoObject
.OldShellParameters
!= NULL
) {
454 Status
= gBS
->ReinstallProtocolInterface (
456 &gEfiShellParametersProtocolGuid
,
457 (VOID
*)NewShellParameters
,
458 (VOID
*)ShellInfoObject
.OldShellParameters
461 ShellInfoObject
.OldShellParameters
= NULL
;
465 // No old one, just uninstall us...
467 Status
= gBS
->UninstallProtocolInterface (
469 &gEfiShellParametersProtocolGuid
,
470 (VOID
*)NewShellParameters
474 if (NewShellParameters
->Argv
!= NULL
) {
475 for ( LoopCounter
= 0
476 ; LoopCounter
< NewShellParameters
->Argc
480 FreePool (NewShellParameters
->Argv
[LoopCounter
]);
483 FreePool (NewShellParameters
->Argv
);
486 FreePool (NewShellParameters
);
491 Determine if a file name represents a unicode file.
493 @param[in] FileName Pointer to the filename to open.
495 @retval EFI_SUCCESS The file is a unicode file.
496 @return An error upon failure.
500 IN CONST CHAR16
*FileName
503 SHELL_FILE_HANDLE Handle
;
505 UINT64 OriginalFilePosition
;
509 Status
= gEfiShellProtocol
->OpenFileByName (FileName
, &Handle
, EFI_FILE_MODE_READ
);
510 if (EFI_ERROR (Status
)) {
514 gEfiShellProtocol
->GetFilePosition (Handle
, &OriginalFilePosition
);
515 gEfiShellProtocol
->SetFilePosition (Handle
, 0);
516 CharSize
= sizeof (CHAR16
);
517 Status
= gEfiShellProtocol
->ReadFile (Handle
, &CharSize
, &CharBuffer
);
518 if (EFI_ERROR (Status
) || (CharBuffer
!= gUnicodeFileTag
)) {
519 Status
= EFI_BUFFER_TOO_SMALL
;
522 gEfiShellProtocol
->SetFilePosition (Handle
, OriginalFilePosition
);
523 gEfiShellProtocol
->CloseFile (Handle
);
528 Strips out quotes sections of a string.
530 All of the characters between quotes is replaced with spaces.
532 @param[in, out] TheString A pointer to the string to update.
536 IN OUT CHAR16
*TheString
541 for (RemoveNow
= FALSE
; TheString
!= NULL
&& *TheString
!= CHAR_NULL
; TheString
++) {
542 if ((*TheString
== L
'^') && (*(TheString
+ 1) == L
'\"')) {
544 } else if (*TheString
== L
'\"') {
545 RemoveNow
= (BOOLEAN
) !RemoveNow
;
546 } else if (RemoveNow
) {
553 Calculate the 32-bit CRC in a EFI table using the service provided by the
556 @param Hdr Pointer to an EFI standard header
561 IN OUT EFI_TABLE_HEADER
*Hdr
569 // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
570 // Crc will come back as zero if we set it to zero here
573 gBS
->CalculateCrc32 ((UINT8
*)Hdr
, Hdr
->HeaderSize
, &Crc
);
578 Fix a string to only have the file name, removing starting at the first space of whatever is quoted.
580 @param[in] FileName The filename to start with.
582 @retval NULL FileName was invalid.
583 @return The modified FileName.
591 CHAR16
*TempLocation
;
593 if (FileName
== NULL
) {
597 if (FileName
[0] == L
'\"') {
599 if ((TempLocation
= StrStr (Copy
, L
"\"")) != NULL
) {
600 TempLocation
[0] = CHAR_NULL
;
604 while (Copy
[0] == L
' ') {
608 if ((TempLocation
= StrStr (Copy
, L
" ")) != NULL
) {
609 TempLocation
[0] = CHAR_NULL
;
613 if (Copy
[0] == CHAR_NULL
) {
621 Fix a string to only have the environment variable name, removing starting at the first space of whatever is quoted and removing the leading and trailing %.
623 @param[in] FileName The filename to start with.
625 @retval NULL FileName was invalid.
626 @return The modified FileName.
634 CHAR16
*TempLocation
;
638 if (FileName
[0] == L
'%') {
640 if ((TempLocation
= StrStr (Copy
, L
"%")) != NULL
) {
641 TempLocation
[0] = CHAR_NULL
;
645 return (FixFileName (Copy
));
649 Write the unicode file tag to the specified file.
651 It is the caller's responsibility to ensure that
652 ShellInfoObject.NewEfiShellProtocol has been initialized before calling this
655 @param[in] FileHandle The file to write the unicode file tag to.
657 @return Status code from ShellInfoObject.NewEfiShellProtocol->WriteFile.
661 IN SHELL_FILE_HANDLE FileHandle
668 FileTag
= gUnicodeFileTag
;
669 Size
= sizeof FileTag
;
670 Status
= ShellInfoObject
.NewEfiShellProtocol
->WriteFile (
675 ASSERT (EFI_ERROR (Status
) || Size
== sizeof FileTag
);
680 Function will replace the current StdIn and StdOut in the ShellParameters protocol
681 structure by parsing NewCommandLine. The current values are returned to the
684 This will also update the system table.
686 @param[in, out] ShellParameters Pointer to parameter structure to modify.
687 @param[in] NewCommandLine The new command line to parse and use.
688 @param[out] OldStdIn Pointer to old StdIn.
689 @param[out] OldStdOut Pointer to old StdOut.
690 @param[out] OldStdErr Pointer to old StdErr.
691 @param[out] SystemTableInfo Pointer to old system table information.
693 @retval EFI_SUCCESS Operation was successful, Argv and Argc are valid.
694 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
697 UpdateStdInStdOutStdErr (
698 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
699 IN CHAR16
*NewCommandLine
,
700 OUT SHELL_FILE_HANDLE
*OldStdIn
,
701 OUT SHELL_FILE_HANDLE
*OldStdOut
,
702 OUT SHELL_FILE_HANDLE
*OldStdErr
,
703 OUT SYSTEM_TABLE_INFO
*SystemTableInfo
706 CHAR16
*CommandLineCopy
;
707 CHAR16
*CommandLineWalker
;
708 CHAR16
*StdErrFileName
;
709 CHAR16
*StdOutFileName
;
710 CHAR16
*StdInFileName
;
711 CHAR16
*StdInVarName
;
712 CHAR16
*StdOutVarName
;
713 CHAR16
*StdErrVarName
;
715 SHELL_FILE_HANDLE TempHandle
;
724 CHAR16
*FirstLocation
;
729 AsciiRedirection
= FALSE
;
732 StdOutVarName
= NULL
;
733 StdErrVarName
= NULL
;
734 StdErrFileName
= NULL
;
735 StdInFileName
= NULL
;
736 StdOutFileName
= NULL
;
739 CommandLineCopy
= NULL
;
740 FirstLocation
= NULL
;
742 if ((ShellParameters
== NULL
) || (SystemTableInfo
== NULL
) || (OldStdIn
== NULL
) || (OldStdOut
== NULL
) || (OldStdErr
== NULL
)) {
743 return (EFI_INVALID_PARAMETER
);
746 SystemTableInfo
->ConIn
= gST
->ConIn
;
747 SystemTableInfo
->ConInHandle
= gST
->ConsoleInHandle
;
748 SystemTableInfo
->ConOut
= gST
->ConOut
;
749 SystemTableInfo
->ConOutHandle
= gST
->ConsoleOutHandle
;
750 SystemTableInfo
->ErrOut
= gST
->StdErr
;
751 SystemTableInfo
->ErrOutHandle
= gST
->StandardErrorHandle
;
752 *OldStdIn
= ShellParameters
->StdIn
;
753 *OldStdOut
= ShellParameters
->StdOut
;
754 *OldStdErr
= ShellParameters
->StdErr
;
756 if (NewCommandLine
== NULL
) {
757 return (EFI_SUCCESS
);
760 CommandLineCopy
= StrnCatGrow (&CommandLineCopy
, NULL
, NewCommandLine
, 0);
761 if (CommandLineCopy
== NULL
) {
762 return (EFI_OUT_OF_RESOURCES
);
765 Status
= EFI_SUCCESS
;
767 FirstLocation
= CommandLineCopy
+ StrLen (CommandLineCopy
);
769 StripQuotes (CommandLineCopy
);
771 if (!IsListEmpty (&ShellInfoObject
.SplitList
.Link
)) {
772 Split
= (SPLIT_LIST
*)GetFirstNode (&ShellInfoObject
.SplitList
.Link
);
773 if ((Split
!= NULL
) && (Split
->SplitStdIn
!= NULL
)) {
774 ShellParameters
->StdIn
= Split
->SplitStdIn
;
777 if ((Split
!= NULL
) && (Split
->SplitStdOut
!= NULL
)) {
778 ShellParameters
->StdOut
= Split
->SplitStdOut
;
782 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 2>>v ")) != NULL
)) {
783 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
784 SetMem16 (CommandLineWalker
, 12, L
' ');
785 StdErrVarName
= CommandLineWalker
+= 6;
787 if (StrStr (CommandLineWalker
, L
" 2>>v ") != NULL
) {
788 Status
= EFI_NOT_FOUND
;
792 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 1>>v ")) != NULL
)) {
793 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
794 SetMem16 (CommandLineWalker
, 12, L
' ');
795 StdOutVarName
= CommandLineWalker
+= 6;
797 if (StrStr (CommandLineWalker
, L
" 1>>v ") != NULL
) {
798 Status
= EFI_NOT_FOUND
;
800 } else if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" >>v ")) != NULL
)) {
801 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
802 SetMem16 (CommandLineWalker
, 10, L
' ');
803 StdOutVarName
= CommandLineWalker
+= 5;
805 if (StrStr (CommandLineWalker
, L
" >>v ") != NULL
) {
806 Status
= EFI_NOT_FOUND
;
808 } else if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" >v ")) != NULL
)) {
809 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
810 SetMem16 (CommandLineWalker
, 8, L
' ');
811 StdOutVarName
= CommandLineWalker
+= 4;
813 if (StrStr (CommandLineWalker
, L
" >v ") != NULL
) {
814 Status
= EFI_NOT_FOUND
;
818 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 1>>a ")) != NULL
)) {
819 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
820 SetMem16 (CommandLineWalker
, 12, L
' ');
821 StdOutFileName
= CommandLineWalker
+= 6;
824 if (StrStr (CommandLineWalker
, L
" 1>>a ") != NULL
) {
825 Status
= EFI_NOT_FOUND
;
829 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 1>> ")) != NULL
)) {
830 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
831 SetMem16 (CommandLineWalker
, 10, L
' ');
832 if (StdOutFileName
!= NULL
) {
833 Status
= EFI_INVALID_PARAMETER
;
835 StdOutFileName
= CommandLineWalker
+= 5;
839 if (StrStr (CommandLineWalker
, L
" 1>> ") != NULL
) {
840 Status
= EFI_NOT_FOUND
;
844 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" >> ")) != NULL
)) {
845 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
846 SetMem16 (CommandLineWalker
, 8, L
' ');
847 if (StdOutFileName
!= NULL
) {
848 Status
= EFI_INVALID_PARAMETER
;
850 StdOutFileName
= CommandLineWalker
+= 4;
854 if (StrStr (CommandLineWalker
, L
" >> ") != NULL
) {
855 Status
= EFI_NOT_FOUND
;
859 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" >>a ")) != NULL
)) {
860 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
861 SetMem16 (CommandLineWalker
, 10, L
' ');
862 if (StdOutFileName
!= NULL
) {
863 Status
= EFI_INVALID_PARAMETER
;
865 StdOutFileName
= CommandLineWalker
+= 5;
870 if (StrStr (CommandLineWalker
, L
" >>a ") != NULL
) {
871 Status
= EFI_NOT_FOUND
;
875 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 1>a ")) != NULL
)) {
876 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
877 SetMem16 (CommandLineWalker
, 10, L
' ');
878 if (StdOutFileName
!= NULL
) {
879 Status
= EFI_INVALID_PARAMETER
;
881 StdOutFileName
= CommandLineWalker
+= 5;
886 if (StrStr (CommandLineWalker
, L
" 1>a ") != NULL
) {
887 Status
= EFI_NOT_FOUND
;
891 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" >a ")) != NULL
)) {
892 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
893 SetMem16 (CommandLineWalker
, 8, L
' ');
894 if (StdOutFileName
!= NULL
) {
895 Status
= EFI_INVALID_PARAMETER
;
897 StdOutFileName
= CommandLineWalker
+= 4;
902 if (StrStr (CommandLineWalker
, L
" >a ") != NULL
) {
903 Status
= EFI_NOT_FOUND
;
907 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 2>> ")) != NULL
)) {
908 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
909 SetMem16 (CommandLineWalker
, 10, L
' ');
910 if (StdErrFileName
!= NULL
) {
911 Status
= EFI_INVALID_PARAMETER
;
913 StdErrFileName
= CommandLineWalker
+= 5;
917 if (StrStr (CommandLineWalker
, L
" 2>> ") != NULL
) {
918 Status
= EFI_NOT_FOUND
;
922 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 2>v ")) != NULL
)) {
923 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
924 SetMem16 (CommandLineWalker
, 10, L
' ');
925 if (StdErrVarName
!= NULL
) {
926 Status
= EFI_INVALID_PARAMETER
;
928 StdErrVarName
= CommandLineWalker
+= 5;
932 if (StrStr (CommandLineWalker
, L
" 2>v ") != NULL
) {
933 Status
= EFI_NOT_FOUND
;
937 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 1>v ")) != NULL
)) {
938 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
939 SetMem16 (CommandLineWalker
, 10, L
' ');
940 if (StdOutVarName
!= NULL
) {
941 Status
= EFI_INVALID_PARAMETER
;
943 StdOutVarName
= CommandLineWalker
+= 5;
947 if (StrStr (CommandLineWalker
, L
" 1>v ") != NULL
) {
948 Status
= EFI_NOT_FOUND
;
952 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 2>a ")) != NULL
)) {
953 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
954 SetMem16 (CommandLineWalker
, 10, L
' ');
955 if (StdErrFileName
!= NULL
) {
956 Status
= EFI_INVALID_PARAMETER
;
958 StdErrFileName
= CommandLineWalker
+= 5;
963 if (StrStr (CommandLineWalker
, L
" 2>a ") != NULL
) {
964 Status
= EFI_NOT_FOUND
;
968 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 2> ")) != NULL
)) {
969 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
970 SetMem16 (CommandLineWalker
, 8, L
' ');
971 if (StdErrFileName
!= NULL
) {
972 Status
= EFI_INVALID_PARAMETER
;
974 StdErrFileName
= CommandLineWalker
+= 4;
978 if (StrStr (CommandLineWalker
, L
" 2> ") != NULL
) {
979 Status
= EFI_NOT_FOUND
;
983 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" 1> ")) != NULL
)) {
984 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
985 SetMem16 (CommandLineWalker
, 8, L
' ');
986 if (StdOutFileName
!= NULL
) {
987 Status
= EFI_INVALID_PARAMETER
;
989 StdOutFileName
= CommandLineWalker
+= 4;
993 if (StrStr (CommandLineWalker
, L
" 1> ") != NULL
) {
994 Status
= EFI_NOT_FOUND
;
998 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" > ")) != NULL
)) {
999 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
1000 SetMem16 (CommandLineWalker
, 6, L
' ');
1001 if (StdOutFileName
!= NULL
) {
1002 Status
= EFI_INVALID_PARAMETER
;
1004 StdOutFileName
= CommandLineWalker
+= 3;
1008 if (StrStr (CommandLineWalker
, L
" > ") != NULL
) {
1009 Status
= EFI_NOT_FOUND
;
1013 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" < ")) != NULL
)) {
1014 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
1015 SetMem16 (CommandLineWalker
, 6, L
' ');
1016 if (StdInFileName
!= NULL
) {
1017 Status
= EFI_INVALID_PARAMETER
;
1019 StdInFileName
= CommandLineWalker
+= 3;
1022 if (StrStr (CommandLineWalker
, L
" < ") != NULL
) {
1023 Status
= EFI_NOT_FOUND
;
1027 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" <a ")) != NULL
)) {
1028 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
1029 SetMem16 (CommandLineWalker
, 8, L
' ');
1030 if (StdInFileName
!= NULL
) {
1031 Status
= EFI_INVALID_PARAMETER
;
1033 StdInFileName
= CommandLineWalker
+= 4;
1035 AsciiRedirection
= TRUE
;
1038 if (StrStr (CommandLineWalker
, L
" <a ") != NULL
) {
1039 Status
= EFI_NOT_FOUND
;
1043 if (!EFI_ERROR (Status
) && ((CommandLineWalker
= StrStr (CommandLineCopy
, L
" <v ")) != NULL
)) {
1044 FirstLocation
= MIN (CommandLineWalker
, FirstLocation
);
1045 SetMem16 (CommandLineWalker
, 8, L
' ');
1046 if (StdInVarName
!= NULL
) {
1047 Status
= EFI_INVALID_PARAMETER
;
1049 StdInVarName
= CommandLineWalker
+= 4;
1052 if (StrStr (CommandLineWalker
, L
" <v ") != NULL
) {
1053 Status
= EFI_NOT_FOUND
;
1058 // re-populate the string to support any filenames that were in quotes.
1060 StrnCpyS (CommandLineCopy
, StrSize (CommandLineCopy
)/sizeof (CHAR16
), NewCommandLine
, StrLen (NewCommandLine
));
1062 if ( (FirstLocation
!= CommandLineCopy
+ StrLen (CommandLineCopy
))
1063 && (((UINTN
)FirstLocation
- (UINTN
)CommandLineCopy
)/sizeof (CHAR16
) < StrLen (NewCommandLine
))
1066 *(NewCommandLine
+ ((UINTN
)FirstLocation
- (UINTN
)CommandLineCopy
)/sizeof (CHAR16
)) = CHAR_NULL
;
1069 if (!EFI_ERROR (Status
)) {
1070 if (StdErrFileName
!= NULL
) {
1071 if ((StdErrFileName
= FixFileName (StdErrFileName
)) == NULL
) {
1072 Status
= EFI_INVALID_PARAMETER
;
1076 if (StdOutFileName
!= NULL
) {
1077 if ((StdOutFileName
= FixFileName (StdOutFileName
)) == NULL
) {
1078 Status
= EFI_INVALID_PARAMETER
;
1082 if (StdInFileName
!= NULL
) {
1083 if ((StdInFileName
= FixFileName (StdInFileName
)) == NULL
) {
1084 Status
= EFI_INVALID_PARAMETER
;
1088 if (StdErrVarName
!= NULL
) {
1089 if ((StdErrVarName
= FixVarName (StdErrVarName
)) == NULL
) {
1090 Status
= EFI_INVALID_PARAMETER
;
1094 if (StdOutVarName
!= NULL
) {
1095 if ((StdOutVarName
= FixVarName (StdOutVarName
)) == NULL
) {
1096 Status
= EFI_INVALID_PARAMETER
;
1100 if (StdInVarName
!= NULL
) {
1101 if ((StdInVarName
= FixVarName (StdInVarName
)) == NULL
) {
1102 Status
= EFI_INVALID_PARAMETER
;
1107 // Verify not the same and not duplicating something from a split
1111 // Check that no 2 filenames are the same
1113 ((StdErrFileName
!= NULL
) && (StdOutFileName
!= NULL
) && (StringNoCaseCompare (&StdErrFileName
, &StdOutFileName
) == 0))
1114 || ((StdErrFileName
!= NULL
) && (StdInFileName
!= NULL
) && (StringNoCaseCompare (&StdErrFileName
, &StdInFileName
) == 0))
1115 || ((StdOutFileName
!= NULL
) && (StdInFileName
!= NULL
) && (StringNoCaseCompare (&StdOutFileName
, &StdInFileName
) == 0))
1117 // Check that no 2 variable names are the same
1119 || ((StdErrVarName
!= NULL
) && (StdInVarName
!= NULL
) && (StringNoCaseCompare (&StdErrVarName
, &StdInVarName
) == 0))
1120 || ((StdOutVarName
!= NULL
) && (StdInVarName
!= NULL
) && (StringNoCaseCompare (&StdOutVarName
, &StdInVarName
) == 0))
1121 || ((StdErrVarName
!= NULL
) && (StdOutVarName
!= NULL
) && (StringNoCaseCompare (&StdErrVarName
, &StdOutVarName
) == 0))
1123 // When a split (using | operator) is in place some are not allowed
1125 || ((Split
!= NULL
) && (Split
->SplitStdIn
!= NULL
) && ((StdInVarName
!= NULL
) || (StdInFileName
!= NULL
)))
1126 || ((Split
!= NULL
) && (Split
->SplitStdOut
!= NULL
) && ((StdOutVarName
!= NULL
) || (StdOutFileName
!= NULL
)))
1128 // Check that nothing is trying to be output to 2 locations.
1130 || ((StdErrFileName
!= NULL
) && (StdErrVarName
!= NULL
))
1131 || ((StdOutFileName
!= NULL
) && (StdOutVarName
!= NULL
))
1132 || ((StdInFileName
!= NULL
) && (StdInVarName
!= NULL
))
1134 // Check for no volatile environment variables
1136 || ((StdErrVarName
!= NULL
) && !EFI_ERROR (IsVolatileEnv (StdErrVarName
, &Volatile
)) && !Volatile
)
1137 || ((StdOutVarName
!= NULL
) && !EFI_ERROR (IsVolatileEnv (StdOutVarName
, &Volatile
)) && !Volatile
)
1139 // Cant redirect during a reconnect operation.
1141 || ( (StrStr (NewCommandLine
, L
"connect -r") != NULL
)
1142 && ((StdOutVarName
!= NULL
) || (StdOutFileName
!= NULL
) || (StdErrFileName
!= NULL
) || (StdErrVarName
!= NULL
)))
1144 // Check that filetypes (Unicode/Ascii) do not change during an append
1146 || ((StdOutFileName
!= NULL
) && OutUnicode
&& OutAppend
&& (!EFI_ERROR (ShellFileExists (StdOutFileName
)) && EFI_ERROR (IsUnicodeFile (StdOutFileName
))))
1147 || ((StdErrFileName
!= NULL
) && ErrUnicode
&& ErrAppend
&& (!EFI_ERROR (ShellFileExists (StdErrFileName
)) && EFI_ERROR (IsUnicodeFile (StdErrFileName
))))
1148 || ((StdOutFileName
!= NULL
) && !OutUnicode
&& OutAppend
&& (!EFI_ERROR (ShellFileExists (StdOutFileName
)) && !EFI_ERROR (IsUnicodeFile (StdOutFileName
))))
1149 || ((StdErrFileName
!= NULL
) && !ErrUnicode
&& ErrAppend
&& (!EFI_ERROR (ShellFileExists (StdErrFileName
)) && !EFI_ERROR (IsUnicodeFile (StdErrFileName
))))
1152 Status
= EFI_INVALID_PARAMETER
;
1153 ShellParameters
->StdIn
= *OldStdIn
;
1154 ShellParameters
->StdOut
= *OldStdOut
;
1155 ShellParameters
->StdErr
= *OldStdErr
;
1156 } else if (!EFI_ERROR (Status
)) {
1158 // Open the Std<Whatever> and we should not have conflicts here...
1164 if (StdErrFileName
!= NULL
) {
1167 // delete existing file.
1169 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName (StdErrFileName
);
1172 Status
= ShellOpenFileByName (StdErrFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
, 0);
1173 if (!ErrAppend
&& ErrUnicode
&& !EFI_ERROR (Status
)) {
1174 Status
= WriteFileTag (TempHandle
);
1177 if (!ErrUnicode
&& !EFI_ERROR (Status
)) {
1178 TempHandle
= CreateFileInterfaceFile (TempHandle
, FALSE
);
1179 ASSERT (TempHandle
!= NULL
);
1182 if (!EFI_ERROR (Status
)) {
1183 ShellParameters
->StdErr
= TempHandle
;
1184 gST
->StdErr
= CreateSimpleTextOutOnFile (TempHandle
, &gST
->StandardErrorHandle
, gST
->StdErr
);
1191 if (!EFI_ERROR (Status
) && (StdOutFileName
!= NULL
)) {
1194 // delete existing file.
1196 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName (StdOutFileName
);
1199 Status
= ShellOpenFileByName (StdOutFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
, 0);
1200 if (TempHandle
== NULL
) {
1201 Status
= EFI_INVALID_PARAMETER
;
1203 if (gUnicodeCollation
->MetaiMatch (gUnicodeCollation
, StdOutFileName
, L
"NUL")) {
1205 } else if (!OutAppend
&& OutUnicode
&& !EFI_ERROR (Status
)) {
1206 Status
= WriteFileTag (TempHandle
);
1207 } else if (OutAppend
) {
1208 Status
= ShellInfoObject
.NewEfiShellProtocol
->GetFileSize (TempHandle
, &FileSize
);
1209 if (!EFI_ERROR (Status
)) {
1211 // When appending to a new unicode file, write the file tag.
1212 // Otherwise (ie. when appending to a new ASCII file, or an
1213 // existent file with any encoding), just seek to the end.
1215 Status
= (FileSize
== 0 && OutUnicode
) ?
1216 WriteFileTag (TempHandle
) :
1217 ShellInfoObject
.NewEfiShellProtocol
->SetFilePosition (
1224 if (!OutUnicode
&& !EFI_ERROR (Status
)) {
1225 TempHandle
= CreateFileInterfaceFile (TempHandle
, FALSE
);
1226 ASSERT (TempHandle
!= NULL
);
1229 if (!EFI_ERROR (Status
)) {
1230 ShellParameters
->StdOut
= TempHandle
;
1231 gST
->ConOut
= CreateSimpleTextOutOnFile (TempHandle
, &gST
->ConsoleOutHandle
, gST
->ConOut
);
1239 if (!EFI_ERROR (Status
) && (StdOutVarName
!= NULL
)) {
1242 // delete existing variable.
1244 SHELL_SET_ENVIRONMENT_VARIABLE_V (StdOutVarName
, 0, L
"");
1247 TempHandle
= CreateFileInterfaceEnv (StdOutVarName
);
1248 ASSERT (TempHandle
!= NULL
);
1249 ShellParameters
->StdOut
= TempHandle
;
1250 gST
->ConOut
= CreateSimpleTextOutOnFile (TempHandle
, &gST
->ConsoleOutHandle
, gST
->ConOut
);
1256 if (!EFI_ERROR (Status
) && (StdErrVarName
!= NULL
)) {
1259 // delete existing variable.
1261 SHELL_SET_ENVIRONMENT_VARIABLE_V (StdErrVarName
, 0, L
"");
1264 TempHandle
= CreateFileInterfaceEnv (StdErrVarName
);
1265 ASSERT (TempHandle
!= NULL
);
1266 ShellParameters
->StdErr
= TempHandle
;
1267 gST
->StdErr
= CreateSimpleTextOutOnFile (TempHandle
, &gST
->StandardErrorHandle
, gST
->StdErr
);
1273 if (!EFI_ERROR (Status
) && (StdInVarName
!= NULL
)) {
1274 TempHandle
= CreateFileInterfaceEnv (StdInVarName
);
1275 if (TempHandle
== NULL
) {
1276 Status
= EFI_OUT_OF_RESOURCES
;
1279 TempHandle
= CreateFileInterfaceFile (TempHandle
, FALSE
);
1283 if ((TempHandle
== NULL
) || (((EFI_FILE_PROTOCOL
*)TempHandle
)->Read (TempHandle
, &Size
, NULL
) != EFI_BUFFER_TOO_SMALL
)) {
1284 Status
= EFI_INVALID_PARAMETER
;
1286 ShellParameters
->StdIn
= TempHandle
;
1287 gST
->ConIn
= CreateSimpleTextInOnFile (TempHandle
, &gST
->ConsoleInHandle
);
1293 // StdIn from a file
1295 if (!EFI_ERROR (Status
) && (StdInFileName
!= NULL
)) {
1296 Status
= ShellOpenFileByName (
1302 if (!EFI_ERROR (Status
)) {
1305 // Create the ASCII->Unicode conversion layer
1307 TempHandle
= CreateFileInterfaceFile (TempHandle
, FALSE
);
1310 ShellParameters
->StdIn
= TempHandle
;
1311 gST
->ConIn
= CreateSimpleTextInOnFile (TempHandle
, &gST
->ConsoleInHandle
);
1317 FreePool (CommandLineCopy
);
1319 CalculateEfiHdrCrc (&gST
->Hdr
);
1321 if ((gST
->ConIn
== NULL
) || (gST
->ConOut
== NULL
)) {
1322 Status
= EFI_OUT_OF_RESOURCES
;
1325 if (Status
== EFI_NOT_FOUND
) {
1326 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR
), ShellInfoObject
.HiiHandle
);
1327 } else if (EFI_ERROR (Status
)) {
1328 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SHELL_INVALID_REDIR
), ShellInfoObject
.HiiHandle
);
1335 Function will replace the current StdIn and StdOut in the ShellParameters protocol
1336 structure with StdIn and StdOut. The current values are de-allocated.
1338 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1339 @param[in] OldStdIn Pointer to old StdIn.
1340 @param[in] OldStdOut Pointer to old StdOut.
1341 @param[in] OldStdErr Pointer to old StdErr.
1342 @param[in] SystemTableInfo Pointer to old system table information.
1345 RestoreStdInStdOutStdErr (
1346 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1347 IN SHELL_FILE_HANDLE
*OldStdIn
,
1348 IN SHELL_FILE_HANDLE
*OldStdOut
,
1349 IN SHELL_FILE_HANDLE
*OldStdErr
,
1350 IN SYSTEM_TABLE_INFO
*SystemTableInfo
1355 if ( (ShellParameters
== NULL
)
1356 || (OldStdIn
== NULL
)
1357 || (OldStdOut
== NULL
)
1358 || (OldStdErr
== NULL
)
1359 || (SystemTableInfo
== NULL
))
1361 return (EFI_INVALID_PARAMETER
);
1364 if (!IsListEmpty (&ShellInfoObject
.SplitList
.Link
)) {
1365 Split
= (SPLIT_LIST
*)GetFirstNode (&ShellInfoObject
.SplitList
.Link
);
1370 if (ShellParameters
->StdIn
!= *OldStdIn
) {
1371 if (((Split
!= NULL
) && (Split
->SplitStdIn
!= ShellParameters
->StdIn
)) || (Split
== NULL
)) {
1372 gEfiShellProtocol
->CloseFile (ShellParameters
->StdIn
);
1375 ShellParameters
->StdIn
= *OldStdIn
;
1378 if (ShellParameters
->StdOut
!= *OldStdOut
) {
1379 if (((Split
!= NULL
) && (Split
->SplitStdOut
!= ShellParameters
->StdOut
)) || (Split
== NULL
)) {
1380 gEfiShellProtocol
->CloseFile (ShellParameters
->StdOut
);
1383 ShellParameters
->StdOut
= *OldStdOut
;
1386 if (ShellParameters
->StdErr
!= *OldStdErr
) {
1387 gEfiShellProtocol
->CloseFile (ShellParameters
->StdErr
);
1388 ShellParameters
->StdErr
= *OldStdErr
;
1391 if (gST
->ConIn
!= SystemTableInfo
->ConIn
) {
1392 CloseSimpleTextInOnFile (gST
->ConIn
);
1393 gST
->ConIn
= SystemTableInfo
->ConIn
;
1394 gST
->ConsoleInHandle
= SystemTableInfo
->ConInHandle
;
1397 if (gST
->ConOut
!= SystemTableInfo
->ConOut
) {
1398 CloseSimpleTextOutOnFile (gST
->ConOut
);
1399 gST
->ConOut
= SystemTableInfo
->ConOut
;
1400 gST
->ConsoleOutHandle
= SystemTableInfo
->ConOutHandle
;
1403 if (gST
->StdErr
!= SystemTableInfo
->ErrOut
) {
1404 CloseSimpleTextOutOnFile (gST
->StdErr
);
1405 gST
->StdErr
= SystemTableInfo
->ErrOut
;
1406 gST
->StandardErrorHandle
= SystemTableInfo
->ErrOutHandle
;
1409 CalculateEfiHdrCrc (&gST
->Hdr
);
1411 return (EFI_SUCCESS
);
1415 Function will replace the current Argc and Argv in the ShellParameters protocol
1416 structure by parsing NewCommandLine. The current values are returned to the
1419 If OldArgv or OldArgc is NULL then that value is not returned.
1421 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1422 @param[in] NewCommandLine The new command line to parse and use.
1423 @param[in] Type The type of operation.
1424 @param[out] OldArgv Pointer to old list of parameters.
1425 @param[out] OldArgc Pointer to old number of items in Argv list.
1428 @retval EFI_SUCCESS Operation was successful, Argv and Argc are valid.
1429 @return EFI_INVALID_PARAMETER Some parameters are invalid.
1430 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1434 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1435 IN CONST CHAR16
*NewCommandLine
,
1436 IN SHELL_OPERATION_TYPES Type
,
1437 OUT CHAR16
***OldArgv OPTIONAL
,
1438 OUT UINTN
*OldArgc OPTIONAL
1441 BOOLEAN StripParamQuotation
;
1443 ASSERT (ShellParameters
!= NULL
);
1444 StripParamQuotation
= TRUE
;
1446 if (OldArgc
!= NULL
) {
1447 *OldArgc
= ShellParameters
->Argc
;
1450 if (OldArgc
!= NULL
) {
1451 *OldArgv
= ShellParameters
->Argv
;
1454 if (Type
== Script_File_Name
) {
1455 StripParamQuotation
= FALSE
;
1458 return ParseCommandLineToArgs (
1460 StripParamQuotation
,
1461 &(ShellParameters
->Argv
),
1462 &(ShellParameters
->Argc
)
1467 Function will replace the current Argc and Argv in the ShellParameters protocol
1468 structure with Argv and Argc. The current values are de-allocated and the
1469 OldArgv must not be deallocated by the caller.
1471 @param[in, out] ShellParameters pointer to parameter structure to modify
1472 @param[in] OldArgv pointer to old list of parameters
1473 @param[in] OldArgc pointer to old number of items in Argv list
1477 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1478 IN CHAR16
***OldArgv
,
1484 ASSERT (ShellParameters
!= NULL
);
1485 ASSERT (OldArgv
!= NULL
);
1486 ASSERT (OldArgc
!= NULL
);
1488 if (ShellParameters
->Argv
!= NULL
) {
1489 for ( LoopCounter
= 0
1490 ; LoopCounter
< ShellParameters
->Argc
1494 FreePool (ShellParameters
->Argv
[LoopCounter
]);
1497 FreePool (ShellParameters
->Argv
);
1500 ShellParameters
->Argv
= *OldArgv
;
1502 ShellParameters
->Argc
= *OldArgc
;