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
'^' && *(TempLoc
+1) == L
'\"') {
76 } else if (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'|') {
78 } else if (*TempLoc
== L
'^') {
80 } else if (*TempLoc
== L
'\"') {
86 if (NextDelim
- ((*Walker
)+1) == 0) {
90 StrCpy(*TempParameter
, L
"");
91 *Walker
= NextDelim
+ 1;
92 } else if (NextDelim
!= NULL
) {
93 StrnCpy(*TempParameter
, (*Walker
)+1, NextDelim
- ((*Walker
)+1));
94 *Walker
= NextDelim
+ 1;
97 // last one... someone forgot the training quote!
99 StrCpy(*TempParameter
, *Walker
);
102 for (TempLoc
= *TempParameter
; TempLoc
!= NULL
&& *TempLoc
!= CHAR_NULL
; TempLoc
++) {
103 if ((*TempLoc
== L
'^' && *(TempLoc
+1) == L
'^')
104 || (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'|')
105 || (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'\"')
107 CopyMem(TempLoc
, TempLoc
+1, StrSize(TempLoc
) - sizeof(TempLoc
[0]));
112 // we have a regular parameter (no quote) OR
113 // we have the final parameter (no trailing space)
115 NextDelim
= StrStr((*Walker
), L
" ");
116 if (NextDelim
!= NULL
) {
117 StrnCpy(*TempParameter
, *Walker
, NextDelim
- (*Walker
));
118 (*TempParameter
)[NextDelim
- (*Walker
)] = CHAR_NULL
;
119 *Walker
= NextDelim
+1;
124 StrCpy(*TempParameter
, *Walker
);
127 for (NextDelim
= *TempParameter
; NextDelim
!= NULL
&& *NextDelim
!= CHAR_NULL
; NextDelim
++) {
128 if (*NextDelim
== L
'^' && *(NextDelim
+1) == L
'^') {
129 CopyMem(NextDelim
, NextDelim
+1, StrSize(NextDelim
) - sizeof(NextDelim
[0]));
130 }/* else if (*NextDelim == L'^') {
134 while ((*TempParameter
)[StrLen(*TempParameter
)-1] == L
' ') {
135 (*TempParameter
)[StrLen(*TempParameter
)-1] = CHAR_NULL
;
137 while ((*TempParameter
)[0] == L
' ') {
138 CopyMem(*TempParameter
, (*TempParameter
)+1, StrSize(*TempParameter
) - sizeof((*TempParameter
)[0]));
145 Function to populate Argc and Argv.
147 This function parses the CommandLine and divides it into standard C style Argc/Argv
148 parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space
149 delimited and quote surrounded parameter definition.
151 @param[in] CommandLine String of command line to parse
152 @param[in,out] Argv pointer to array of strings; one for each parameter
153 @param[in,out] Argc pointer to number of strings in Argv array
155 @return EFI_SUCCESS the operation was sucessful
156 @return EFI_OUT_OF_RESOURCES a memory allocation failed.
160 ParseCommandLineToArgs(
161 IN CONST CHAR16
*CommandLine
,
162 IN OUT CHAR16
***Argv
,
167 CHAR16
*TempParameter
;
172 ASSERT(Argc
!= NULL
);
173 ASSERT(Argv
!= NULL
);
175 if (CommandLine
== NULL
|| StrLen(CommandLine
)==0) {
178 return (EFI_SUCCESS
);
181 Size
= StrSize(CommandLine
);
182 TempParameter
= AllocateZeroPool(Size
);
183 if (TempParameter
== NULL
) {
184 return (EFI_OUT_OF_RESOURCES
);
188 , Walker
= (CHAR16
*)CommandLine
189 ; Walker
!= NULL
&& *Walker
!= CHAR_NULL
190 ; GetNextParameter(&Walker
, &TempParameter
)
195 Walker = (CHAR16*)CommandLine;
196 while(Walker != NULL) {
197 GetNextParameter(&Walker, &TempParameter);
202 // lets allocate the pointer array
204 (*Argv
) = AllocateZeroPool((Count
)*sizeof(CHAR16
*));
206 return (EFI_OUT_OF_RESOURCES
);
210 Walker
= (CHAR16
*)CommandLine
;
211 while(Walker
!= NULL
&& *Walker
!= CHAR_NULL
) {
212 SetMem16(TempParameter
, Size
, CHAR_NULL
);
213 GetNextParameter(&Walker
, &TempParameter
);
214 NewParam
= AllocateZeroPool(StrSize(TempParameter
));
215 ASSERT(NewParam
!= NULL
);
216 StrCpy(NewParam
, TempParameter
);
217 ((CHAR16
**)(*Argv
))[(*Argc
)] = NewParam
;
220 ASSERT(Count
>= (*Argc
));
221 return (EFI_SUCCESS
);
225 creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
226 installs it on our handle and if there is an existing version of the protocol
227 that one is cached for removal later.
229 @param[in,out] NewShellParameters on a successful return, a pointer to pointer
230 to the newly installed interface.
231 @param[in,out] RootShellInstance on a successful return, pointer to boolean.
232 TRUE if this is the root shell instance.
234 @retval EFI_SUCCESS the operation completed successfully.
235 @return other the operation failed.
236 @sa ReinstallProtocolInterface
237 @sa InstallProtocolInterface
238 @sa ParseCommandLineToArgs
242 CreatePopulateInstallShellParametersProtocol (
243 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
**NewShellParameters
,
244 IN OUT BOOLEAN
*RootShellInstance
248 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
249 CHAR16
*FullCommandLine
;
253 FullCommandLine
= NULL
;
257 // Assert for valid parameters
259 ASSERT(NewShellParameters
!= NULL
);
260 ASSERT(RootShellInstance
!= NULL
);
263 // See if we have a shell parameters placed on us
265 Status
= gBS
->OpenProtocol (
267 &gEfiShellParametersProtocolGuid
,
268 (VOID
**) &ShellInfoObject
.OldShellParameters
,
271 EFI_OPEN_PROTOCOL_GET_PROTOCOL
274 // if we don't then we must be the root shell (error is expected)
276 if (EFI_ERROR (Status
)) {
277 *RootShellInstance
= TRUE
;
281 // Allocate the new structure
283 *NewShellParameters
= AllocateZeroPool(sizeof(EFI_SHELL_PARAMETERS_PROTOCOL
));
284 if ((*NewShellParameters
) == NULL
) {
285 return (EFI_OUT_OF_RESOURCES
);
289 // get loaded image protocol
291 Status
= gBS
->OpenProtocol (
293 &gEfiLoadedImageProtocolGuid
,
294 (VOID
**) &LoadedImage
,
297 EFI_OPEN_PROTOCOL_GET_PROTOCOL
299 ASSERT_EFI_ERROR(Status
);
301 // Build the full command line
303 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, &FullCommandLine
);
304 if (Status
== EFI_BUFFER_TOO_SMALL
) {
305 FullCommandLine
= AllocateZeroPool(Size
+ LoadedImage
->LoadOptionsSize
);
306 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, &FullCommandLine
);
308 if (Status
== EFI_NOT_FOUND
) {
310 // no parameters via environment... ok
313 if (EFI_ERROR(Status
)) {
317 if (Size
== 0 && LoadedImage
->LoadOptionsSize
!= 0) {
318 ASSERT(FullCommandLine
== NULL
);
320 // Now we need to include a NULL terminator in the size.
322 Size
= LoadedImage
->LoadOptionsSize
+ sizeof(FullCommandLine
[0]);
323 FullCommandLine
= AllocateZeroPool(Size
);
325 if (FullCommandLine
!= NULL
) {
326 if (LoadedImage
->LoadOptionsSize
!= 0){
327 StrCpy(FullCommandLine
, LoadedImage
->LoadOptions
);
330 // Populate Argc and Argv
332 Status
= ParseCommandLineToArgs(FullCommandLine
,
333 &(*NewShellParameters
)->Argv
,
334 &(*NewShellParameters
)->Argc
);
336 FreePool(FullCommandLine
);
338 ASSERT_EFI_ERROR(Status
);
340 (*NewShellParameters
)->Argv
= NULL
;
341 (*NewShellParameters
)->Argc
= 0;
345 // Populate the 3 faked file systems...
347 if (*RootShellInstance
) {
348 (*NewShellParameters
)->StdIn
= &FileInterfaceStdIn
;
349 (*NewShellParameters
)->StdOut
= &FileInterfaceStdOut
;
350 (*NewShellParameters
)->StdErr
= &FileInterfaceStdErr
;
351 Status
= gBS
->InstallProtocolInterface(&gImageHandle
,
352 &gEfiShellParametersProtocolGuid
,
353 EFI_NATIVE_INTERFACE
,
354 (VOID
*)(*NewShellParameters
));
357 // copy from the existing ones
359 (*NewShellParameters
)->StdIn
= ShellInfoObject
.OldShellParameters
->StdIn
;
360 (*NewShellParameters
)->StdOut
= ShellInfoObject
.OldShellParameters
->StdOut
;
361 (*NewShellParameters
)->StdErr
= ShellInfoObject
.OldShellParameters
->StdErr
;
362 Status
= gBS
->ReinstallProtocolInterface(gImageHandle
,
363 &gEfiShellParametersProtocolGuid
,
364 (VOID
*)ShellInfoObject
.OldShellParameters
,
365 (VOID
*)(*NewShellParameters
));
372 frees all memory used by createion and installation of shell parameters protocol
373 and if there was an old version installed it will restore that one.
375 @param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
378 @retval EFI_SUCCESS the cleanup was successful
379 @return other the cleanup failed
380 @sa ReinstallProtocolInterface
381 @sa UninstallProtocolInterface
385 CleanUpShellParametersProtocol (
386 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*NewShellParameters
393 // If the old exists we need to restore it
395 if (ShellInfoObject
.OldShellParameters
!= NULL
) {
396 Status
= gBS
->ReinstallProtocolInterface(gImageHandle
,
397 &gEfiShellParametersProtocolGuid
,
398 (VOID
*)NewShellParameters
,
399 (VOID
*)ShellInfoObject
.OldShellParameters
);
400 DEBUG_CODE(ShellInfoObject
.OldShellParameters
= NULL
;);
403 // No old one, just uninstall us...
405 Status
= gBS
->UninstallProtocolInterface(gImageHandle
,
406 &gEfiShellParametersProtocolGuid
,
407 (VOID
*)NewShellParameters
);
409 if (NewShellParameters
->Argv
!= NULL
) {
410 for ( LoopCounter
= 0
411 ; LoopCounter
< NewShellParameters
->Argc
414 FreePool(NewShellParameters
->Argv
[LoopCounter
]);
416 FreePool(NewShellParameters
->Argv
);
418 FreePool(NewShellParameters
);
425 IN CONST CHAR16
*FileName
428 SHELL_FILE_HANDLE Handle
;
430 UINT64 OriginalFilePosition
;
434 Status
= gEfiShellProtocol
->OpenFileByName(FileName
, &Handle
, EFI_FILE_MODE_READ
);
435 if (EFI_ERROR(Status
)) {
438 gEfiShellProtocol
->GetFilePosition(Handle
, &OriginalFilePosition
);
439 gEfiShellProtocol
->SetFilePosition(Handle
, 0);
440 CharSize
= sizeof(CHAR16
);
441 Status
= gEfiShellProtocol
->ReadFile(Handle
, &CharSize
, &CharBuffer
);
442 if (EFI_ERROR(Status
) || CharBuffer
!= gUnicodeFileTag
) {
443 Status
= EFI_BUFFER_TOO_SMALL
;
445 gEfiShellProtocol
->SetFilePosition(Handle
, OriginalFilePosition
);
446 gEfiShellProtocol
->CloseFile(Handle
);
451 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
452 structure by parsing NewCommandLine. The current values are returned to the
455 This will also update the system table.
457 @param[in,out] ShellParameters Pointer to parameter structure to modify.
458 @param[in] NewCommandLine The new command line to parse and use.
459 @param[out] OldStdIn Pointer to old StdIn.
460 @param[out] OldStdOut Pointer to old StdOut.
461 @param[out] OldStdErr Pointer to old StdErr.
462 @param[out] SystemTableInfo Pointer to old system table information.
464 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
465 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
469 UpdateStdInStdOutStdErr(
470 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
471 IN CONST CHAR16
*NewCommandLine
,
472 OUT SHELL_FILE_HANDLE
*OldStdIn
,
473 OUT SHELL_FILE_HANDLE
*OldStdOut
,
474 OUT SHELL_FILE_HANDLE
*OldStdErr
,
475 OUT SYSTEM_TABLE_INFO
*SystemTableInfo
478 CHAR16
*CommandLineCopy
;
479 CHAR16
*CommandLineWalker
;
480 CHAR16
*StdErrFileName
;
481 CHAR16
*StdOutFileName
;
482 CHAR16
*StdInFileName
;
483 CHAR16
*StdInVarName
;
484 CHAR16
*StdOutVarName
;
485 CHAR16
*StdErrVarName
;
487 SHELL_FILE_HANDLE TempHandle
;
502 StdOutVarName
= NULL
;
503 StdErrVarName
= NULL
;
504 StdErrFileName
= NULL
;
505 StdInFileName
= NULL
;
506 StdOutFileName
= NULL
;
509 CommandLineCopy
= NULL
;
511 if (ShellParameters
== NULL
|| SystemTableInfo
== NULL
|| OldStdIn
== NULL
|| OldStdOut
== NULL
|| OldStdErr
== NULL
) {
512 return (EFI_INVALID_PARAMETER
);
515 SystemTableInfo
->ConIn
= gST
->ConIn
;
516 SystemTableInfo
->ConInHandle
= gST
->ConsoleInHandle
;
517 SystemTableInfo
->ConOut
= gST
->ConOut
;
518 SystemTableInfo
->ConOutHandle
= gST
->ConsoleOutHandle
;
519 SystemTableInfo
->ConErr
= gST
->StdErr
;
520 SystemTableInfo
->ConErrHandle
= gST
->StandardErrorHandle
;
521 *OldStdIn
= ShellParameters
->StdIn
;
522 *OldStdOut
= ShellParameters
->StdOut
;
523 *OldStdErr
= ShellParameters
->StdErr
;
525 if (NewCommandLine
== NULL
) {
526 return (EFI_SUCCESS
);
529 CommandLineCopy
= StrnCatGrow(&CommandLineCopy
, NULL
, NewCommandLine
, 0);
530 Status
= EFI_SUCCESS
;
533 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
534 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
535 if (Split
!= NULL
&& Split
->SplitStdIn
!= NULL
) {
536 ShellParameters
->StdIn
= Split
->SplitStdIn
;
538 if (Split
!= NULL
&& Split
->SplitStdOut
!= NULL
) {
539 ShellParameters
->StdOut
= Split
->SplitStdOut
;
543 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>>v ")) != NULL
) {
544 SetMem16(CommandLineWalker
, 12, L
' ');
545 StdErrVarName
= CommandLineWalker
+= 6;
547 if (StrStr(CommandLineWalker
, L
" 2>>v ") != NULL
) {
548 Status
= EFI_NOT_FOUND
;
551 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>v ")) != NULL
) {
552 SetMem16(CommandLineWalker
, 12, L
' ');
553 StdOutVarName
= CommandLineWalker
+= 6;
555 if (StrStr(CommandLineWalker
, L
" 1>>v ") != NULL
) {
556 Status
= EFI_NOT_FOUND
;
558 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>v ")) != NULL
) {
559 SetMem16(CommandLineWalker
, 10, L
' ');
560 StdOutVarName
= CommandLineWalker
+= 5;
562 if (StrStr(CommandLineWalker
, L
" >>v ") != NULL
) {
563 Status
= EFI_NOT_FOUND
;
565 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >v ")) != NULL
) {
566 SetMem16(CommandLineWalker
, 8, L
' ');
567 StdOutVarName
= CommandLineWalker
+= 4;
569 if (StrStr(CommandLineWalker
, L
" >v ") != NULL
) {
570 Status
= EFI_NOT_FOUND
;
573 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>a ")) != NULL
) {
574 SetMem16(CommandLineWalker
, 12, L
' ');
575 StdOutFileName
= CommandLineWalker
+= 6;
578 if (StrStr(CommandLineWalker
, L
" 1>>a ") != NULL
) {
579 Status
= EFI_NOT_FOUND
;
582 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>> ")) != NULL
) {
583 SetMem16(CommandLineWalker
, 10, L
' ');
584 if (StdOutFileName
!= NULL
) {
585 Status
= EFI_INVALID_PARAMETER
;
587 StdOutFileName
= CommandLineWalker
+= 5;
590 if (StrStr(CommandLineWalker
, L
" 1>> ") != NULL
) {
591 Status
= EFI_NOT_FOUND
;
594 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >> ")) != NULL
) {
595 SetMem16(CommandLineWalker
, 8, L
' ');
596 if (StdOutFileName
!= NULL
) {
597 Status
= EFI_INVALID_PARAMETER
;
599 StdOutFileName
= CommandLineWalker
+= 4;
602 if (StrStr(CommandLineWalker
, L
" >> ") != NULL
) {
603 Status
= EFI_NOT_FOUND
;
606 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>a ")) != NULL
) {
607 SetMem16(CommandLineWalker
, 10, L
' ');
608 if (StdOutFileName
!= NULL
) {
609 Status
= EFI_INVALID_PARAMETER
;
611 StdOutFileName
= CommandLineWalker
+= 5;
615 if (StrStr(CommandLineWalker
, L
" >>a ") != NULL
) {
616 Status
= EFI_NOT_FOUND
;
619 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>a ")) != NULL
) {
620 SetMem16(CommandLineWalker
, 10, L
' ');
621 if (StdOutFileName
!= NULL
) {
622 Status
= EFI_INVALID_PARAMETER
;
624 StdOutFileName
= CommandLineWalker
+= 5;
628 if (StrStr(CommandLineWalker
, L
" 1>a ") != NULL
) {
629 Status
= EFI_NOT_FOUND
;
632 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >a ")) != NULL
) {
633 SetMem16(CommandLineWalker
, 8, L
' ');
634 if (StdOutFileName
!= NULL
) {
635 Status
= EFI_INVALID_PARAMETER
;
637 StdOutFileName
= CommandLineWalker
+= 4;
641 if (StrStr(CommandLineWalker
, L
" >a ") != NULL
) {
642 Status
= EFI_NOT_FOUND
;
645 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>> ")) != NULL
) {
646 SetMem16(CommandLineWalker
, 10, L
' ');
647 if (StdErrFileName
!= NULL
) {
648 Status
= EFI_INVALID_PARAMETER
;
650 StdErrFileName
= CommandLineWalker
+= 5;
653 if (StrStr(CommandLineWalker
, L
" 2>> ") != NULL
) {
654 Status
= EFI_NOT_FOUND
;
658 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>v ")) != NULL
) {
659 SetMem16(CommandLineWalker
, 10, L
' ');
660 if (StdErrVarName
!= NULL
) {
661 Status
= EFI_INVALID_PARAMETER
;
663 StdErrVarName
= CommandLineWalker
+= 5;
666 if (StrStr(CommandLineWalker
, L
" 2>v ") != NULL
) {
667 Status
= EFI_NOT_FOUND
;
670 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>v ")) != NULL
) {
671 SetMem16(CommandLineWalker
, 10, L
' ');
672 if (StdOutVarName
!= NULL
) {
673 Status
= EFI_INVALID_PARAMETER
;
675 StdOutVarName
= CommandLineWalker
+= 5;
678 if (StrStr(CommandLineWalker
, L
" 1>v ") != NULL
) {
679 Status
= EFI_NOT_FOUND
;
682 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>a ")) != NULL
) {
683 SetMem16(CommandLineWalker
, 10, L
' ');
684 if (StdErrFileName
!= NULL
) {
685 Status
= EFI_INVALID_PARAMETER
;
687 StdErrFileName
= CommandLineWalker
+= 5;
691 if (StrStr(CommandLineWalker
, L
" 2>a ") != NULL
) {
692 Status
= EFI_NOT_FOUND
;
695 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2> ")) != NULL
) {
696 SetMem16(CommandLineWalker
, 8, L
' ');
697 if (StdErrFileName
!= NULL
) {
698 Status
= EFI_INVALID_PARAMETER
;
700 StdErrFileName
= CommandLineWalker
+= 4;
703 if (StrStr(CommandLineWalker
, L
" 2> ") != NULL
) {
704 Status
= EFI_NOT_FOUND
;
708 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1> ")) != NULL
) {
709 SetMem16(CommandLineWalker
, 8, L
' ');
710 if (StdOutFileName
!= NULL
) {
711 Status
= EFI_INVALID_PARAMETER
;
713 StdOutFileName
= CommandLineWalker
+= 4;
716 if (StrStr(CommandLineWalker
, L
" 1> ") != NULL
) {
717 Status
= EFI_NOT_FOUND
;
721 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" > ")) != NULL
) {
722 SetMem16(CommandLineWalker
, 6, L
' ');
723 if (StdOutFileName
!= NULL
) {
724 Status
= EFI_INVALID_PARAMETER
;
726 StdOutFileName
= CommandLineWalker
+= 3;
729 if (StrStr(CommandLineWalker
, L
" > ") != NULL
) {
730 Status
= EFI_NOT_FOUND
;
734 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" < ")) != NULL
) {
735 SetMem16(CommandLineWalker
, 6, L
' ');
736 if (StdInFileName
!= NULL
) {
737 Status
= EFI_INVALID_PARAMETER
;
739 StdInFileName
= CommandLineWalker
+= 3;
741 if (StrStr(CommandLineWalker
, L
" < ") != NULL
) {
742 Status
= EFI_NOT_FOUND
;
745 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <a ")) != NULL
) {
746 SetMem16(CommandLineWalker
, 8, L
' ');
747 if (StdInFileName
!= NULL
) {
748 Status
= EFI_INVALID_PARAMETER
;
750 StdInFileName
= CommandLineWalker
+= 4;
753 if (StrStr(CommandLineWalker
, L
" <a ") != NULL
) {
754 Status
= EFI_NOT_FOUND
;
757 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <v ")) != NULL
) {
758 SetMem16(CommandLineWalker
, 8, L
' ');
759 if (StdInVarName
!= NULL
) {
760 Status
= EFI_INVALID_PARAMETER
;
762 StdInVarName
= CommandLineWalker
+= 4;
764 if (StrStr(CommandLineWalker
, L
" <v ") != NULL
) {
765 Status
= EFI_NOT_FOUND
;
769 if (!EFI_ERROR(Status
)) {
770 if (StdErrFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrFileName
, L
" ")) != NULL
) {
771 CommandLineWalker
[0] = CHAR_NULL
;
773 if (StdOutFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutFileName
, L
" ")) != NULL
) {
774 CommandLineWalker
[0] = CHAR_NULL
;
776 if (StdInFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdInFileName
, L
" ")) != NULL
) {
777 CommandLineWalker
[0] = CHAR_NULL
;
779 if (StdErrVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrVarName
, L
" ")) != NULL
) {
780 CommandLineWalker
[0] = CHAR_NULL
;
782 if (StdOutVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutVarName
, L
" ")) != NULL
) {
783 CommandLineWalker
[0] = CHAR_NULL
;
785 if (StdInVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdInVarName
, L
" ")) != NULL
) {
786 CommandLineWalker
[0] = CHAR_NULL
;
790 // Verify not the same and not duplicating something from a split
794 // Check that no 2 filenames are the same
796 (StdErrFileName
!= NULL
&& StdOutFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdOutFileName
) == 0)
797 ||(StdErrFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdInFileName
) == 0)
798 ||(StdOutFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdOutFileName
, &StdInFileName
) == 0)
800 // Check that no 2 variable names are the same
802 ||(StdErrVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdInVarName
) == 0)
803 ||(StdOutVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdOutVarName
, &StdInVarName
) == 0)
804 ||(StdErrVarName
!= NULL
&& StdOutVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdOutVarName
) == 0)
806 // When a split (using | operator) is in place some are not allowed
808 ||(Split
!= NULL
&& Split
->SplitStdIn
!= NULL
&& (StdInVarName
!= NULL
|| StdInFileName
!= NULL
))
809 ||(Split
!= NULL
&& Split
->SplitStdOut
!= NULL
&& (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
))
811 // Check that nothing is trying to be output to 2 locations.
813 ||(StdErrFileName
!= NULL
&& StdErrVarName
!= NULL
)
814 ||(StdOutFileName
!= NULL
&& StdOutVarName
!= NULL
)
815 ||(StdInFileName
!= NULL
&& StdInVarName
!= NULL
)
817 // There should not be extra > or <
819 ||(StrStr(CommandLineCopy
, L
"<") != NULL
)
820 ||(StrStr(CommandLineCopy
, L
">") != NULL
)
822 // Check for no volatile environment variables
824 ||(StdErrVarName
!= NULL
&& !IsVolatileEnv(StdErrVarName
))
825 ||(StdOutVarName
!= NULL
&& !IsVolatileEnv(StdOutVarName
))
827 // Cant redirect during a reconnect operation.
829 ||(StrStr(NewCommandLine
, L
"connect -r") != NULL
830 && (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
|| StdErrFileName
!= NULL
|| StdErrVarName
!= NULL
))
832 // Check that filetypes (Unicode/Ascii) do not change during an append
834 ||(StdOutFileName
!= NULL
&& OutUnicode
&& OutAppend
&& (!EFI_ERROR(ShellFileExists(StdOutFileName
)) && EFI_ERROR(IsUnicodeFile(StdOutFileName
))))
835 ||(StdErrFileName
!= NULL
&& ErrUnicode
&& ErrAppend
&& (!EFI_ERROR(ShellFileExists(StdErrFileName
)) && EFI_ERROR(IsUnicodeFile(StdErrFileName
))))
836 ||(StdOutFileName
!= NULL
&& !OutUnicode
&& OutAppend
&& (!EFI_ERROR(ShellFileExists(StdOutFileName
)) && !EFI_ERROR(IsUnicodeFile(StdOutFileName
))))
837 ||(StdErrFileName
!= NULL
&& !ErrUnicode
&& ErrAppend
&& (!EFI_ERROR(ShellFileExists(StdErrFileName
)) && !EFI_ERROR(IsUnicodeFile(StdErrFileName
))))
839 Status
= EFI_INVALID_PARAMETER
;
842 // Open the Std<Whatever> and we should not have conflicts here...
848 if (StdErrFileName
!= NULL
) {
851 // delete existing file.
853 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdErrFileName
);
855 Status
= ShellOpenFileByName(StdErrFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
856 if (!ErrAppend
&& ErrUnicode
&& !EFI_ERROR(Status
)) {
858 // Write out the gUnicodeFileTag
860 Size
= sizeof(CHAR16
);
861 TagBuffer
[0] = gUnicodeFileTag
;
862 TagBuffer
[1] = CHAR_NULL
;
863 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
865 if (!ErrUnicode
&& !EFI_ERROR(Status
)) {
866 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
867 ASSERT(TempHandle
!= NULL
);
869 if (!EFI_ERROR(Status
)) {
870 ShellParameters
->StdErr
= TempHandle
;
871 gST
->StdErr
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->StandardErrorHandle
);
878 if (!EFI_ERROR(Status
) && StdOutFileName
!= NULL
) {
881 // delete existing file.
883 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdOutFileName
);
885 Status
= ShellOpenFileByName(StdOutFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
886 if (TempHandle
== NULL
) {
887 Status
= EFI_INVALID_PARAMETER
;
889 if (StrStr(StdOutFileName
, L
"NUL")==StdOutFileName
) {
891 } else if (!OutAppend
&& OutUnicode
&& !EFI_ERROR(Status
)) {
893 // Write out the gUnicodeFileTag
895 Size
= sizeof(CHAR16
);
896 TagBuffer
[0] = gUnicodeFileTag
;
897 TagBuffer
[1] = CHAR_NULL
;
898 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
899 } else if (OutAppend
) {
901 // Move to end of file
903 Status
= ShellInfoObject
.NewEfiShellProtocol
->GetFileSize(TempHandle
, &FileSize
);
904 if (!EFI_ERROR(Status
)) {
905 Status
= ShellInfoObject
.NewEfiShellProtocol
->SetFilePosition(TempHandle
, FileSize
);
908 if (!OutUnicode
&& !EFI_ERROR(Status
)) {
909 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
910 ASSERT(TempHandle
!= NULL
);
912 if (!EFI_ERROR(Status
)) {
913 ShellParameters
->StdOut
= TempHandle
;
914 gST
->ConOut
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->ConsoleOutHandle
);
922 if (!EFI_ERROR(Status
) && StdOutVarName
!= NULL
) {
925 // delete existing variable.
927 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName
, 0, L
"");
929 TempHandle
= CreateFileInterfaceEnv(StdOutVarName
);
930 ASSERT(TempHandle
!= NULL
);
931 ShellParameters
->StdOut
= TempHandle
;
932 gST
->ConOut
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->ConsoleOutHandle
);
938 if (!EFI_ERROR(Status
) && StdErrVarName
!= NULL
) {
941 // delete existing variable.
943 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName
, 0, L
"");
945 TempHandle
= CreateFileInterfaceEnv(StdErrVarName
);
946 ASSERT(TempHandle
!= NULL
);
947 ShellParameters
->StdErr
= TempHandle
;
948 gST
->StdErr
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->StandardErrorHandle
);
954 if (!EFI_ERROR(Status
) && StdInVarName
!= NULL
) {
955 TempHandle
= CreateFileInterfaceEnv(StdInVarName
);
957 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
960 ASSERT(TempHandle
!= NULL
);
961 if (((EFI_FILE_PROTOCOL
*)TempHandle
)->Read(TempHandle
, &Size
, NULL
) != EFI_BUFFER_TOO_SMALL
) {
962 Status
= EFI_INVALID_PARAMETER
;
964 ShellParameters
->StdIn
= TempHandle
;
965 gST
->ConIn
= CreateSimpleTextInOnFile(TempHandle
, &gST
->ConsoleInHandle
);
972 if (!EFI_ERROR(Status
) && StdInFileName
!= NULL
) {
973 Status
= ShellOpenFileByName(
978 if (!InUnicode
&& !EFI_ERROR(Status
)) {
979 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
981 if (!EFI_ERROR(Status
)) {
982 ShellParameters
->StdIn
= TempHandle
;
983 gST
->ConIn
= CreateSimpleTextInOnFile(TempHandle
, &gST
->ConsoleInHandle
);
988 FreePool(CommandLineCopy
);
990 if (gST
->ConIn
== NULL
||gST
->ConOut
== NULL
) {
991 return (EFI_OUT_OF_RESOURCES
);
997 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
998 structure with StdIn and StdOut. The current values are de-allocated.
1000 @param[in,out] ShellParameters Pointer to parameter structure to modify.
1001 @param[in] OldStdIn Pointer to old StdIn.
1002 @param[in] OldStdOut Pointer to old StdOut.
1003 @param[in] OldStdErr Pointer to old StdErr.
1004 @param[in] SystemTableInfo Pointer to old system table information.
1008 RestoreStdInStdOutStdErr (
1009 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1010 IN SHELL_FILE_HANDLE
*OldStdIn
,
1011 IN SHELL_FILE_HANDLE
*OldStdOut
,
1012 IN SHELL_FILE_HANDLE
*OldStdErr
,
1013 IN SYSTEM_TABLE_INFO
*SystemTableInfo
1018 if (ShellParameters
== NULL
1022 ||SystemTableInfo
== NULL
) {
1023 return (EFI_INVALID_PARAMETER
);
1025 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
1026 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
1030 if (ShellParameters
->StdIn
!= *OldStdIn
) {
1031 if ((Split
!= NULL
&& Split
->SplitStdIn
!= ShellParameters
->StdIn
) || Split
== NULL
) {
1032 gEfiShellProtocol
->CloseFile(ShellParameters
->StdIn
);
1034 ShellParameters
->StdIn
= *OldStdIn
;
1036 if (ShellParameters
->StdOut
!= *OldStdOut
) {
1037 if ((Split
!= NULL
&& Split
->SplitStdOut
!= ShellParameters
->StdOut
) || Split
== NULL
) {
1038 gEfiShellProtocol
->CloseFile(ShellParameters
->StdOut
);
1040 ShellParameters
->StdOut
= *OldStdOut
;
1042 if (ShellParameters
->StdErr
!= *OldStdErr
) {
1043 gEfiShellProtocol
->CloseFile(ShellParameters
->StdErr
);
1044 ShellParameters
->StdErr
= *OldStdErr
;
1047 if (gST
->ConIn
!= SystemTableInfo
->ConIn
) {
1048 CloseSimpleTextInOnFile(gST
->ConIn
);
1049 gST
->ConIn
= SystemTableInfo
->ConIn
;
1050 gST
->ConsoleInHandle
= SystemTableInfo
->ConInHandle
;
1052 if (gST
->ConOut
!= SystemTableInfo
->ConOut
) {
1053 CloseSimpleTextOutOnFile(gST
->ConOut
);
1054 gST
->ConOut
= SystemTableInfo
->ConOut
;
1055 gST
->ConsoleOutHandle
= SystemTableInfo
->ConOutHandle
;
1057 if (gST
->StdErr
!= SystemTableInfo
->ConErr
) {
1058 CloseSimpleTextOutOnFile(gST
->StdErr
);
1059 gST
->StdErr
= SystemTableInfo
->ConErr
;
1060 gST
->StandardErrorHandle
= SystemTableInfo
->ConErrHandle
;
1063 return (EFI_SUCCESS
);
1066 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1067 structure by parsing NewCommandLine. The current values are returned to the
1070 If OldArgv or OldArgc is NULL then that value is not returned.
1072 @param[in,out] ShellParameters Pointer to parameter structure to modify.
1073 @param[in] NewCommandLine The new command line to parse and use.
1074 @param[out] OldArgv Pointer to old list of parameters.
1075 @param[out] OldArgc Pointer to old number of items in Argv list.
1077 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
1078 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1083 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1084 IN CONST CHAR16
*NewCommandLine
,
1085 OUT CHAR16
***OldArgv OPTIONAL
,
1086 OUT UINTN
*OldArgc OPTIONAL
1089 ASSERT(ShellParameters
!= NULL
);
1091 if (OldArgc
!= NULL
) {
1092 *OldArgc
= ShellParameters
->Argc
;
1094 if (OldArgc
!= NULL
) {
1095 *OldArgv
= ShellParameters
->Argv
;
1098 return (ParseCommandLineToArgs(NewCommandLine
, &(ShellParameters
->Argv
), &(ShellParameters
->Argc
)));
1102 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1103 structure with Argv and Argc. The current values are de-allocated and the
1104 OldArgv must not be deallocated by the caller.
1106 @param[in,out] ShellParameters pointer to parameter structure to modify
1107 @param[in] OldArgv pointer to old list of parameters
1108 @param[in] OldArgc pointer to old number of items in Argv list
1113 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
1114 IN CHAR16
***OldArgv
,
1119 ASSERT(ShellParameters
!= NULL
);
1120 ASSERT(OldArgv
!= NULL
);
1121 ASSERT(OldArgc
!= NULL
);
1123 if (ShellParameters
->Argv
!= NULL
) {
1124 for ( LoopCounter
= 0
1125 ; LoopCounter
< ShellParameters
->Argc
1128 FreePool(ShellParameters
->Argv
[LoopCounter
]);
1130 FreePool(ShellParameters
->Argv
);
1132 ShellParameters
->Argv
= *OldArgv
;
1134 ShellParameters
->Argc
= *OldArgc
;