2 Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,
3 manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
5 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "ShellParametersProtocol.h"
17 #include "ConsoleWrappers.h"
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 return (EFI_OUT_OF_RESOURCES
);
199 Walker
= (CHAR16
*)CommandLine
;
200 while(Walker
!= NULL
&& *Walker
!= CHAR_NULL
) {
201 SetMem16(TempParameter
, Size
, CHAR_NULL
);
202 GetNextParameter(&Walker
, &TempParameter
);
203 NewParam
= AllocateZeroPool(StrSize(TempParameter
));
204 ASSERT(NewParam
!= NULL
);
205 StrCpy(NewParam
, TempParameter
);
206 ((CHAR16
**)(*Argv
))[(*Argc
)] = NewParam
;
209 ASSERT(Count
>= (*Argc
));
210 return (EFI_SUCCESS
);
214 creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
215 installs it on our handle and if there is an existing version of the protocol
216 that one is cached for removal later.
218 @param[in, out] NewShellParameters on a successful return, a pointer to pointer
219 to the newly installed interface.
220 @param[in, out] RootShellInstance on a successful return, pointer to boolean.
221 TRUE if this is the root shell instance.
223 @retval EFI_SUCCESS the operation completed successfully.
224 @return other the operation failed.
225 @sa ReinstallProtocolInterface
226 @sa InstallProtocolInterface
227 @sa ParseCommandLineToArgs
231 CreatePopulateInstallShellParametersProtocol (
232 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
**NewShellParameters
,
233 IN OUT BOOLEAN
*RootShellInstance
237 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
238 CHAR16
*FullCommandLine
;
242 FullCommandLine
= NULL
;
246 // Assert for valid parameters
248 ASSERT(NewShellParameters
!= NULL
);
249 ASSERT(RootShellInstance
!= NULL
);
252 // See if we have a shell parameters placed on us
254 Status
= gBS
->OpenProtocol (
256 &gEfiShellParametersProtocolGuid
,
257 (VOID
**) &ShellInfoObject
.OldShellParameters
,
260 EFI_OPEN_PROTOCOL_GET_PROTOCOL
263 // if we don't then we must be the root shell (error is expected)
265 if (EFI_ERROR (Status
)) {
266 *RootShellInstance
= TRUE
;
270 // Allocate the new structure
272 *NewShellParameters
= AllocateZeroPool(sizeof(EFI_SHELL_PARAMETERS_PROTOCOL
));
273 if ((*NewShellParameters
) == NULL
) {
274 return (EFI_OUT_OF_RESOURCES
);
278 // get loaded image protocol
280 Status
= gBS
->OpenProtocol (
282 &gEfiLoadedImageProtocolGuid
,
283 (VOID
**) &LoadedImage
,
286 EFI_OPEN_PROTOCOL_GET_PROTOCOL
288 ASSERT_EFI_ERROR(Status
);
290 // Build the full command line
292 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, &FullCommandLine
);
293 if (Status
== EFI_BUFFER_TOO_SMALL
) {
294 FullCommandLine
= AllocateZeroPool(Size
+ LoadedImage
->LoadOptionsSize
);
295 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, &FullCommandLine
);
297 if (Status
== EFI_NOT_FOUND
) {
299 // no parameters via environment... ok
302 if (EFI_ERROR(Status
)) {
306 if (Size
== 0 && LoadedImage
->LoadOptionsSize
!= 0) {
307 ASSERT(FullCommandLine
== NULL
);
309 // Now we need to include a NULL terminator in the size.
311 Size
= LoadedImage
->LoadOptionsSize
+ sizeof(FullCommandLine
[0]);
312 FullCommandLine
= AllocateZeroPool(Size
);
314 if (FullCommandLine
!= NULL
) {
315 if (LoadedImage
->LoadOptionsSize
!= 0){
316 StrCpy(FullCommandLine
, LoadedImage
->LoadOptions
);
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 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
500 structure by parsing NewCommandLine. The current values are returned to the
503 This will also update the system table.
505 @param[in, out] ShellParameters Pointer to parameter structure to modify.
506 @param[in] NewCommandLine The new command line to parse and use.
507 @param[out] OldStdIn Pointer to old StdIn.
508 @param[out] OldStdOut Pointer to old StdOut.
509 @param[out] OldStdErr Pointer to old StdErr.
510 @param[out] SystemTableInfo Pointer to old system table information.
512 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
513 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
517 UpdateStdInStdOutStdErr(
518 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
519 IN CHAR16
*NewCommandLine
,
520 OUT SHELL_FILE_HANDLE
*OldStdIn
,
521 OUT SHELL_FILE_HANDLE
*OldStdOut
,
522 OUT SHELL_FILE_HANDLE
*OldStdErr
,
523 OUT SYSTEM_TABLE_INFO
*SystemTableInfo
526 CHAR16
*CommandLineCopy
;
527 CHAR16
*CommandLineWalker
;
528 CHAR16
*StdErrFileName
;
529 CHAR16
*StdOutFileName
;
530 CHAR16
*StdInFileName
;
531 CHAR16
*StdInVarName
;
532 CHAR16
*StdOutVarName
;
533 CHAR16
*StdErrVarName
;
535 SHELL_FILE_HANDLE TempHandle
;
545 CHAR16
*FirstLocation
;
551 StdOutVarName
= NULL
;
552 StdErrVarName
= NULL
;
553 StdErrFileName
= NULL
;
554 StdInFileName
= NULL
;
555 StdOutFileName
= NULL
;
558 CommandLineCopy
= NULL
;
559 FirstLocation
= NULL
;
561 if (ShellParameters
== NULL
|| SystemTableInfo
== NULL
|| OldStdIn
== NULL
|| OldStdOut
== NULL
|| OldStdErr
== NULL
) {
562 return (EFI_INVALID_PARAMETER
);
565 SystemTableInfo
->ConIn
= gST
->ConIn
;
566 SystemTableInfo
->ConInHandle
= gST
->ConsoleInHandle
;
567 SystemTableInfo
->ConOut
= gST
->ConOut
;
568 SystemTableInfo
->ConOutHandle
= gST
->ConsoleOutHandle
;
569 SystemTableInfo
->ConErr
= gST
->StdErr
;
570 SystemTableInfo
->ConErrHandle
= gST
->StandardErrorHandle
;
571 *OldStdIn
= ShellParameters
->StdIn
;
572 *OldStdOut
= ShellParameters
->StdOut
;
573 *OldStdErr
= ShellParameters
->StdErr
;
575 if (NewCommandLine
== NULL
) {
576 return (EFI_SUCCESS
);
579 CommandLineCopy
= StrnCatGrow(&CommandLineCopy
, NULL
, NewCommandLine
, 0);
580 Status
= EFI_SUCCESS
;
582 FirstLocation
= CommandLineCopy
+ StrLen(CommandLineCopy
);
584 StripQuotes(CommandLineCopy
);
586 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
587 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
588 if (Split
!= NULL
&& Split
->SplitStdIn
!= NULL
) {
589 ShellParameters
->StdIn
= Split
->SplitStdIn
;
591 if (Split
!= NULL
&& Split
->SplitStdOut
!= NULL
) {
592 ShellParameters
->StdOut
= Split
->SplitStdOut
;
596 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>>v ")) != NULL
) {
597 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
598 SetMem16(CommandLineWalker
, 12, L
' ');
599 StdErrVarName
= CommandLineWalker
+= 6;
601 if (StrStr(CommandLineWalker
, L
" 2>>v ") != NULL
) {
602 Status
= EFI_NOT_FOUND
;
605 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>v ")) != NULL
) {
606 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
607 SetMem16(CommandLineWalker
, 12, L
' ');
608 StdOutVarName
= CommandLineWalker
+= 6;
610 if (StrStr(CommandLineWalker
, L
" 1>>v ") != NULL
) {
611 Status
= EFI_NOT_FOUND
;
613 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>v ")) != NULL
) {
614 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
615 SetMem16(CommandLineWalker
, 10, L
' ');
616 StdOutVarName
= CommandLineWalker
+= 5;
618 if (StrStr(CommandLineWalker
, L
" >>v ") != NULL
) {
619 Status
= EFI_NOT_FOUND
;
621 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >v ")) != NULL
) {
622 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
623 SetMem16(CommandLineWalker
, 8, L
' ');
624 StdOutVarName
= CommandLineWalker
+= 4;
626 if (StrStr(CommandLineWalker
, L
" >v ") != NULL
) {
627 Status
= EFI_NOT_FOUND
;
630 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>a ")) != NULL
) {
631 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
632 SetMem16(CommandLineWalker
, 12, L
' ');
633 StdOutFileName
= CommandLineWalker
+= 6;
636 if (StrStr(CommandLineWalker
, L
" 1>>a ") != NULL
) {
637 Status
= EFI_NOT_FOUND
;
640 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>> ")) != NULL
) {
641 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
642 SetMem16(CommandLineWalker
, 10, L
' ');
643 if (StdOutFileName
!= NULL
) {
644 Status
= EFI_INVALID_PARAMETER
;
646 StdOutFileName
= CommandLineWalker
+= 5;
649 if (StrStr(CommandLineWalker
, L
" 1>> ") != NULL
) {
650 Status
= EFI_NOT_FOUND
;
653 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >> ")) != NULL
) {
654 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
655 SetMem16(CommandLineWalker
, 8, L
' ');
656 if (StdOutFileName
!= NULL
) {
657 Status
= EFI_INVALID_PARAMETER
;
659 StdOutFileName
= CommandLineWalker
+= 4;
662 if (StrStr(CommandLineWalker
, L
" >> ") != NULL
) {
663 Status
= EFI_NOT_FOUND
;
666 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>a ")) != NULL
) {
667 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
668 SetMem16(CommandLineWalker
, 10, L
' ');
669 if (StdOutFileName
!= NULL
) {
670 Status
= EFI_INVALID_PARAMETER
;
672 StdOutFileName
= CommandLineWalker
+= 5;
676 if (StrStr(CommandLineWalker
, L
" >>a ") != NULL
) {
677 Status
= EFI_NOT_FOUND
;
680 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>a ")) != NULL
) {
681 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
682 SetMem16(CommandLineWalker
, 10, L
' ');
683 if (StdOutFileName
!= NULL
) {
684 Status
= EFI_INVALID_PARAMETER
;
686 StdOutFileName
= CommandLineWalker
+= 5;
690 if (StrStr(CommandLineWalker
, L
" 1>a ") != NULL
) {
691 Status
= EFI_NOT_FOUND
;
694 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >a ")) != NULL
) {
695 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
696 SetMem16(CommandLineWalker
, 8, L
' ');
697 if (StdOutFileName
!= NULL
) {
698 Status
= EFI_INVALID_PARAMETER
;
700 StdOutFileName
= CommandLineWalker
+= 4;
704 if (StrStr(CommandLineWalker
, L
" >a ") != NULL
) {
705 Status
= EFI_NOT_FOUND
;
708 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>> ")) != NULL
) {
709 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
710 SetMem16(CommandLineWalker
, 10, L
' ');
711 if (StdErrFileName
!= NULL
) {
712 Status
= EFI_INVALID_PARAMETER
;
714 StdErrFileName
= CommandLineWalker
+= 5;
717 if (StrStr(CommandLineWalker
, L
" 2>> ") != NULL
) {
718 Status
= EFI_NOT_FOUND
;
722 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>v ")) != NULL
) {
723 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
724 SetMem16(CommandLineWalker
, 10, L
' ');
725 if (StdErrVarName
!= NULL
) {
726 Status
= EFI_INVALID_PARAMETER
;
728 StdErrVarName
= CommandLineWalker
+= 5;
731 if (StrStr(CommandLineWalker
, L
" 2>v ") != NULL
) {
732 Status
= EFI_NOT_FOUND
;
735 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>v ")) != NULL
) {
736 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
737 SetMem16(CommandLineWalker
, 10, L
' ');
738 if (StdOutVarName
!= NULL
) {
739 Status
= EFI_INVALID_PARAMETER
;
741 StdOutVarName
= CommandLineWalker
+= 5;
744 if (StrStr(CommandLineWalker
, L
" 1>v ") != NULL
) {
745 Status
= EFI_NOT_FOUND
;
748 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>a ")) != NULL
) {
749 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
750 SetMem16(CommandLineWalker
, 10, L
' ');
751 if (StdErrFileName
!= NULL
) {
752 Status
= EFI_INVALID_PARAMETER
;
754 StdErrFileName
= CommandLineWalker
+= 5;
758 if (StrStr(CommandLineWalker
, L
" 2>a ") != NULL
) {
759 Status
= EFI_NOT_FOUND
;
762 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2> ")) != NULL
) {
763 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
764 SetMem16(CommandLineWalker
, 8, L
' ');
765 if (StdErrFileName
!= NULL
) {
766 Status
= EFI_INVALID_PARAMETER
;
768 StdErrFileName
= CommandLineWalker
+= 4;
771 if (StrStr(CommandLineWalker
, L
" 2> ") != NULL
) {
772 Status
= EFI_NOT_FOUND
;
776 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1> ")) != NULL
) {
777 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
778 SetMem16(CommandLineWalker
, 8, L
' ');
779 if (StdOutFileName
!= NULL
) {
780 Status
= EFI_INVALID_PARAMETER
;
782 StdOutFileName
= CommandLineWalker
+= 4;
785 if (StrStr(CommandLineWalker
, L
" 1> ") != NULL
) {
786 Status
= EFI_NOT_FOUND
;
790 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" > ")) != NULL
) {
791 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
792 SetMem16(CommandLineWalker
, 6, L
' ');
793 if (StdOutFileName
!= NULL
) {
794 Status
= EFI_INVALID_PARAMETER
;
796 StdOutFileName
= CommandLineWalker
+= 3;
799 if (StrStr(CommandLineWalker
, L
" > ") != NULL
) {
800 Status
= EFI_NOT_FOUND
;
804 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" < ")) != NULL
) {
805 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
806 SetMem16(CommandLineWalker
, 6, L
' ');
807 if (StdInFileName
!= NULL
) {
808 Status
= EFI_INVALID_PARAMETER
;
810 StdInFileName
= CommandLineWalker
+= 3;
812 if (StrStr(CommandLineWalker
, L
" < ") != NULL
) {
813 Status
= EFI_NOT_FOUND
;
816 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <a ")) != NULL
) {
817 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
818 SetMem16(CommandLineWalker
, 8, L
' ');
819 if (StdInFileName
!= NULL
) {
820 Status
= EFI_INVALID_PARAMETER
;
822 StdInFileName
= CommandLineWalker
+= 4;
825 if (StrStr(CommandLineWalker
, L
" <a ") != NULL
) {
826 Status
= EFI_NOT_FOUND
;
829 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <v ")) != NULL
) {
830 FirstLocation
= MIN(CommandLineWalker
, FirstLocation
);
831 SetMem16(CommandLineWalker
, 8, L
' ');
832 if (StdInVarName
!= NULL
) {
833 Status
= EFI_INVALID_PARAMETER
;
835 StdInVarName
= CommandLineWalker
+= 4;
837 if (StrStr(CommandLineWalker
, L
" <v ") != NULL
) {
838 Status
= EFI_NOT_FOUND
;
842 if (FirstLocation
!= CommandLineCopy
+ StrLen(CommandLineCopy
)
843 && ((UINTN
)(FirstLocation
- CommandLineCopy
) < StrLen(NewCommandLine
))
845 *(NewCommandLine
+ (UINTN
)(FirstLocation
- CommandLineCopy
)) = CHAR_NULL
;
848 if (!EFI_ERROR(Status
)) {
849 if (StdErrFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrFileName
, L
" ")) != NULL
) {
850 CommandLineWalker
[0] = CHAR_NULL
;
852 if (StdOutFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutFileName
, L
" ")) != NULL
) {
853 CommandLineWalker
[0] = CHAR_NULL
;
855 if (StdInFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdInFileName
, L
" ")) != NULL
) {
856 CommandLineWalker
[0] = CHAR_NULL
;
858 if (StdErrVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrVarName
, L
" ")) != NULL
) {
859 CommandLineWalker
[0] = CHAR_NULL
;
861 if (StdOutVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutVarName
, L
" ")) != NULL
) {
862 CommandLineWalker
[0] = CHAR_NULL
;
864 if (StdInVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdInVarName
, L
" ")) != NULL
) {
865 CommandLineWalker
[0] = CHAR_NULL
;
869 // Verify not the same and not duplicating something from a split
873 // Check that no 2 filenames are the same
875 (StdErrFileName
!= NULL
&& StdOutFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdOutFileName
) == 0)
876 ||(StdErrFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdInFileName
) == 0)
877 ||(StdOutFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdOutFileName
, &StdInFileName
) == 0)
879 // Check that no 2 variable names are the same
881 ||(StdErrVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdInVarName
) == 0)
882 ||(StdOutVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdOutVarName
, &StdInVarName
) == 0)
883 ||(StdErrVarName
!= NULL
&& StdOutVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdOutVarName
) == 0)
885 // When a split (using | operator) is in place some are not allowed
887 ||(Split
!= NULL
&& Split
->SplitStdIn
!= NULL
&& (StdInVarName
!= NULL
|| StdInFileName
!= NULL
))
888 ||(Split
!= NULL
&& Split
->SplitStdOut
!= NULL
&& (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
))
890 // Check that nothing is trying to be output to 2 locations.
892 ||(StdErrFileName
!= NULL
&& StdErrVarName
!= NULL
)
893 ||(StdOutFileName
!= NULL
&& StdOutVarName
!= NULL
)
894 ||(StdInFileName
!= NULL
&& StdInVarName
!= NULL
)
896 // Check for no volatile environment variables
898 ||(StdErrVarName
!= NULL
&& !IsVolatileEnv(StdErrVarName
))
899 ||(StdOutVarName
!= NULL
&& !IsVolatileEnv(StdOutVarName
))
901 // Cant redirect during a reconnect operation.
903 ||(StrStr(NewCommandLine
, L
"connect -r") != NULL
904 && (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
|| StdErrFileName
!= NULL
|| StdErrVarName
!= NULL
))
906 // Check that filetypes (Unicode/Ascii) do not change during an append
908 ||(StdOutFileName
!= NULL
&& OutUnicode
&& OutAppend
&& (!EFI_ERROR(ShellFileExists(StdOutFileName
)) && EFI_ERROR(IsUnicodeFile(StdOutFileName
))))
909 ||(StdErrFileName
!= NULL
&& ErrUnicode
&& ErrAppend
&& (!EFI_ERROR(ShellFileExists(StdErrFileName
)) && EFI_ERROR(IsUnicodeFile(StdErrFileName
))))
910 ||(StdOutFileName
!= NULL
&& !OutUnicode
&& OutAppend
&& (!EFI_ERROR(ShellFileExists(StdOutFileName
)) && !EFI_ERROR(IsUnicodeFile(StdOutFileName
))))
911 ||(StdErrFileName
!= NULL
&& !ErrUnicode
&& ErrAppend
&& (!EFI_ERROR(ShellFileExists(StdErrFileName
)) && !EFI_ERROR(IsUnicodeFile(StdErrFileName
))))
913 Status
= EFI_INVALID_PARAMETER
;
914 ShellParameters
->StdIn
= *OldStdIn
;
915 ShellParameters
->StdOut
= *OldStdOut
;
916 ShellParameters
->StdErr
= *OldStdErr
;
917 } else if (!EFI_ERROR(Status
)){
919 // Open the Std<Whatever> and we should not have conflicts here...
925 if (StdErrFileName
!= NULL
) {
928 // delete existing file.
930 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdErrFileName
);
932 Status
= ShellOpenFileByName(StdErrFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
933 if (!ErrAppend
&& ErrUnicode
&& !EFI_ERROR(Status
)) {
935 // Write out the gUnicodeFileTag
937 Size
= sizeof(CHAR16
);
938 TagBuffer
[0] = gUnicodeFileTag
;
939 TagBuffer
[1] = CHAR_NULL
;
940 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
942 if (!ErrUnicode
&& !EFI_ERROR(Status
)) {
943 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
944 ASSERT(TempHandle
!= NULL
);
946 if (!EFI_ERROR(Status
)) {
947 ShellParameters
->StdErr
= TempHandle
;
948 gST
->StdErr
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->StandardErrorHandle
);
955 if (!EFI_ERROR(Status
) && StdOutFileName
!= NULL
) {
958 // delete existing file.
960 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdOutFileName
);
962 Status
= ShellOpenFileByName(StdOutFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
963 if (TempHandle
== NULL
) {
964 Status
= EFI_INVALID_PARAMETER
;
966 if (StrStr(StdOutFileName
, L
"NUL")==StdOutFileName
) {
968 } else if (!OutAppend
&& OutUnicode
&& !EFI_ERROR(Status
)) {
970 // Write out the gUnicodeFileTag
972 Size
= sizeof(CHAR16
);
973 TagBuffer
[0] = gUnicodeFileTag
;
974 TagBuffer
[1] = CHAR_NULL
;
975 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
976 } else if (OutAppend
) {
978 // Move to end of file
980 Status
= ShellInfoObject
.NewEfiShellProtocol
->GetFileSize(TempHandle
, &FileSize
);
981 if (!EFI_ERROR(Status
)) {
982 Status
= ShellInfoObject
.NewEfiShellProtocol
->SetFilePosition(TempHandle
, FileSize
);
985 if (!OutUnicode
&& !EFI_ERROR(Status
)) {
986 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
987 ASSERT(TempHandle
!= NULL
);
989 if (!EFI_ERROR(Status
)) {
990 ShellParameters
->StdOut
= TempHandle
;
991 gST
->ConOut
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->ConsoleOutHandle
);
999 if (!EFI_ERROR(Status
) && StdOutVarName
!= NULL
) {
1002 // delete existing variable.
1004 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName
, 0, L
"");
1006 TempHandle
= CreateFileInterfaceEnv(StdOutVarName
);
1007 ASSERT(TempHandle
!= NULL
);
1008 ShellParameters
->StdOut
= TempHandle
;
1009 gST
->ConOut
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->ConsoleOutHandle
);
1015 if (!EFI_ERROR(Status
) && StdErrVarName
!= NULL
) {
1018 // delete existing variable.
1020 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName
, 0, L
"");
1022 TempHandle
= CreateFileInterfaceEnv(StdErrVarName
);
1023 ASSERT(TempHandle
!= NULL
);
1024 ShellParameters
->StdErr
= TempHandle
;
1025 gST
->StdErr
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->StandardErrorHandle
);
1031 if (!EFI_ERROR(Status
) && StdInVarName
!= NULL
) {
1032 TempHandle
= CreateFileInterfaceEnv(StdInVarName
);
1034 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
1037 ASSERT(TempHandle
!= NULL
);
1038 if (((EFI_FILE_PROTOCOL
*)TempHandle
)->Read(TempHandle
, &Size
, NULL
) != EFI_BUFFER_TOO_SMALL
) {
1039 Status
= EFI_INVALID_PARAMETER
;
1041 ShellParameters
->StdIn
= TempHandle
;
1042 gST
->ConIn
= CreateSimpleTextInOnFile(TempHandle
, &gST
->ConsoleInHandle
);
1047 // StdIn from a file
1049 if (!EFI_ERROR(Status
) && StdInFileName
!= NULL
) {
1050 Status
= ShellOpenFileByName(
1055 if (!InUnicode
&& !EFI_ERROR(Status
)) {
1056 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
1058 if (!EFI_ERROR(Status
)) {
1059 ShellParameters
->StdIn
= TempHandle
;
1060 gST
->ConIn
= CreateSimpleTextInOnFile(TempHandle
, &gST
->ConsoleInHandle
);
1065 FreePool(CommandLineCopy
);
1067 CalculateEfiHdrCrc(&gST
->Hdr
);
1069 if (gST
->ConIn
== NULL
||gST
->ConOut
== NULL
) {
1070 return (EFI_OUT_OF_RESOURCES
);
1076 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
1077 structure with StdIn and StdOut. The current values are de-allocated.
1079 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1080 @param[in] OldStdIn Pointer to old StdIn.
1081 @param[in] OldStdOut Pointer to old StdOut.
1082 @param[in] OldStdErr Pointer to old StdErr.
1083 @param[in] SystemTableInfo Pointer to old system table information.
1087 RestoreStdInStdOutStdErr (
1088 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1089 IN SHELL_FILE_HANDLE
*OldStdIn
,
1090 IN SHELL_FILE_HANDLE
*OldStdOut
,
1091 IN SHELL_FILE_HANDLE
*OldStdErr
,
1092 IN SYSTEM_TABLE_INFO
*SystemTableInfo
1097 if (ShellParameters
== NULL
1101 ||SystemTableInfo
== NULL
) {
1102 return (EFI_INVALID_PARAMETER
);
1104 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
1105 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
1109 if (ShellParameters
->StdIn
!= *OldStdIn
) {
1110 if ((Split
!= NULL
&& Split
->SplitStdIn
!= ShellParameters
->StdIn
) || Split
== NULL
) {
1111 gEfiShellProtocol
->CloseFile(ShellParameters
->StdIn
);
1113 ShellParameters
->StdIn
= *OldStdIn
;
1115 if (ShellParameters
->StdOut
!= *OldStdOut
) {
1116 if ((Split
!= NULL
&& Split
->SplitStdOut
!= ShellParameters
->StdOut
) || Split
== NULL
) {
1117 gEfiShellProtocol
->CloseFile(ShellParameters
->StdOut
);
1119 ShellParameters
->StdOut
= *OldStdOut
;
1121 if (ShellParameters
->StdErr
!= *OldStdErr
) {
1122 gEfiShellProtocol
->CloseFile(ShellParameters
->StdErr
);
1123 ShellParameters
->StdErr
= *OldStdErr
;
1126 if (gST
->ConIn
!= SystemTableInfo
->ConIn
) {
1127 CloseSimpleTextInOnFile(gST
->ConIn
);
1128 gST
->ConIn
= SystemTableInfo
->ConIn
;
1129 gST
->ConsoleInHandle
= SystemTableInfo
->ConInHandle
;
1131 if (gST
->ConOut
!= SystemTableInfo
->ConOut
) {
1132 CloseSimpleTextOutOnFile(gST
->ConOut
);
1133 gST
->ConOut
= SystemTableInfo
->ConOut
;
1134 gST
->ConsoleOutHandle
= SystemTableInfo
->ConOutHandle
;
1136 if (gST
->StdErr
!= SystemTableInfo
->ConErr
) {
1137 CloseSimpleTextOutOnFile(gST
->StdErr
);
1138 gST
->StdErr
= SystemTableInfo
->ConErr
;
1139 gST
->StandardErrorHandle
= SystemTableInfo
->ConErrHandle
;
1142 CalculateEfiHdrCrc(&gST
->Hdr
);
1144 return (EFI_SUCCESS
);
1147 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1148 structure by parsing NewCommandLine. The current values are returned to the
1151 If OldArgv or OldArgc is NULL then that value is not returned.
1153 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1154 @param[in] NewCommandLine The new command line to parse and use.
1155 @param[out] OldArgv Pointer to old list of parameters.
1156 @param[out] OldArgc Pointer to old number of items in Argv list.
1158 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
1159 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1164 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1165 IN CONST CHAR16
*NewCommandLine
,
1166 OUT CHAR16
***OldArgv OPTIONAL
,
1167 OUT UINTN
*OldArgc OPTIONAL
1170 ASSERT(ShellParameters
!= NULL
);
1172 if (OldArgc
!= NULL
) {
1173 *OldArgc
= ShellParameters
->Argc
;
1175 if (OldArgc
!= NULL
) {
1176 *OldArgv
= ShellParameters
->Argv
;
1179 return (ParseCommandLineToArgs(NewCommandLine
, &(ShellParameters
->Argv
), &(ShellParameters
->Argc
)));
1183 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1184 structure with Argv and Argc. The current values are de-allocated and the
1185 OldArgv must not be deallocated by the caller.
1187 @param[in, out] ShellParameters pointer to parameter structure to modify
1188 @param[in] OldArgv pointer to old list of parameters
1189 @param[in] OldArgc pointer to old number of items in Argv list
1194 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1195 IN CHAR16
***OldArgv
,
1200 ASSERT(ShellParameters
!= NULL
);
1201 ASSERT(OldArgv
!= NULL
);
1202 ASSERT(OldArgc
!= NULL
);
1204 if (ShellParameters
->Argv
!= NULL
) {
1205 for ( LoopCounter
= 0
1206 ; LoopCounter
< ShellParameters
->Argc
1209 FreePool(ShellParameters
->Argv
[LoopCounter
]);
1211 FreePool(ShellParameters
->Argv
);
1213 ShellParameters
->Argv
= *OldArgv
;
1215 ShellParameters
->Argc
= *OldArgc
;