2 Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,
3 manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
5 Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
6 Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 return the next parameter from a command line string;
22 This function moves the next parameter from Walker into TempParameter and moves
23 Walker up past that parameter for recursive calling. When the final parameter
24 is moved *Walker will be set to NULL;
26 Temp Parameter must be large enough to hold the parameter before calling this
29 @param[in, out] Walker pointer to string of command line. Adjusted to
30 reminaing command line on return
31 @param[in, out] TempParameter pointer to string of command line item extracted.
38 CHAR16
**TempParameter
44 ASSERT(Walker
!= NULL
);
45 ASSERT(*Walker
!= NULL
);
46 ASSERT(TempParameter
!= NULL
);
47 ASSERT(*TempParameter
!= NULL
);
50 // make sure we dont have any leading spaces
52 while ((*Walker
)[0] == L
' ') {
57 // make sure we still have some params now...
59 if (StrLen(*Walker
) == 0) {
60 ASSERT((*Walker
)[0] == CHAR_NULL
);
66 // we have a quoted parameter
67 // could be the last parameter, but SHOULD have a trailing quote
69 if ((*Walker
)[0] == L
'\"') {
71 for (TempLoc
= *Walker
+ 1 ; TempLoc
!= NULL
&& *TempLoc
!= CHAR_NULL
; TempLoc
++) {
72 if (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'\"') {
74 } else if (*TempLoc
== L
'\"') {
80 if (NextDelim
- ((*Walker
)+1) == 0) {
84 StrCpy(*TempParameter
, L
"");
85 *Walker
= NextDelim
+ 1;
86 } else if (NextDelim
!= NULL
) {
87 StrnCpy(*TempParameter
, (*Walker
)+1, NextDelim
- ((*Walker
)+1));
88 *Walker
= NextDelim
+ 1;
91 // last one... someone forgot the training quote!
93 StrCpy(*TempParameter
, *Walker
);
96 for (TempLoc
= *TempParameter
; TempLoc
!= NULL
&& *TempLoc
!= CHAR_NULL
; TempLoc
++) {
97 if (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'\"') {
98 CopyMem(TempLoc
, TempLoc
+1, StrSize(TempLoc
) - sizeof(TempLoc
[0]));
103 // we have a regular parameter (no quote) OR
104 // we have the final parameter (no trailing space)
106 NextDelim
= StrStr((*Walker
), L
" ");
107 if (NextDelim
!= NULL
) {
108 StrnCpy(*TempParameter
, *Walker
, NextDelim
- (*Walker
));
109 (*TempParameter
)[NextDelim
- (*Walker
)] = CHAR_NULL
;
110 *Walker
= NextDelim
+1;
115 StrCpy(*TempParameter
, *Walker
);
118 for (NextDelim
= *TempParameter
; NextDelim
!= NULL
&& *NextDelim
!= CHAR_NULL
; NextDelim
++) {
119 if (*NextDelim
== L
'^' && *(NextDelim
+1) == L
'^') {
120 CopyMem(NextDelim
, NextDelim
+1, StrSize(NextDelim
) - sizeof(NextDelim
[0]));
123 while ((*TempParameter
)[StrLen(*TempParameter
)-1] == L
' ') {
124 (*TempParameter
)[StrLen(*TempParameter
)-1] = CHAR_NULL
;
126 while ((*TempParameter
)[0] == L
' ') {
127 CopyMem(*TempParameter
, (*TempParameter
)+1, StrSize(*TempParameter
) - sizeof((*TempParameter
)[0]));
134 Function to populate Argc and Argv.
136 This function parses the CommandLine and divides it into standard C style Argc/Argv
137 parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space
138 delimited and quote surrounded parameter definition.
140 @param[in] CommandLine String of command line to parse
141 @param[in, out] Argv pointer to array of strings; one for each parameter
142 @param[in, out] Argc pointer to number of strings in Argv array
144 @return EFI_SUCCESS the operation was sucessful
145 @return EFI_OUT_OF_RESOURCES a memory allocation failed.
149 ParseCommandLineToArgs(
150 IN CONST CHAR16
*CommandLine
,
151 IN OUT CHAR16
***Argv
,
156 CHAR16
*TempParameter
;
161 ASSERT(Argc
!= NULL
);
162 ASSERT(Argv
!= NULL
);
164 if (CommandLine
== NULL
|| StrLen(CommandLine
)==0) {
167 return (EFI_SUCCESS
);
170 Size
= StrSize(CommandLine
);
171 TempParameter
= AllocateZeroPool(Size
);
172 if (TempParameter
== NULL
) {
173 return (EFI_OUT_OF_RESOURCES
);
177 , Walker
= (CHAR16
*)CommandLine
178 ; Walker
!= NULL
&& *Walker
!= CHAR_NULL
179 ; GetNextParameter(&Walker
, &TempParameter
)
184 Walker = (CHAR16*)CommandLine;
185 while(Walker != NULL) {
186 GetNextParameter(&Walker, &TempParameter);
191 // lets allocate the pointer array
193 (*Argv
) = AllocateZeroPool((Count
)*sizeof(CHAR16
*));
195 SHELL_FREE_NON_NULL(TempParameter
);
196 return (EFI_OUT_OF_RESOURCES
);
200 Walker
= (CHAR16
*)CommandLine
;
201 while(Walker
!= NULL
&& *Walker
!= CHAR_NULL
) {
202 SetMem16(TempParameter
, Size
, CHAR_NULL
);
203 GetNextParameter(&Walker
, &TempParameter
);
204 NewParam
= AllocateZeroPool(StrSize(TempParameter
));
205 ASSERT(NewParam
!= NULL
);
206 StrCpy(NewParam
, TempParameter
);
207 ((CHAR16
**)(*Argv
))[(*Argc
)] = NewParam
;
210 ASSERT(Count
>= (*Argc
));
211 SHELL_FREE_NON_NULL(TempParameter
);
212 return (EFI_SUCCESS
);
216 creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
217 installs it on our handle and if there is an existing version of the protocol
218 that one is cached for removal later.
220 @param[in, out] NewShellParameters on a successful return, a pointer to pointer
221 to the newly installed interface.
222 @param[in, out] RootShellInstance on a successful return, pointer to boolean.
223 TRUE if this is the root shell instance.
225 @retval EFI_SUCCESS the operation completed successfully.
226 @return other the operation failed.
227 @sa ReinstallProtocolInterface
228 @sa InstallProtocolInterface
229 @sa ParseCommandLineToArgs
233 CreatePopulateInstallShellParametersProtocol (
234 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
**NewShellParameters
,
235 IN OUT BOOLEAN
*RootShellInstance
239 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
240 CHAR16
*FullCommandLine
;
244 FullCommandLine
= NULL
;
248 // Assert for valid parameters
250 ASSERT(NewShellParameters
!= NULL
);
251 ASSERT(RootShellInstance
!= NULL
);
254 // See if we have a shell parameters placed on us
256 Status
= gBS
->OpenProtocol (
258 &gEfiShellParametersProtocolGuid
,
259 (VOID
**) &ShellInfoObject
.OldShellParameters
,
262 EFI_OPEN_PROTOCOL_GET_PROTOCOL
265 // if we don't then we must be the root shell (error is expected)
267 if (EFI_ERROR (Status
)) {
268 *RootShellInstance
= TRUE
;
272 // Allocate the new structure
274 *NewShellParameters
= AllocateZeroPool(sizeof(EFI_SHELL_PARAMETERS_PROTOCOL
));
275 if ((*NewShellParameters
) == NULL
) {
276 return (EFI_OUT_OF_RESOURCES
);
280 // get loaded image protocol
282 Status
= gBS
->OpenProtocol (
284 &gEfiLoadedImageProtocolGuid
,
285 (VOID
**) &LoadedImage
,
288 EFI_OPEN_PROTOCOL_GET_PROTOCOL
290 ASSERT_EFI_ERROR(Status
);
292 // Build the full command line
294 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, FullCommandLine
);
295 if (Status
== EFI_BUFFER_TOO_SMALL
) {
296 FullCommandLine
= AllocateZeroPool(Size
+ LoadedImage
->LoadOptionsSize
);
297 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, FullCommandLine
);
299 if (Status
== EFI_NOT_FOUND
) {
301 // no parameters via environment... ok
304 if (EFI_ERROR(Status
)) {
308 if (Size
== 0 && LoadedImage
->LoadOptionsSize
!= 0) {
309 ASSERT(FullCommandLine
== NULL
);
311 // Now we need to include a NULL terminator in the size.
313 Size
= LoadedImage
->LoadOptionsSize
+ sizeof(FullCommandLine
[0]);
314 FullCommandLine
= AllocateZeroPool(Size
);
316 if (FullCommandLine
!= NULL
) {
317 CopyMem (FullCommandLine
, LoadedImage
->LoadOptions
, LoadedImage
->LoadOptionsSize
);
319 // Populate Argc and Argv
321 Status
= ParseCommandLineToArgs(FullCommandLine
,
322 &(*NewShellParameters
)->Argv
,
323 &(*NewShellParameters
)->Argc
);
325 FreePool(FullCommandLine
);
327 ASSERT_EFI_ERROR(Status
);
329 (*NewShellParameters
)->Argv
= NULL
;
330 (*NewShellParameters
)->Argc
= 0;
334 // Populate the 3 faked file systems...
336 if (*RootShellInstance
) {
337 (*NewShellParameters
)->StdIn
= &FileInterfaceStdIn
;
338 (*NewShellParameters
)->StdOut
= &FileInterfaceStdOut
;
339 (*NewShellParameters
)->StdErr
= &FileInterfaceStdErr
;
340 Status
= gBS
->InstallProtocolInterface(&gImageHandle
,
341 &gEfiShellParametersProtocolGuid
,
342 EFI_NATIVE_INTERFACE
,
343 (VOID
*)(*NewShellParameters
));
346 // copy from the existing ones
348 (*NewShellParameters
)->StdIn
= ShellInfoObject
.OldShellParameters
->StdIn
;
349 (*NewShellParameters
)->StdOut
= ShellInfoObject
.OldShellParameters
->StdOut
;
350 (*NewShellParameters
)->StdErr
= ShellInfoObject
.OldShellParameters
->StdErr
;
351 Status
= gBS
->ReinstallProtocolInterface(gImageHandle
,
352 &gEfiShellParametersProtocolGuid
,
353 (VOID
*)ShellInfoObject
.OldShellParameters
,
354 (VOID
*)(*NewShellParameters
));
361 frees all memory used by createion and installation of shell parameters protocol
362 and if there was an old version installed it will restore that one.
364 @param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
367 @retval EFI_SUCCESS the cleanup was successful
368 @return other the cleanup failed
369 @sa ReinstallProtocolInterface
370 @sa UninstallProtocolInterface
374 CleanUpShellParametersProtocol (
375 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*NewShellParameters
382 // If the old exists we need to restore it
384 if (ShellInfoObject
.OldShellParameters
!= NULL
) {
385 Status
= gBS
->ReinstallProtocolInterface(gImageHandle
,
386 &gEfiShellParametersProtocolGuid
,
387 (VOID
*)NewShellParameters
,
388 (VOID
*)ShellInfoObject
.OldShellParameters
);
389 DEBUG_CODE(ShellInfoObject
.OldShellParameters
= NULL
;);
392 // No old one, just uninstall us...
394 Status
= gBS
->UninstallProtocolInterface(gImageHandle
,
395 &gEfiShellParametersProtocolGuid
,
396 (VOID
*)NewShellParameters
);
398 if (NewShellParameters
->Argv
!= NULL
) {
399 for ( LoopCounter
= 0
400 ; LoopCounter
< NewShellParameters
->Argc
403 FreePool(NewShellParameters
->Argv
[LoopCounter
]);
405 FreePool(NewShellParameters
->Argv
);
407 FreePool(NewShellParameters
);
412 Determin if a file name represents a unicode file.
414 @param[in] FileName Pointer to the filename to open.
416 @retval EFI_SUCCESS The file is a unicode file.
417 @return An error upon failure.
422 IN CONST CHAR16
*FileName
425 SHELL_FILE_HANDLE Handle
;
427 UINT64 OriginalFilePosition
;
431 Status
= gEfiShellProtocol
->OpenFileByName(FileName
, &Handle
, EFI_FILE_MODE_READ
);
432 if (EFI_ERROR(Status
)) {
435 gEfiShellProtocol
->GetFilePosition(Handle
, &OriginalFilePosition
);
436 gEfiShellProtocol
->SetFilePosition(Handle
, 0);
437 CharSize
= sizeof(CHAR16
);
438 Status
= gEfiShellProtocol
->ReadFile(Handle
, &CharSize
, &CharBuffer
);
439 if (EFI_ERROR(Status
) || CharBuffer
!= gUnicodeFileTag
) {
440 Status
= EFI_BUFFER_TOO_SMALL
;
442 gEfiShellProtocol
->SetFilePosition(Handle
, OriginalFilePosition
);
443 gEfiShellProtocol
->CloseFile(Handle
);
448 Strips out quotes sections of a string.
450 All of the characters between quotes is replaced with spaces.
452 @param[in, out] TheString A pointer to the string to update.
457 IN OUT CHAR16
*TheString
462 for (RemoveNow
= FALSE
; TheString
!= NULL
&& *TheString
!= CHAR_NULL
; TheString
++) {
463 if (*TheString
== L
'^' && *(TheString
+ 1) == L
'\"') {
465 } else if (*TheString
== L
'\"') {
466 RemoveNow
= (BOOLEAN
)!RemoveNow
;
467 } else if (RemoveNow
) {
474 Calcualte the 32-bit CRC in a EFI table using the service provided by the
477 @param Hdr Pointer to an EFI standard header
482 IN OUT EFI_TABLE_HEADER
*Hdr
490 // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
491 // Crc will come back as zero if we set it to zero here
494 gBS
->CalculateCrc32 ((UINT8
*)Hdr
, Hdr
->HeaderSize
, &Crc
);
499 Fix a string to only have the file name, removing starting at the first space of whatever is quoted.
501 @param[in] FileName The filename to start with.
503 @retval NULL FileName was invalid.
504 @return The modified FileName.
513 CHAR16
*TempLocation
;
515 if (FileName
== NULL
) {
519 if (FileName
[0] == L
'\"') {
521 if ((TempLocation
= StrStr(Copy
, L
"\"")) != NULL
) {
522 TempLocation
[0] = CHAR_NULL
;
526 while(Copy
[0] == L
' ') {
529 if ((TempLocation
= StrStr(Copy
, L
" ")) != NULL
) {
530 TempLocation
[0] = CHAR_NULL
;
534 if (Copy
[0] == CHAR_NULL
) {
542 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 %.
544 @param[in] FileName The filename to start with.
546 @retval NULL FileName was invalid.
547 @return The modified FileName.
556 CHAR16
*TempLocation
;
560 if (FileName
[0] == L
'%') {
562 if ((TempLocation
= StrStr(Copy
, L
"%")) != NULL
) {
563 TempLocation
[0] = CHAR_NULL
;
567 return (FixFileName(Copy
));
571 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
572 structure by parsing NewCommandLine. The current values are returned to the
575 This will also update the system table.
577 @param[in, out] ShellParameters Pointer to parameter structure to modify.
578 @param[in] NewCommandLine The new command line to parse and use.
579 @param[out] OldStdIn Pointer to old StdIn.
580 @param[out] OldStdOut Pointer to old StdOut.
581 @param[out] OldStdErr Pointer to old StdErr.
582 @param[out] SystemTableInfo Pointer to old system table information.
584 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
585 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
589 UpdateStdInStdOutStdErr(
590 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
591 IN CHAR16
*NewCommandLine
,
592 OUT SHELL_FILE_HANDLE
*OldStdIn
,
593 OUT SHELL_FILE_HANDLE
*OldStdOut
,
594 OUT SHELL_FILE_HANDLE
*OldStdErr
,
595 OUT SYSTEM_TABLE_INFO
*SystemTableInfo
598 CHAR16
*CommandLineCopy
;
599 CHAR16
*CommandLineWalker
;
600 CHAR16
*StdErrFileName
;
601 CHAR16
*StdOutFileName
;
602 CHAR16
*StdInFileName
;
603 CHAR16
*StdInVarName
;
604 CHAR16
*StdOutVarName
;
605 CHAR16
*StdErrVarName
;
607 SHELL_FILE_HANDLE TempHandle
;
617 CHAR16
*FirstLocation
;
623 StdOutVarName
= NULL
;
624 StdErrVarName
= NULL
;
625 StdErrFileName
= NULL
;
626 StdInFileName
= NULL
;
627 StdOutFileName
= NULL
;
630 CommandLineCopy
= NULL
;
631 FirstLocation
= NULL
;
633 if (ShellParameters
== NULL
|| SystemTableInfo
== NULL
|| OldStdIn
== NULL
|| OldStdOut
== NULL
|| OldStdErr
== NULL
) {
634 return (EFI_INVALID_PARAMETER
);
637 SystemTableInfo
->ConIn
= gST
->ConIn
;
638 SystemTableInfo
->ConInHandle
= gST
->ConsoleInHandle
;
639 SystemTableInfo
->ConOut
= gST
->ConOut
;
640 SystemTableInfo
->ConOutHandle
= gST
->ConsoleOutHandle
;
641 SystemTableInfo
->ErrOut
= gST
->StdErr
;
642 SystemTableInfo
->ErrOutHandle
= gST
->StandardErrorHandle
;
643 *OldStdIn
= ShellParameters
->StdIn
;
644 *OldStdOut
= ShellParameters
->StdOut
;
645 *OldStdErr
= ShellParameters
->StdErr
;
647 if (NewCommandLine
== NULL
) {
648 return (EFI_SUCCESS
);
651 CommandLineCopy
= StrnCatGrow(&CommandLineCopy
, NULL
, NewCommandLine
, 0);
652 if (CommandLineCopy
== NULL
) {
653 return (EFI_OUT_OF_RESOURCES
);
655 Status
= EFI_SUCCESS
;
657 FirstLocation
= CommandLineCopy
+ StrLen(CommandLineCopy
);
659 StripQuotes(CommandLineCopy
);
661 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
662 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
663 if (Split
!= NULL
&& Split
->SplitStdIn
!= NULL
) {
664 ShellParameters
->StdIn
= Split
->SplitStdIn
;
666 if (Split
!= NULL
&& Split
->SplitStdOut
!= NULL
) {
667 ShellParameters
->StdOut
= Split
->SplitStdOut
;
671 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>>v ")) != NULL
) {
672 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
673 SetMem16(CommandLineWalker
, 12, L
' ');
674 StdErrVarName
= CommandLineWalker
+= 6;
676 if (StrStr(CommandLineWalker
, L
" 2>>v ") != NULL
) {
677 Status
= EFI_NOT_FOUND
;
680 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>v ")) != NULL
) {
681 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
682 SetMem16(CommandLineWalker
, 12, L
' ');
683 StdOutVarName
= CommandLineWalker
+= 6;
685 if (StrStr(CommandLineWalker
, L
" 1>>v ") != NULL
) {
686 Status
= EFI_NOT_FOUND
;
688 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>v ")) != NULL
) {
689 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
690 SetMem16(CommandLineWalker
, 10, L
' ');
691 StdOutVarName
= CommandLineWalker
+= 5;
693 if (StrStr(CommandLineWalker
, L
" >>v ") != NULL
) {
694 Status
= EFI_NOT_FOUND
;
696 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >v ")) != NULL
) {
697 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
698 SetMem16(CommandLineWalker
, 8, L
' ');
699 StdOutVarName
= CommandLineWalker
+= 4;
701 if (StrStr(CommandLineWalker
, L
" >v ") != NULL
) {
702 Status
= EFI_NOT_FOUND
;
705 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>a ")) != NULL
) {
706 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
707 SetMem16(CommandLineWalker
, 12, L
' ');
708 StdOutFileName
= CommandLineWalker
+= 6;
711 if (StrStr(CommandLineWalker
, L
" 1>>a ") != NULL
) {
712 Status
= EFI_NOT_FOUND
;
715 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>> ")) != NULL
) {
716 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
717 SetMem16(CommandLineWalker
, 10, L
' ');
718 if (StdOutFileName
!= NULL
) {
719 Status
= EFI_INVALID_PARAMETER
;
721 StdOutFileName
= CommandLineWalker
+= 5;
724 if (StrStr(CommandLineWalker
, L
" 1>> ") != NULL
) {
725 Status
= EFI_NOT_FOUND
;
728 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >> ")) != NULL
) {
729 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
730 SetMem16(CommandLineWalker
, 8, L
' ');
731 if (StdOutFileName
!= NULL
) {
732 Status
= EFI_INVALID_PARAMETER
;
734 StdOutFileName
= CommandLineWalker
+= 4;
737 if (StrStr(CommandLineWalker
, L
" >> ") != NULL
) {
738 Status
= EFI_NOT_FOUND
;
741 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>a ")) != NULL
) {
742 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
743 SetMem16(CommandLineWalker
, 10, L
' ');
744 if (StdOutFileName
!= NULL
) {
745 Status
= EFI_INVALID_PARAMETER
;
747 StdOutFileName
= CommandLineWalker
+= 5;
751 if (StrStr(CommandLineWalker
, L
" >>a ") != NULL
) {
752 Status
= EFI_NOT_FOUND
;
755 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>a ")) != NULL
) {
756 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
757 SetMem16(CommandLineWalker
, 10, L
' ');
758 if (StdOutFileName
!= NULL
) {
759 Status
= EFI_INVALID_PARAMETER
;
761 StdOutFileName
= CommandLineWalker
+= 5;
765 if (StrStr(CommandLineWalker
, L
" 1>a ") != NULL
) {
766 Status
= EFI_NOT_FOUND
;
769 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >a ")) != NULL
) {
770 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
771 SetMem16(CommandLineWalker
, 8, L
' ');
772 if (StdOutFileName
!= NULL
) {
773 Status
= EFI_INVALID_PARAMETER
;
775 StdOutFileName
= CommandLineWalker
+= 4;
779 if (StrStr(CommandLineWalker
, L
" >a ") != NULL
) {
780 Status
= EFI_NOT_FOUND
;
783 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>> ")) != NULL
) {
784 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
785 SetMem16(CommandLineWalker
, 10, L
' ');
786 if (StdErrFileName
!= NULL
) {
787 Status
= EFI_INVALID_PARAMETER
;
789 StdErrFileName
= CommandLineWalker
+= 5;
792 if (StrStr(CommandLineWalker
, L
" 2>> ") != NULL
) {
793 Status
= EFI_NOT_FOUND
;
797 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>v ")) != NULL
) {
798 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
799 SetMem16(CommandLineWalker
, 10, L
' ');
800 if (StdErrVarName
!= NULL
) {
801 Status
= EFI_INVALID_PARAMETER
;
803 StdErrVarName
= CommandLineWalker
+= 5;
806 if (StrStr(CommandLineWalker
, L
" 2>v ") != NULL
) {
807 Status
= EFI_NOT_FOUND
;
810 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>v ")) != NULL
) {
811 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
812 SetMem16(CommandLineWalker
, 10, L
' ');
813 if (StdOutVarName
!= NULL
) {
814 Status
= EFI_INVALID_PARAMETER
;
816 StdOutVarName
= CommandLineWalker
+= 5;
819 if (StrStr(CommandLineWalker
, L
" 1>v ") != NULL
) {
820 Status
= EFI_NOT_FOUND
;
823 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>a ")) != NULL
) {
824 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
825 SetMem16(CommandLineWalker
, 10, L
' ');
826 if (StdErrFileName
!= NULL
) {
827 Status
= EFI_INVALID_PARAMETER
;
829 StdErrFileName
= CommandLineWalker
+= 5;
833 if (StrStr(CommandLineWalker
, L
" 2>a ") != NULL
) {
834 Status
= EFI_NOT_FOUND
;
837 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2> ")) != NULL
) {
838 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
839 SetMem16(CommandLineWalker
, 8, L
' ');
840 if (StdErrFileName
!= NULL
) {
841 Status
= EFI_INVALID_PARAMETER
;
843 StdErrFileName
= CommandLineWalker
+= 4;
846 if (StrStr(CommandLineWalker
, L
" 2> ") != NULL
) {
847 Status
= EFI_NOT_FOUND
;
851 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1> ")) != NULL
) {
852 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
853 SetMem16(CommandLineWalker
, 8, L
' ');
854 if (StdOutFileName
!= NULL
) {
855 Status
= EFI_INVALID_PARAMETER
;
857 StdOutFileName
= CommandLineWalker
+= 4;
860 if (StrStr(CommandLineWalker
, L
" 1> ") != NULL
) {
861 Status
= EFI_NOT_FOUND
;
865 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" > ")) != NULL
) {
866 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
867 SetMem16(CommandLineWalker
, 6, L
' ');
868 if (StdOutFileName
!= NULL
) {
869 Status
= EFI_INVALID_PARAMETER
;
871 StdOutFileName
= CommandLineWalker
+= 3;
874 if (StrStr(CommandLineWalker
, L
" > ") != NULL
) {
875 Status
= EFI_NOT_FOUND
;
879 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" < ")) != NULL
) {
880 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
881 SetMem16(CommandLineWalker
, 6, L
' ');
882 if (StdInFileName
!= NULL
) {
883 Status
= EFI_INVALID_PARAMETER
;
885 StdInFileName
= CommandLineWalker
+= 3;
887 if (StrStr(CommandLineWalker
, L
" < ") != NULL
) {
888 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 (StdInFileName
!= NULL
) {
895 Status
= EFI_INVALID_PARAMETER
;
897 StdInFileName
= CommandLineWalker
+= 4;
900 if (StrStr(CommandLineWalker
, L
" <a ") != NULL
) {
901 Status
= EFI_NOT_FOUND
;
904 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <v ")) != NULL
) {
905 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
906 SetMem16(CommandLineWalker
, 8, L
' ');
907 if (StdInVarName
!= NULL
) {
908 Status
= EFI_INVALID_PARAMETER
;
910 StdInVarName
= CommandLineWalker
+= 4;
912 if (StrStr(CommandLineWalker
, L
" <v ") != NULL
) {
913 Status
= EFI_NOT_FOUND
;
918 // re-populate the string to support any filenames that were in quotes.
920 StrCpy(CommandLineCopy
, NewCommandLine
);
922 if (FirstLocation
!= CommandLineCopy
+ StrLen(CommandLineCopy
)
923 && ((UINTN
)(FirstLocation
- CommandLineCopy
) < StrLen(NewCommandLine
))
925 *(NewCommandLine
+ (UINTN
)(FirstLocation
- CommandLineCopy
)) = CHAR_NULL
;
928 if (!EFI_ERROR(Status
)) {
930 if (StdErrFileName
!= NULL
) {
931 if ((StdErrFileName
= FixFileName(StdErrFileName
)) == NULL
) {
932 Status
= EFI_INVALID_PARAMETER
;
935 if (StdOutFileName
!= NULL
) {
936 if ((StdOutFileName
= FixFileName(StdOutFileName
)) == NULL
) {
937 Status
= EFI_INVALID_PARAMETER
;
940 if (StdInFileName
!= NULL
) {
941 if ((StdInFileName
= FixFileName(StdInFileName
)) == NULL
) {
942 Status
= EFI_INVALID_PARAMETER
;
945 if (StdErrVarName
!= NULL
) {
946 if ((StdErrVarName
= FixVarName(StdErrVarName
)) == NULL
) {
947 Status
= EFI_INVALID_PARAMETER
;
950 if (StdOutVarName
!= NULL
) {
951 if ((StdOutVarName
= FixVarName(StdOutVarName
)) == NULL
) {
952 Status
= EFI_INVALID_PARAMETER
;
955 if (StdInVarName
!= NULL
) {
956 if ((StdInVarName
= FixVarName(StdInVarName
)) == NULL
) {
957 Status
= EFI_INVALID_PARAMETER
;
962 // Verify not the same and not duplicating something from a split
966 // Check that no 2 filenames are the same
968 (StdErrFileName
!= NULL
&& StdOutFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdOutFileName
) == 0)
969 ||(StdErrFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdInFileName
) == 0)
970 ||(StdOutFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdOutFileName
, &StdInFileName
) == 0)
972 // Check that no 2 variable names are the same
974 ||(StdErrVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdInVarName
) == 0)
975 ||(StdOutVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdOutVarName
, &StdInVarName
) == 0)
976 ||(StdErrVarName
!= NULL
&& StdOutVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdOutVarName
) == 0)
978 // When a split (using | operator) is in place some are not allowed
980 ||(Split
!= NULL
&& Split
->SplitStdIn
!= NULL
&& (StdInVarName
!= NULL
|| StdInFileName
!= NULL
))
981 ||(Split
!= NULL
&& Split
->SplitStdOut
!= NULL
&& (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
))
983 // Check that nothing is trying to be output to 2 locations.
985 ||(StdErrFileName
!= NULL
&& StdErrVarName
!= NULL
)
986 ||(StdOutFileName
!= NULL
&& StdOutVarName
!= NULL
)
987 ||(StdInFileName
!= NULL
&& StdInVarName
!= NULL
)
989 // Check for no volatile environment variables
991 ||(StdErrVarName
!= NULL
&& !IsVolatileEnv(StdErrVarName
))
992 ||(StdOutVarName
!= NULL
&& !IsVolatileEnv(StdOutVarName
))
994 // Cant redirect during a reconnect operation.
996 ||(StrStr(NewCommandLine
, L
"connect -r") != NULL
997 && (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
|| StdErrFileName
!= NULL
|| StdErrVarName
!= NULL
))
999 // Check that filetypes (Unicode/Ascii) do not change during an append
1001 ||(StdOutFileName
!= NULL
&& OutUnicode
&& OutAppend
&& (!EFI_ERROR(ShellFileExists(StdOutFileName
)) && EFI_ERROR(IsUnicodeFile(StdOutFileName
))))
1002 ||(StdErrFileName
!= NULL
&& ErrUnicode
&& ErrAppend
&& (!EFI_ERROR(ShellFileExists(StdErrFileName
)) && EFI_ERROR(IsUnicodeFile(StdErrFileName
))))
1003 ||(StdOutFileName
!= NULL
&& !OutUnicode
&& OutAppend
&& (!EFI_ERROR(ShellFileExists(StdOutFileName
)) && !EFI_ERROR(IsUnicodeFile(StdOutFileName
))))
1004 ||(StdErrFileName
!= NULL
&& !ErrUnicode
&& ErrAppend
&& (!EFI_ERROR(ShellFileExists(StdErrFileName
)) && !EFI_ERROR(IsUnicodeFile(StdErrFileName
))))
1006 Status
= EFI_INVALID_PARAMETER
;
1007 ShellParameters
->StdIn
= *OldStdIn
;
1008 ShellParameters
->StdOut
= *OldStdOut
;
1009 ShellParameters
->StdErr
= *OldStdErr
;
1010 } else if (!EFI_ERROR(Status
)){
1012 // Open the Std<Whatever> and we should not have conflicts here...
1018 if (StdErrFileName
!= NULL
) {
1021 // delete existing file.
1023 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdErrFileName
);
1025 Status
= ShellOpenFileByName(StdErrFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
1026 if (!ErrAppend
&& ErrUnicode
&& !EFI_ERROR(Status
)) {
1028 // Write out the gUnicodeFileTag
1030 Size
= sizeof(CHAR16
);
1031 TagBuffer
[0] = gUnicodeFileTag
;
1032 TagBuffer
[1] = CHAR_NULL
;
1033 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
1035 if (!ErrUnicode
&& !EFI_ERROR(Status
)) {
1036 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
1037 ASSERT(TempHandle
!= NULL
);
1039 if (!EFI_ERROR(Status
)) {
1040 ShellParameters
->StdErr
= TempHandle
;
1041 gST
->StdErr
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->StandardErrorHandle
, gST
->StdErr
);
1048 if (!EFI_ERROR(Status
) && StdOutFileName
!= NULL
) {
1051 // delete existing file.
1053 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdOutFileName
);
1055 Status
= ShellOpenFileByName(StdOutFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
1056 if (TempHandle
== NULL
) {
1057 Status
= EFI_INVALID_PARAMETER
;
1059 if (StrStr(StdOutFileName
, L
"NUL")==StdOutFileName
) {
1061 } else if (!OutAppend
&& OutUnicode
&& !EFI_ERROR(Status
)) {
1063 // Write out the gUnicodeFileTag
1065 Size
= sizeof(CHAR16
);
1066 TagBuffer
[0] = gUnicodeFileTag
;
1067 TagBuffer
[1] = CHAR_NULL
;
1068 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
1069 } else if (OutAppend
) {
1071 // Move to end of file
1073 Status
= ShellInfoObject
.NewEfiShellProtocol
->GetFileSize(TempHandle
, &FileSize
);
1074 if (!EFI_ERROR(Status
)) {
1075 Status
= ShellInfoObject
.NewEfiShellProtocol
->SetFilePosition(TempHandle
, FileSize
);
1078 if (!OutUnicode
&& !EFI_ERROR(Status
)) {
1079 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
1080 ASSERT(TempHandle
!= NULL
);
1082 if (!EFI_ERROR(Status
)) {
1083 ShellParameters
->StdOut
= TempHandle
;
1084 gST
->ConOut
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->ConsoleOutHandle
, gST
->ConOut
);
1092 if (!EFI_ERROR(Status
) && StdOutVarName
!= NULL
) {
1095 // delete existing variable.
1097 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName
, 0, L
"");
1099 TempHandle
= CreateFileInterfaceEnv(StdOutVarName
);
1100 ASSERT(TempHandle
!= NULL
);
1101 ShellParameters
->StdOut
= TempHandle
;
1102 gST
->ConOut
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->ConsoleOutHandle
, gST
->ConOut
);
1108 if (!EFI_ERROR(Status
) && StdErrVarName
!= NULL
) {
1111 // delete existing variable.
1113 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName
, 0, L
"");
1115 TempHandle
= CreateFileInterfaceEnv(StdErrVarName
);
1116 ASSERT(TempHandle
!= NULL
);
1117 ShellParameters
->StdErr
= TempHandle
;
1118 gST
->StdErr
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->StandardErrorHandle
, gST
->StdErr
);
1124 if (!EFI_ERROR(Status
) && StdInVarName
!= NULL
) {
1125 TempHandle
= CreateFileInterfaceEnv(StdInVarName
);
1126 if (TempHandle
== NULL
) {
1127 Status
= EFI_OUT_OF_RESOURCES
;
1130 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
1133 if (TempHandle
== NULL
|| ((EFI_FILE_PROTOCOL
*)TempHandle
)->Read(TempHandle
, &Size
, NULL
) != EFI_BUFFER_TOO_SMALL
) {
1134 Status
= EFI_INVALID_PARAMETER
;
1136 ShellParameters
->StdIn
= TempHandle
;
1137 gST
->ConIn
= CreateSimpleTextInOnFile(TempHandle
, &gST
->ConsoleInHandle
);
1143 // StdIn from a file
1145 if (!EFI_ERROR(Status
) && StdInFileName
!= NULL
) {
1146 Status
= ShellOpenFileByName(
1151 if (!InUnicode
&& !EFI_ERROR(Status
)) {
1152 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
1154 if (!EFI_ERROR(Status
)) {
1155 ShellParameters
->StdIn
= TempHandle
;
1156 gST
->ConIn
= CreateSimpleTextInOnFile(TempHandle
, &gST
->ConsoleInHandle
);
1161 FreePool(CommandLineCopy
);
1163 CalculateEfiHdrCrc(&gST
->Hdr
);
1165 if (gST
->ConIn
== NULL
||gST
->ConOut
== NULL
) {
1166 Status
= EFI_OUT_OF_RESOURCES
;
1169 if (Status
== EFI_NOT_FOUND
) {
1170 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR
), ShellInfoObject
.HiiHandle
);
1171 } else if (EFI_ERROR(Status
)) {
1172 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SHELL_INVALID_REDIR
), ShellInfoObject
.HiiHandle
);
1179 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
1180 structure with StdIn and StdOut. The current values are de-allocated.
1182 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1183 @param[in] OldStdIn Pointer to old StdIn.
1184 @param[in] OldStdOut Pointer to old StdOut.
1185 @param[in] OldStdErr Pointer to old StdErr.
1186 @param[in] SystemTableInfo Pointer to old system table information.
1190 RestoreStdInStdOutStdErr (
1191 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1192 IN SHELL_FILE_HANDLE
*OldStdIn
,
1193 IN SHELL_FILE_HANDLE
*OldStdOut
,
1194 IN SHELL_FILE_HANDLE
*OldStdErr
,
1195 IN SYSTEM_TABLE_INFO
*SystemTableInfo
1200 if (ShellParameters
== NULL
1204 ||SystemTableInfo
== NULL
) {
1205 return (EFI_INVALID_PARAMETER
);
1207 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
1208 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
1212 if (ShellParameters
->StdIn
!= *OldStdIn
) {
1213 if ((Split
!= NULL
&& Split
->SplitStdIn
!= ShellParameters
->StdIn
) || Split
== NULL
) {
1214 gEfiShellProtocol
->CloseFile(ShellParameters
->StdIn
);
1216 ShellParameters
->StdIn
= *OldStdIn
;
1218 if (ShellParameters
->StdOut
!= *OldStdOut
) {
1219 if ((Split
!= NULL
&& Split
->SplitStdOut
!= ShellParameters
->StdOut
) || Split
== NULL
) {
1220 gEfiShellProtocol
->CloseFile(ShellParameters
->StdOut
);
1222 ShellParameters
->StdOut
= *OldStdOut
;
1224 if (ShellParameters
->StdErr
!= *OldStdErr
) {
1225 gEfiShellProtocol
->CloseFile(ShellParameters
->StdErr
);
1226 ShellParameters
->StdErr
= *OldStdErr
;
1229 if (gST
->ConIn
!= SystemTableInfo
->ConIn
) {
1230 CloseSimpleTextInOnFile(gST
->ConIn
);
1231 gST
->ConIn
= SystemTableInfo
->ConIn
;
1232 gST
->ConsoleInHandle
= SystemTableInfo
->ConInHandle
;
1234 if (gST
->ConOut
!= SystemTableInfo
->ConOut
) {
1235 CloseSimpleTextOutOnFile(gST
->ConOut
);
1236 gST
->ConOut
= SystemTableInfo
->ConOut
;
1237 gST
->ConsoleOutHandle
= SystemTableInfo
->ConOutHandle
;
1239 if (gST
->StdErr
!= SystemTableInfo
->ErrOut
) {
1240 CloseSimpleTextOutOnFile(gST
->StdErr
);
1241 gST
->StdErr
= SystemTableInfo
->ErrOut
;
1242 gST
->StandardErrorHandle
= SystemTableInfo
->ErrOutHandle
;
1245 CalculateEfiHdrCrc(&gST
->Hdr
);
1247 return (EFI_SUCCESS
);
1250 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1251 structure by parsing NewCommandLine. The current values are returned to the
1254 If OldArgv or OldArgc is NULL then that value is not returned.
1256 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1257 @param[in] NewCommandLine The new command line to parse and use.
1258 @param[out] OldArgv Pointer to old list of parameters.
1259 @param[out] OldArgc Pointer to old number of items in Argv list.
1261 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
1262 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1267 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1268 IN CONST CHAR16
*NewCommandLine
,
1269 OUT CHAR16
***OldArgv OPTIONAL
,
1270 OUT UINTN
*OldArgc OPTIONAL
1273 ASSERT(ShellParameters
!= NULL
);
1275 if (OldArgc
!= NULL
) {
1276 *OldArgc
= ShellParameters
->Argc
;
1278 if (OldArgc
!= NULL
) {
1279 *OldArgv
= ShellParameters
->Argv
;
1282 return (ParseCommandLineToArgs(NewCommandLine
, &(ShellParameters
->Argv
), &(ShellParameters
->Argc
)));
1286 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1287 structure with Argv and Argc. The current values are de-allocated and the
1288 OldArgv must not be deallocated by the caller.
1290 @param[in, out] ShellParameters pointer to parameter structure to modify
1291 @param[in] OldArgv pointer to old list of parameters
1292 @param[in] OldArgc pointer to old number of items in Argv list
1297 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1298 IN CHAR16
***OldArgv
,
1303 ASSERT(ShellParameters
!= NULL
);
1304 ASSERT(OldArgv
!= NULL
);
1305 ASSERT(OldArgc
!= NULL
);
1307 if (ShellParameters
->Argv
!= NULL
) {
1308 for ( LoopCounter
= 0
1309 ; LoopCounter
< ShellParameters
->Argc
1312 FreePool(ShellParameters
->Argv
[LoopCounter
]);
1314 FreePool(ShellParameters
->Argv
);
1316 ShellParameters
->Argv
= *OldArgv
;
1318 ShellParameters
->Argc
= *OldArgc
;