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 - 2010, 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
);
423 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
424 structure by parsing NewCommandLine. The current values are returned to the
427 This will also update the system table.
429 @param[in,out] ShellParameters Pointer to parameter structure to modify.
430 @param[in] NewCommandLine The new command line to parse and use.
431 @param[out] OldStdIn Pointer to old StdIn.
432 @param[out] OldStdOut Pointer to old StdOut.
433 @param[out] OldStdErr Pointer to old StdErr.
434 @param[out] SystemTableInfo Pointer to old system table information.
436 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
437 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
441 UpdateStdInStdOutStdErr(
442 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
443 IN CONST CHAR16
*NewCommandLine
,
444 OUT SHELL_FILE_HANDLE
*OldStdIn
,
445 OUT SHELL_FILE_HANDLE
*OldStdOut
,
446 OUT SHELL_FILE_HANDLE
*OldStdErr
,
447 OUT SYSTEM_TABLE_INFO
*SystemTableInfo
450 CHAR16
*CommandLineCopy
;
451 CHAR16
*CommandLineWalker
;
452 CHAR16
*StdErrFileName
;
453 CHAR16
*StdOutFileName
;
454 CHAR16
*StdInFileName
;
455 CHAR16
*StdInVarName
;
456 CHAR16
*StdOutVarName
;
457 CHAR16
*StdErrVarName
;
459 SHELL_FILE_HANDLE TempHandle
;
474 StdOutVarName
= NULL
;
475 StdErrVarName
= NULL
;
476 StdErrFileName
= NULL
;
477 StdInFileName
= NULL
;
478 StdOutFileName
= NULL
;
481 CommandLineCopy
= NULL
;
483 if (ShellParameters
== NULL
|| SystemTableInfo
== NULL
|| OldStdIn
== NULL
|| OldStdOut
== NULL
|| OldStdErr
== NULL
) {
484 return (EFI_INVALID_PARAMETER
);
487 SystemTableInfo
->ConIn
= gST
->ConIn
;
488 SystemTableInfo
->ConInHandle
= gST
->ConsoleInHandle
;
489 SystemTableInfo
->ConOut
= gST
->ConOut
;
490 SystemTableInfo
->ConOutHandle
= gST
->ConsoleOutHandle
;
491 SystemTableInfo
->ConErr
= gST
->StdErr
;
492 SystemTableInfo
->ConErrHandle
= gST
->StandardErrorHandle
;
493 *OldStdIn
= ShellParameters
->StdIn
;
494 *OldStdOut
= ShellParameters
->StdOut
;
495 *OldStdErr
= ShellParameters
->StdErr
;
497 if (NewCommandLine
== NULL
) {
498 return (EFI_SUCCESS
);
501 CommandLineCopy
= StrnCatGrow(&CommandLineCopy
, NULL
, NewCommandLine
, 0);
502 Status
= EFI_SUCCESS
;
505 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
506 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
507 if (Split
!= NULL
&& Split
->SplitStdIn
!= NULL
) {
508 ShellParameters
->StdIn
= Split
->SplitStdIn
;
510 if (Split
!= NULL
&& Split
->SplitStdOut
!= NULL
) {
511 ShellParameters
->StdOut
= Split
->SplitStdOut
;
515 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>>v ")) != NULL
) {
516 StdErrVarName
= CommandLineWalker
+= 6;
519 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>v ")) != NULL
) {
520 StdOutVarName
= CommandLineWalker
+= 6;
522 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>v ")) != NULL
) {
523 StdOutVarName
= CommandLineWalker
+= 5;
525 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >v ")) != NULL
) {
526 StdOutVarName
= CommandLineWalker
+= 4;
529 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>a ")) != NULL
) {
530 StdOutFileName
= CommandLineWalker
+= 6;
534 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>> ")) != NULL
) {
535 if (StdOutFileName
!= NULL
) {
536 Status
= EFI_INVALID_PARAMETER
;
538 StdOutFileName
= CommandLineWalker
+= 5;
542 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >> ")) != NULL
) {
543 if (StdOutFileName
!= NULL
) {
544 Status
= EFI_INVALID_PARAMETER
;
546 StdOutFileName
= CommandLineWalker
+= 4;
550 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>a ")) != NULL
) {
551 if (StdOutFileName
!= NULL
) {
552 Status
= EFI_INVALID_PARAMETER
;
554 StdOutFileName
= CommandLineWalker
+= 5;
559 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>a ")) != NULL
) {
560 if (StdOutFileName
!= NULL
) {
561 Status
= EFI_INVALID_PARAMETER
;
563 StdOutFileName
= CommandLineWalker
+= 5;
568 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >a ")) != NULL
) {
569 if (StdOutFileName
!= NULL
) {
570 Status
= EFI_INVALID_PARAMETER
;
572 StdOutFileName
= CommandLineWalker
+= 4;
577 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>> ")) != NULL
) {
578 if (StdErrFileName
!= NULL
) {
579 Status
= EFI_INVALID_PARAMETER
;
581 StdErrFileName
= CommandLineWalker
+= 5;
586 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>v ")) != NULL
) {
587 if (StdErrVarName
!= NULL
) {
588 Status
= EFI_INVALID_PARAMETER
;
590 StdErrVarName
= CommandLineWalker
+= 5;
594 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>v ")) != NULL
) {
595 if (StdOutVarName
!= NULL
) {
596 Status
= EFI_INVALID_PARAMETER
;
598 StdOutVarName
= CommandLineWalker
+= 5;
602 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>a ")) != NULL
) {
603 if (StdErrFileName
!= NULL
) {
604 Status
= EFI_INVALID_PARAMETER
;
606 StdErrFileName
= CommandLineWalker
+= 5;
611 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2> ")) != NULL
) {
612 if (StdErrFileName
!= NULL
) {
613 Status
= EFI_INVALID_PARAMETER
;
615 StdErrFileName
= CommandLineWalker
+= 4;
620 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1> ")) != NULL
) {
621 if (StdOutFileName
!= NULL
) {
622 Status
= EFI_INVALID_PARAMETER
;
624 StdOutFileName
= CommandLineWalker
+= 4;
629 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" > ")) != NULL
) {
630 if (StdOutFileName
!= NULL
) {
631 Status
= EFI_INVALID_PARAMETER
;
633 StdOutFileName
= CommandLineWalker
+= 3;
638 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" < ")) != NULL
) {
639 if (StdInFileName
!= NULL
) {
640 Status
= EFI_INVALID_PARAMETER
;
642 StdInFileName
= CommandLineWalker
+= 3;
646 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <a ")) != NULL
) {
647 if (StdInFileName
!= NULL
) {
648 Status
= EFI_INVALID_PARAMETER
;
650 StdInFileName
= CommandLineWalker
+= 4;
654 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <v ")) != NULL
) {
655 if (StdInVarName
!= NULL
) {
656 Status
= EFI_INVALID_PARAMETER
;
658 StdInVarName
= CommandLineWalker
+= 4;
663 if (!EFI_ERROR(Status
)) {
664 if (StdErrFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrFileName
, L
" ")) != NULL
) {
665 CommandLineWalker
[0] = CHAR_NULL
;
667 if (StdOutFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutFileName
, L
" ")) != NULL
) {
668 CommandLineWalker
[0] = CHAR_NULL
;
670 if (StdInFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdInFileName
, L
" ")) != NULL
) {
671 CommandLineWalker
[0] = CHAR_NULL
;
673 if (StdErrVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrVarName
, L
" ")) != NULL
) {
674 CommandLineWalker
[0] = CHAR_NULL
;
676 if (StdOutVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutVarName
, L
" ")) != NULL
) {
677 CommandLineWalker
[0] = CHAR_NULL
;
679 if (StdInVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdInVarName
, L
" ")) != NULL
) {
680 CommandLineWalker
[0] = CHAR_NULL
;
684 // Verify not the same and not duplicating something from a split
686 if ((StdErrFileName
!= NULL
&& StdOutFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdOutFileName
) == 0)
687 ||(StdErrFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdInFileName
) == 0)
688 ||(StdOutFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdOutFileName
, &StdInFileName
) == 0)
689 ||(StdErrVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdInVarName
) == 0)
690 ||(StdOutVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdOutVarName
, &StdInVarName
) == 0)
691 ||(StdErrVarName
!= NULL
&& StdOutVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdOutVarName
) == 0)
692 ||(Split
!= NULL
&& Split
->SplitStdIn
!= NULL
&& (StdInVarName
!= NULL
|| StdInFileName
!= NULL
))
693 ||(Split
!= NULL
&& Split
->SplitStdOut
!= NULL
&& (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
))
694 ||(StdErrFileName
!= NULL
&& StdErrVarName
!= NULL
)
695 ||(StdOutFileName
!= NULL
&& StdOutVarName
!= NULL
)
696 ||(StdInFileName
!= NULL
&& StdInVarName
!= NULL
)
697 ||(StdErrVarName
!= NULL
&& !IsVolatileEnv(StdErrVarName
))
698 ||(StdOutVarName
!= NULL
&& !IsVolatileEnv(StdOutVarName
))
699 ||(StrStr(NewCommandLine
, L
"connect -r") != NULL
700 && (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
|| StdErrFileName
!= NULL
|| StdErrVarName
!= NULL
))
702 Status
= EFI_INVALID_PARAMETER
;
705 // Open the Std<Whatever> and we should not have conflicts here...
711 if (StdErrFileName
!= NULL
) {
714 // delete existing file.
716 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdErrFileName
);
718 Status
= ShellOpenFileByName(StdErrFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
719 ASSERT(TempHandle
!= NULL
);
720 if (!ErrAppend
&& ErrUnicode
&& !EFI_ERROR(Status
)) {
722 // Write out the UnicodeFileTag
724 Size
= sizeof(CHAR16
);
725 TagBuffer
[0] = UnicodeFileTag
;
726 TagBuffer
[1] = CHAR_NULL
;
727 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
729 if (!ErrUnicode
&& !EFI_ERROR(Status
)) {
730 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
731 ASSERT(TempHandle
!= NULL
);
733 if (!EFI_ERROR(Status
)) {
734 ShellParameters
->StdErr
= TempHandle
;
735 gST
->StdErr
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->StandardErrorHandle
);
742 if (!EFI_ERROR(Status
) && StdOutFileName
!= NULL
) {
745 // delete existing file.
747 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdOutFileName
);
749 Status
= ShellOpenFileByName(StdOutFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
750 if (TempHandle
== NULL
) {
751 Status
= EFI_INVALID_PARAMETER
;
753 if (!OutAppend
&& OutUnicode
&& !EFI_ERROR(Status
)) {
755 // Write out the UnicodeFileTag
757 Size
= sizeof(CHAR16
);
758 TagBuffer
[0] = UnicodeFileTag
;
759 TagBuffer
[1] = CHAR_NULL
;
760 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
761 } else if (OutAppend
) {
763 // Move to end of file
765 Status
= ShellInfoObject
.NewEfiShellProtocol
->GetFileSize(TempHandle
, &FileSize
);
766 if (!EFI_ERROR(Status
)) {
767 Status
= ShellInfoObject
.NewEfiShellProtocol
->SetFilePosition(TempHandle
, FileSize
);
770 if (!OutUnicode
&& !EFI_ERROR(Status
)) {
771 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
772 ASSERT(TempHandle
!= NULL
);
774 if (!EFI_ERROR(Status
)) {
775 ShellParameters
->StdOut
= TempHandle
;
776 gST
->ConOut
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->ConsoleOutHandle
);
784 if (!EFI_ERROR(Status
) && StdOutVarName
!= NULL
) {
787 // delete existing variable.
789 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName
, 0, L
"");
791 TempHandle
= CreateFileInterfaceEnv(StdOutVarName
);
792 ASSERT(TempHandle
!= NULL
);
794 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
795 ASSERT(TempHandle
!= NULL
);
797 ShellParameters
->StdOut
= TempHandle
;
798 gST
->ConOut
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->ConsoleOutHandle
);
804 if (!EFI_ERROR(Status
) && StdErrVarName
!= NULL
) {
807 // delete existing variable.
809 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName
, 0, L
"");
811 TempHandle
= CreateFileInterfaceEnv(StdErrVarName
);
812 ASSERT(TempHandle
!= NULL
);
814 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
815 ASSERT(TempHandle
!= NULL
);
817 ShellParameters
->StdErr
= TempHandle
;
818 gST
->StdErr
= CreateSimpleTextOutOnFile(TempHandle
, &gST
->StandardErrorHandle
);
824 if (!EFI_ERROR(Status
) && StdInVarName
!= NULL
) {
825 TempHandle
= CreateFileInterfaceEnv(StdInVarName
);
827 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
830 ASSERT(TempHandle
!= NULL
);
831 if (((EFI_FILE_PROTOCOL
*)TempHandle
)->Read(TempHandle
, &Size
, NULL
) != EFI_BUFFER_TOO_SMALL
) {
832 Status
= EFI_INVALID_PARAMETER
;
834 ShellParameters
->StdIn
= TempHandle
;
835 gST
->ConIn
= CreateSimpleTextInOnFile(TempHandle
, &gST
->ConsoleInHandle
);
842 if (!EFI_ERROR(Status
) && StdInFileName
!= NULL
) {
843 Status
= ShellOpenFileByName(
848 if (!InUnicode
&& !EFI_ERROR(Status
)) {
849 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
851 if (!EFI_ERROR(Status
)) {
852 ShellParameters
->StdIn
= TempHandle
;
853 gST
->ConIn
= CreateSimpleTextInOnFile(TempHandle
, &gST
->ConsoleInHandle
);
858 FreePool(CommandLineCopy
);
860 if (gST
->ConIn
== NULL
||gST
->ConOut
== NULL
) {
861 return (EFI_OUT_OF_RESOURCES
);
867 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
868 structure with StdIn and StdOut. The current values are de-allocated.
870 @param[in,out] ShellParameters Pointer to parameter structure to modify.
871 @param[in] OldStdIn Pointer to old StdIn.
872 @param[in] OldStdOut Pointer to old StdOut.
873 @param[in] OldStdErr Pointer to old StdErr.
874 @param[in] SystemTableInfo Pointer to old system table information.
878 RestoreStdInStdOutStdErr (
879 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
880 IN SHELL_FILE_HANDLE
*OldStdIn
,
881 IN SHELL_FILE_HANDLE
*OldStdOut
,
882 IN SHELL_FILE_HANDLE
*OldStdErr
,
883 IN SYSTEM_TABLE_INFO
*SystemTableInfo
888 if (ShellParameters
== NULL
892 ||SystemTableInfo
== NULL
) {
893 return (EFI_INVALID_PARAMETER
);
895 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
896 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
900 if (ShellParameters
->StdIn
!= *OldStdIn
) {
901 if ((Split
!= NULL
&& Split
->SplitStdIn
!= ShellParameters
->StdIn
) || Split
== NULL
) {
902 gEfiShellProtocol
->CloseFile(ShellParameters
->StdIn
);
904 ShellParameters
->StdIn
= *OldStdIn
;
906 if (ShellParameters
->StdOut
!= *OldStdOut
) {
907 if ((Split
!= NULL
&& Split
->SplitStdOut
!= ShellParameters
->StdOut
) || Split
== NULL
) {
908 gEfiShellProtocol
->CloseFile(ShellParameters
->StdOut
);
910 ShellParameters
->StdOut
= *OldStdOut
;
912 if (ShellParameters
->StdErr
!= *OldStdErr
) {
913 gEfiShellProtocol
->CloseFile(ShellParameters
->StdErr
);
914 ShellParameters
->StdErr
= *OldStdErr
;
917 if (gST
->ConIn
!= SystemTableInfo
->ConIn
) {
918 CloseSimpleTextInOnFile(gST
->ConIn
);
919 gST
->ConIn
= SystemTableInfo
->ConIn
;
920 gST
->ConsoleInHandle
= SystemTableInfo
->ConInHandle
;
922 if (gST
->ConOut
!= SystemTableInfo
->ConOut
) {
923 CloseSimpleTextOutOnFile(gST
->ConOut
);
924 gST
->ConOut
= SystemTableInfo
->ConOut
;
925 gST
->ConsoleOutHandle
= SystemTableInfo
->ConOutHandle
;
927 if (gST
->StdErr
!= SystemTableInfo
->ConErr
) {
928 CloseSimpleTextOutOnFile(gST
->StdErr
);
929 gST
->StdErr
= SystemTableInfo
->ConErr
;
930 gST
->StandardErrorHandle
= SystemTableInfo
->ConErrHandle
;
933 return (EFI_SUCCESS
);
936 Funcion will replace the current Argc and Argv in the ShellParameters protocol
937 structure by parsing NewCommandLine. The current values are returned to the
940 If OldArgv or OldArgc is NULL then that value is not returned.
942 @param[in,out] ShellParameters Pointer to parameter structure to modify.
943 @param[in] NewCommandLine The new command line to parse and use.
944 @param[out] OldArgv Pointer to old list of parameters.
945 @param[out] OldArgc Pointer to old number of items in Argv list.
947 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
948 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
953 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
954 IN CONST CHAR16
*NewCommandLine
,
955 OUT CHAR16
***OldArgv OPTIONAL
,
956 OUT UINTN
*OldArgc OPTIONAL
959 ASSERT(ShellParameters
!= NULL
);
961 if (OldArgc
!= NULL
) {
962 *OldArgc
= ShellParameters
->Argc
;
964 if (OldArgc
!= NULL
) {
965 *OldArgv
= ShellParameters
->Argv
;
968 return (ParseCommandLineToArgs(NewCommandLine
, &(ShellParameters
->Argv
), &(ShellParameters
->Argc
)));
972 Funcion will replace the current Argc and Argv in the ShellParameters protocol
973 structure with Argv and Argc. The current values are de-allocated and the
974 OldArgv must not be deallocated by the caller.
976 @param[in,out] ShellParameters pointer to parameter structure to modify
977 @param[in] OldArgv pointer to old list of parameters
978 @param[in] OldArgc pointer to old number of items in Argv list
983 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
984 IN CHAR16
***OldArgv
,
989 ASSERT(ShellParameters
!= NULL
);
990 ASSERT(OldArgv
!= NULL
);
991 ASSERT(OldArgc
!= NULL
);
993 if (ShellParameters
->Argv
!= NULL
) {
994 for ( LoopCounter
= 0
995 ; LoopCounter
< ShellParameters
->Argc
998 FreePool(ShellParameters
->Argv
[LoopCounter
]);
1000 FreePool(ShellParameters
->Argv
);
1002 ShellParameters
->Argv
= *OldArgv
;
1004 ShellParameters
->Argc
= *OldArgc
;