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"
19 return the next parameter from a command line string;
21 This function moves the next parameter from Walker into TempParameter and moves
22 Walker up past that parameter for recursive calling. When the final parameter
23 is moved *Walker will be set to NULL;
25 Temp Parameter must be large enough to hold the parameter before calling this
28 @param[in,out] Walker pointer to string of command line. Adjusted to
29 reminaing command line on return
30 @param[in,out] TempParameter pointer to string of command line item extracted.
37 CHAR16
**TempParameter
43 ASSERT(Walker
!= NULL
);
44 ASSERT(*Walker
!= NULL
);
45 ASSERT(TempParameter
!= NULL
);
46 ASSERT(*TempParameter
!= NULL
);
49 // make sure we dont have any leading spaces
51 while ((*Walker
)[0] == L
' ') {
56 // make sure we still have some params now...
58 if (StrLen(*Walker
) == 0) {
59 ASSERT((*Walker
)[0] == CHAR_NULL
);
65 // we have a quoted parameter
66 // could be the last parameter, but SHOULD have a trailing quote
68 if ((*Walker
)[0] == L
'\"') {
70 for (TempLoc
= *Walker
+ 1 ; TempLoc
!= NULL
&& *TempLoc
!= CHAR_NULL
; TempLoc
++) {
71 if (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'^') {
73 } else if (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'\"') {
75 } else if (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'|') {
77 } else if (*TempLoc
== L
'^') {
79 } else if (*TempLoc
== L
'\"') {
85 if (NextDelim
- ((*Walker
)+1) == 0) {
89 StrCpy(*TempParameter
, L
"");
90 *Walker
= NextDelim
+ 1;
91 } else if (NextDelim
!= NULL
) {
92 StrnCpy(*TempParameter
, (*Walker
)+1, NextDelim
- ((*Walker
)+1));
93 *Walker
= NextDelim
+ 1;
96 // last one... someone forgot the training quote!
98 StrCpy(*TempParameter
, *Walker
);
101 for (TempLoc
= *TempParameter
; TempLoc
!= NULL
&& *TempLoc
!= CHAR_NULL
; TempLoc
++) {
102 if ((*TempLoc
== L
'^' && *(TempLoc
+1) == L
'^')
103 || (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'|')
104 || (*TempLoc
== L
'^' && *(TempLoc
+1) == L
'\"')
106 CopyMem(TempLoc
, TempLoc
+1, StrSize(TempLoc
) - sizeof(TempLoc
[0]));
111 // we have a regular parameter (no quote) OR
112 // we have the final parameter (no trailing space)
114 NextDelim
= StrStr((*Walker
), L
" ");
115 if (NextDelim
!= NULL
) {
116 StrnCpy(*TempParameter
, *Walker
, NextDelim
- (*Walker
));
117 (*TempParameter
)[NextDelim
- (*Walker
)] = CHAR_NULL
;
118 *Walker
= NextDelim
+1;
123 StrCpy(*TempParameter
, *Walker
);
126 for (NextDelim
= *TempParameter
; NextDelim
!= NULL
&& *NextDelim
!= CHAR_NULL
; NextDelim
++) {
127 if (*NextDelim
== L
'^' && *(NextDelim
+1) == L
'^') {
128 CopyMem(NextDelim
, NextDelim
+1, StrSize(NextDelim
) - sizeof(NextDelim
[0]));
129 } else if (*NextDelim
== L
'^') {
133 while ((*TempParameter
)[StrLen(*TempParameter
)-1] == L
' ') {
134 (*TempParameter
)[StrLen(*TempParameter
)-1] = CHAR_NULL
;
136 while ((*TempParameter
)[0] == L
' ') {
137 CopyMem(*TempParameter
, (*TempParameter
)+1, StrSize(*TempParameter
) - sizeof((*TempParameter
)[0]));
144 function to populate Argc and Argv.
146 This function parses the CommandLine and divides it into standard C style Argc/Argv
147 parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space
148 delimited and quote surrounded parameter definition.
150 @param[in] CommandLine String of command line to parse
151 @param[in,out] Argv pointer to array of strings; one for each parameter
152 @param[in,out] Argc pointer to number of strings in Argv array
154 @return EFI_SUCCESS the operation was sucessful
155 @return EFI_OUT_OF_RESOURCES a memory allocation failed.
159 ParseCommandLineToArgs(
160 IN CONST CHAR16
*CommandLine
,
161 IN OUT CHAR16
***Argv
,
166 CHAR16
*TempParameter
;
171 ASSERT(Argc
!= NULL
);
172 ASSERT(Argv
!= NULL
);
174 if (CommandLine
== NULL
|| StrLen(CommandLine
)==0) {
177 return (EFI_SUCCESS
);
180 Size
= StrSize(CommandLine
);
181 TempParameter
= AllocateZeroPool(Size
);
182 if (TempParameter
== NULL
) {
183 return (EFI_OUT_OF_RESOURCES
);
187 , Walker
= (CHAR16
*)CommandLine
188 ; Walker
!= NULL
&& *Walker
!= CHAR_NULL
189 ; GetNextParameter(&Walker
, &TempParameter
)
194 Walker = (CHAR16*)CommandLine;
195 while(Walker != NULL) {
196 GetNextParameter(&Walker, &TempParameter);
201 // lets allocate the pointer array
203 (*Argv
) = AllocateZeroPool((Count
)*sizeof(CHAR16
*));
205 return (EFI_OUT_OF_RESOURCES
);
209 Walker
= (CHAR16
*)CommandLine
;
210 while(Walker
!= NULL
&& *Walker
!= CHAR_NULL
) {
211 SetMem16(TempParameter
, Size
, CHAR_NULL
);
212 GetNextParameter(&Walker
, &TempParameter
);
213 NewParam
= AllocateZeroPool(StrSize(TempParameter
));
214 ASSERT(NewParam
!= NULL
);
215 StrCpy(NewParam
, TempParameter
);
216 ((CHAR16
**)(*Argv
))[(*Argc
)] = NewParam
;
219 ASSERT(Count
>= (*Argc
));
220 return (EFI_SUCCESS
);
224 creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
225 installs it on our handle and if there is an existing version of the protocol
226 that one is cached for removal later.
228 @param[in,out] NewShellParameters on a successful return, a pointer to pointer
229 to the newly installed interface.
230 @param[in,out] RootShellInstance on a successful return, pointer to boolean.
231 TRUE if this is the root shell instance.
233 @retval EFI_SUCCESS the operation completed successfully.
234 @return other the operation failed.
235 @sa ReinstallProtocolInterface
236 @sa InstallProtocolInterface
237 @sa ParseCommandLineToArgs
241 CreatePopulateInstallShellParametersProtocol (
242 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
**NewShellParameters
,
243 IN OUT BOOLEAN
*RootShellInstance
247 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
248 CHAR16
*FullCommandLine
;
252 FullCommandLine
= NULL
;
256 // Assert for valid parameters
258 ASSERT(NewShellParameters
!= NULL
);
259 ASSERT(RootShellInstance
!= NULL
);
262 // See if we have a shell parameters placed on us
264 Status
= gBS
->OpenProtocol (
266 &gEfiShellParametersProtocolGuid
,
267 (VOID
**) &ShellInfoObject
.OldShellParameters
,
270 EFI_OPEN_PROTOCOL_GET_PROTOCOL
273 // if we don't then we must be the root shell (error is expected)
275 if (EFI_ERROR (Status
)) {
276 *RootShellInstance
= TRUE
;
280 // Allocate the new structure
282 *NewShellParameters
= AllocateZeroPool(sizeof(EFI_SHELL_PARAMETERS_PROTOCOL
));
283 ASSERT(NewShellParameters
!= NULL
);
286 // get loaded image protocol
288 Status
= gBS
->OpenProtocol (
290 &gEfiLoadedImageProtocolGuid
,
291 (VOID
**) &LoadedImage
,
294 EFI_OPEN_PROTOCOL_GET_PROTOCOL
296 ASSERT_EFI_ERROR(Status
);
298 // Build the full command line
300 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, &FullCommandLine
);
301 if (Status
== EFI_BUFFER_TOO_SMALL
) {
302 FullCommandLine
= AllocateZeroPool(Size
+ LoadedImage
->LoadOptionsSize
);
303 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, &FullCommandLine
);
305 if (Status
== EFI_NOT_FOUND
) {
307 // no parameters via environment... ok
310 ASSERT_EFI_ERROR(Status
);
312 if (Size
== 0 && LoadedImage
->LoadOptionsSize
!= 0) {
314 // Now we need to include a NULL terminator in the size.
316 Size
= LoadedImage
->LoadOptionsSize
+ sizeof(FullCommandLine
[0]);
317 FullCommandLine
= AllocateZeroPool(Size
);
319 if (LoadedImage
->LoadOptionsSize
!= 0){
320 StrCpy(FullCommandLine
, LoadedImage
->LoadOptions
);
322 if (FullCommandLine
!= NULL
) {
324 // Populate Argc and Argv
326 Status
= ParseCommandLineToArgs(FullCommandLine
,
327 &(*NewShellParameters
)->Argv
,
328 &(*NewShellParameters
)->Argc
);
330 FreePool(FullCommandLine
);
332 ASSERT_EFI_ERROR(Status
);
334 (*NewShellParameters
)->Argv
= NULL
;
335 (*NewShellParameters
)->Argc
= 0;
339 // Populate the 3 faked file systems...
341 if (*RootShellInstance
) {
342 (*NewShellParameters
)->StdIn
= &FileInterfaceStdIn
;
343 (*NewShellParameters
)->StdOut
= &FileInterfaceStdOut
;
344 (*NewShellParameters
)->StdErr
= &FileInterfaceStdErr
;
345 Status
= gBS
->InstallProtocolInterface(&gImageHandle
,
346 &gEfiShellParametersProtocolGuid
,
347 EFI_NATIVE_INTERFACE
,
348 (VOID
*)(*NewShellParameters
));
351 // copy from the existing ones
353 (*NewShellParameters
)->StdIn
= ShellInfoObject
.OldShellParameters
->StdIn
;
354 (*NewShellParameters
)->StdOut
= ShellInfoObject
.OldShellParameters
->StdOut
;
355 (*NewShellParameters
)->StdErr
= ShellInfoObject
.OldShellParameters
->StdErr
;
356 Status
= gBS
->ReinstallProtocolInterface(gImageHandle
,
357 &gEfiShellParametersProtocolGuid
,
358 (VOID
*)ShellInfoObject
.OldShellParameters
,
359 (VOID
*)(*NewShellParameters
));
366 frees all memory used by createion and installation of shell parameters protocol
367 and if there was an old version installed it will restore that one.
369 @param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
372 @retval EFI_SUCCESS the cleanup was successful
373 @return other the cleanup failed
374 @sa ReinstallProtocolInterface
375 @sa UninstallProtocolInterface
379 CleanUpShellParametersProtocol (
380 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*NewShellParameters
387 // If the old exists we need to restore it
389 if (ShellInfoObject
.OldShellParameters
!= NULL
) {
390 Status
= gBS
->ReinstallProtocolInterface(gImageHandle
,
391 &gEfiShellParametersProtocolGuid
,
392 (VOID
*)NewShellParameters
,
393 (VOID
*)ShellInfoObject
.OldShellParameters
);
394 DEBUG_CODE(ShellInfoObject
.OldShellParameters
= NULL
;);
397 // No old one, just uninstall us...
399 Status
= gBS
->UninstallProtocolInterface(gImageHandle
,
400 &gEfiShellParametersProtocolGuid
,
401 (VOID
*)NewShellParameters
);
403 if (NewShellParameters
->Argv
!= NULL
) {
404 for ( LoopCounter
= 0
405 ; LoopCounter
< NewShellParameters
->Argc
408 FreePool(NewShellParameters
->Argv
[LoopCounter
]);
410 FreePool(NewShellParameters
->Argv
);
412 FreePool(NewShellParameters
);
417 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
418 structure by parsing NewCommandLine. The current values are returned to the
421 If OldStdIn or OldStdOut is NULL then that value is not returned.
423 @param[in,out] ShellParameters Pointer to parameter structure to modify.
424 @param[in] NewCommandLine The new command line to parse and use.
425 @param[out] OldStdIn Pointer to old StdIn.
426 @param[out] OldStdOut Pointer to old StdOut.
427 @param[out] OldStdErr Pointer to old StdErr.
429 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
430 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
434 UpdateStdInStdOutStdErr(
435 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
436 IN CONST CHAR16
*NewCommandLine
,
437 OUT SHELL_FILE_HANDLE
*OldStdIn
,
438 OUT SHELL_FILE_HANDLE
*OldStdOut
,
439 OUT SHELL_FILE_HANDLE
*OldStdErr
442 CHAR16
*CommandLineCopy
;
443 CHAR16
*CommandLineWalker
;
444 CHAR16
*StdErrFileName
;
445 CHAR16
*StdOutFileName
;
446 CHAR16
*StdInFileName
;
447 CHAR16
*StdInVarName
;
448 CHAR16
*StdOutVarName
;
449 CHAR16
*StdErrVarName
;
451 SHELL_FILE_HANDLE TempHandle
;
462 ASSERT(ShellParameters
!= NULL
);
467 StdOutVarName
= NULL
;
468 StdErrVarName
= NULL
;
469 StdErrFileName
= NULL
;
470 StdInFileName
= NULL
;
471 StdOutFileName
= NULL
;
474 CommandLineCopy
= NULL
;
476 if (OldStdIn
!= NULL
) {
477 *OldStdIn
= ShellParameters
->StdIn
;
479 if (OldStdOut
!= NULL
) {
480 *OldStdOut
= ShellParameters
->StdOut
;
482 if (OldStdErr
!= NULL
) {
483 *OldStdErr
= ShellParameters
->StdErr
;
486 if (NewCommandLine
== NULL
) {
487 return (EFI_SUCCESS
);
490 CommandLineCopy
= StrnCatGrow(&CommandLineCopy
, NULL
, NewCommandLine
, 0);
491 Status
= EFI_SUCCESS
;
494 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
495 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
496 if (Split
!= NULL
&& Split
->SplitStdIn
!= NULL
) {
497 ShellParameters
->StdIn
= Split
->SplitStdIn
;
499 if (Split
!= NULL
&& Split
->SplitStdOut
!= NULL
) {
500 ShellParameters
->StdOut
= Split
->SplitStdOut
;
504 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>>v ")) != NULL
) {
505 StdErrVarName
= CommandLineWalker
+= 6;
508 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>v ")) != NULL
) {
509 StdOutVarName
= CommandLineWalker
+= 6;
511 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>v ")) != NULL
) {
512 StdOutVarName
= CommandLineWalker
+= 5;
514 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >v ")) != NULL
) {
515 StdOutVarName
= CommandLineWalker
+= 4;
518 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>a ")) != NULL
) {
519 StdOutFileName
= CommandLineWalker
+= 6;
523 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>> ")) != NULL
) {
524 if (StdOutFileName
!= NULL
) {
525 Status
= EFI_INVALID_PARAMETER
;
527 StdOutFileName
= CommandLineWalker
+= 5;
531 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >> ")) != NULL
) {
532 if (StdOutFileName
!= NULL
) {
533 Status
= EFI_INVALID_PARAMETER
;
535 StdOutFileName
= CommandLineWalker
+= 4;
539 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>a ")) != NULL
) {
540 if (StdOutFileName
!= NULL
) {
541 Status
= EFI_INVALID_PARAMETER
;
543 StdOutFileName
= CommandLineWalker
+= 5;
548 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>a ")) != NULL
) {
549 if (StdOutFileName
!= NULL
) {
550 Status
= EFI_INVALID_PARAMETER
;
552 StdOutFileName
= CommandLineWalker
+= 5;
557 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >a ")) != NULL
) {
558 if (StdOutFileName
!= NULL
) {
559 Status
= EFI_INVALID_PARAMETER
;
561 StdOutFileName
= CommandLineWalker
+= 4;
566 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>> ")) != NULL
) {
567 if (StdErrFileName
!= NULL
) {
568 Status
= EFI_INVALID_PARAMETER
;
570 StdErrFileName
= CommandLineWalker
+= 5;
575 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>v ")) != NULL
) {
576 if (StdErrVarName
!= NULL
) {
577 Status
= EFI_INVALID_PARAMETER
;
579 StdErrVarName
= CommandLineWalker
+= 5;
583 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>v ")) != NULL
) {
584 if (StdOutVarName
!= NULL
) {
585 Status
= EFI_INVALID_PARAMETER
;
587 StdOutVarName
= CommandLineWalker
+= 5;
591 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>a ")) != NULL
) {
592 if (StdErrFileName
!= NULL
) {
593 Status
= EFI_INVALID_PARAMETER
;
595 StdErrFileName
= CommandLineWalker
+= 5;
600 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2> ")) != NULL
) {
601 if (StdErrFileName
!= NULL
) {
602 Status
= EFI_INVALID_PARAMETER
;
604 StdErrFileName
= CommandLineWalker
+= 4;
609 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1> ")) != NULL
) {
610 if (StdOutFileName
!= NULL
) {
611 Status
= EFI_INVALID_PARAMETER
;
613 StdOutFileName
= CommandLineWalker
+= 4;
618 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" > ")) != NULL
) {
619 if (StdOutFileName
!= NULL
) {
620 Status
= EFI_INVALID_PARAMETER
;
622 StdOutFileName
= CommandLineWalker
+= 3;
627 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" < ")) != NULL
) {
628 if (StdInFileName
!= NULL
) {
629 Status
= EFI_INVALID_PARAMETER
;
631 StdInFileName
= CommandLineWalker
+= 3;
635 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <a ")) != NULL
) {
636 if (StdInFileName
!= NULL
) {
637 Status
= EFI_INVALID_PARAMETER
;
639 StdInFileName
= CommandLineWalker
+= 4;
643 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <v ")) != NULL
) {
644 if (StdInVarName
!= NULL
) {
645 Status
= EFI_INVALID_PARAMETER
;
647 StdInVarName
= CommandLineWalker
+= 4;
652 if (!EFI_ERROR(Status
)) {
653 if (StdErrFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrFileName
, L
" ")) != NULL
) {
654 CommandLineWalker
[0] = CHAR_NULL
;
656 if (StdOutFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutFileName
, L
" ")) != NULL
) {
657 CommandLineWalker
[0] = CHAR_NULL
;
659 if (StdInFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdInFileName
, L
" ")) != NULL
) {
660 CommandLineWalker
[0] = CHAR_NULL
;
662 if (StdErrVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrVarName
, L
" ")) != NULL
) {
663 CommandLineWalker
[0] = CHAR_NULL
;
665 if (StdOutVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutVarName
, L
" ")) != NULL
) {
666 CommandLineWalker
[0] = CHAR_NULL
;
668 if (StdInVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdInVarName
, L
" ")) != NULL
) {
669 CommandLineWalker
[0] = CHAR_NULL
;
673 // Verify not the same and not duplicating something from a split
675 if ((StdErrFileName
!= NULL
&& StdOutFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdOutFileName
) == 0)
676 ||(StdErrFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdInFileName
) == 0)
677 ||(StdOutFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdOutFileName
, &StdInFileName
) == 0)
678 ||(StdErrVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdInVarName
) == 0)
679 ||(StdOutVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdOutVarName
, &StdInVarName
) == 0)
680 ||(StdErrVarName
!= NULL
&& StdOutVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdOutVarName
) == 0)
681 ||(Split
!= NULL
&& Split
->SplitStdIn
!= NULL
&& (StdInVarName
!= NULL
|| StdInFileName
!= NULL
))
682 ||(Split
!= NULL
&& Split
->SplitStdOut
!= NULL
&& (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
))
683 ||(StdErrFileName
!= NULL
&& StdErrVarName
!= NULL
)
684 ||(StdOutFileName
!= NULL
&& StdOutVarName
!= NULL
)
685 ||(StdInFileName
!= NULL
&& StdInVarName
!= NULL
)
686 ||(StdErrVarName
!= NULL
&& !IsVolatileEnv(StdErrVarName
))
687 ||(StdOutVarName
!= NULL
&& !IsVolatileEnv(StdOutVarName
))
689 Status
= EFI_INVALID_PARAMETER
;
692 // Open the Std<Whatever> and we should not have conflicts here...
698 if (StdErrFileName
!= NULL
) {
701 // delete existing file.
703 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdErrFileName
);
705 Status
= ShellOpenFileByName(StdErrFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
706 ASSERT(TempHandle
!= NULL
);
707 if (!ErrAppend
&& ErrUnicode
&& !EFI_ERROR(Status
)) {
709 // Write out the UnicodeFileTag
711 Size
= sizeof(CHAR16
);
712 TagBuffer
[0] = UnicodeFileTag
;
713 TagBuffer
[1] = CHAR_NULL
;
714 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
716 if (!ErrUnicode
&& !EFI_ERROR(Status
)) {
717 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
718 ASSERT(TempHandle
!= NULL
);
720 if (!EFI_ERROR(Status
)) {
721 ShellParameters
->StdErr
= TempHandle
;
728 if (!EFI_ERROR(Status
) && StdOutFileName
!= NULL
) {
731 // delete existing file.
733 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdOutFileName
);
735 Status
= ShellOpenFileByName(StdOutFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
736 ASSERT(TempHandle
!= NULL
);
737 if (!OutAppend
&& OutUnicode
&& !EFI_ERROR(Status
)) {
739 // Write out the UnicodeFileTag
741 Size
= sizeof(CHAR16
);
742 TagBuffer
[0] = UnicodeFileTag
;
743 TagBuffer
[1] = CHAR_NULL
;
744 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
745 } else if (OutAppend
) {
747 // Move to end of file
749 Status
= ShellInfoObject
.NewEfiShellProtocol
->GetFileSize(TempHandle
, &FileSize
);
750 if (!EFI_ERROR(Status
)) {
751 Status
= ShellInfoObject
.NewEfiShellProtocol
->SetFilePosition(TempHandle
, FileSize
);
754 if (!OutUnicode
&& !EFI_ERROR(Status
)) {
755 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
756 ASSERT(TempHandle
!= NULL
);
758 if (!EFI_ERROR(Status
)) {
759 ShellParameters
->StdOut
= TempHandle
;
766 if (!EFI_ERROR(Status
) && StdOutVarName
!= NULL
) {
769 // delete existing variable.
771 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName
, 0, L
"");
773 TempHandle
= CreateFileInterfaceEnv(StdOutVarName
);
774 ASSERT(TempHandle
!= NULL
);
776 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
777 ASSERT(TempHandle
!= NULL
);
779 ShellParameters
->StdOut
= TempHandle
;
785 if (!EFI_ERROR(Status
) && StdErrVarName
!= NULL
) {
788 // delete existing variable.
790 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName
, 0, L
"");
792 TempHandle
= CreateFileInterfaceEnv(StdErrVarName
);
793 ASSERT(TempHandle
!= NULL
);
795 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
796 ASSERT(TempHandle
!= NULL
);
798 ShellParameters
->StdErr
= TempHandle
;
804 if (!EFI_ERROR(Status
) && StdInVarName
!= NULL
) {
805 TempHandle
= CreateFileInterfaceEnv(StdInVarName
);
807 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
810 ASSERT(TempHandle
!= NULL
);
811 if (((EFI_FILE_PROTOCOL
*)TempHandle
)->Read(TempHandle
, &Size
, NULL
) != EFI_BUFFER_TOO_SMALL
) {
812 Status
= EFI_INVALID_PARAMETER
;
814 ShellParameters
->StdIn
= TempHandle
;
821 if (!EFI_ERROR(Status
) && StdInFileName
!= NULL
) {
822 Status
= ShellOpenFileByName(
827 if (!InUnicode
&& !EFI_ERROR(Status
)) {
828 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
830 if (!EFI_ERROR(Status
)) {
831 ShellParameters
->StdIn
= TempHandle
;
836 FreePool(CommandLineCopy
);
841 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
842 structure with StdIn and StdOut. The current values are de-allocated.
844 @param[in,out] ShellParameters pointer to parameter structure to modify
845 @param[out] OldStdIn Pointer to old StdIn.
846 @param[out] OldStdOut Pointer to old StdOut.
847 @param[out] OldStdErr Pointer to old StdErr.
851 RestoreStdInStdOutStdErr (
852 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
853 OUT SHELL_FILE_HANDLE
*OldStdIn OPTIONAL
,
854 OUT SHELL_FILE_HANDLE
*OldStdOut OPTIONAL
,
855 OUT SHELL_FILE_HANDLE
*OldStdErr OPTIONAL
859 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
860 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
864 if (OldStdIn
!= NULL
&& ShellParameters
->StdIn
!= *OldStdIn
) {
865 if ((Split
!= NULL
&& Split
->SplitStdIn
!= ShellParameters
->StdIn
) || Split
== NULL
) {
866 gEfiShellProtocol
->CloseFile(ShellParameters
->StdIn
);
868 ShellParameters
->StdIn
= OldStdIn
==NULL
?NULL
:*OldStdIn
;
870 if (OldStdOut
!= NULL
&& ShellParameters
->StdOut
!= *OldStdOut
) {
871 if ((Split
!= NULL
&& Split
->SplitStdOut
!= ShellParameters
->StdOut
) || Split
== NULL
) {
872 gEfiShellProtocol
->CloseFile(ShellParameters
->StdOut
);
874 ShellParameters
->StdOut
= OldStdOut
==NULL
?NULL
:*OldStdOut
;
876 return (EFI_SUCCESS
);
879 Funcion will replace the current Argc and Argv in the ShellParameters protocol
880 structure by parsing NewCommandLine. The current values are returned to the
883 If OldArgv or OldArgc is NULL then that value is not returned.
885 @param[in,out] ShellParameters Pointer to parameter structure to modify.
886 @param[in] NewCommandLine The new command line to parse and use.
887 @param[out] OldArgv Pointer to old list of parameters.
888 @param[out] OldArgc Pointer to old number of items in Argv list.
890 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
891 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
896 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
897 IN CONST CHAR16
*NewCommandLine
,
898 OUT CHAR16
***OldArgv OPTIONAL
,
899 OUT UINTN
*OldArgc OPTIONAL
902 ASSERT(ShellParameters
!= NULL
);
904 if (OldArgc
!= NULL
) {
905 *OldArgc
= ShellParameters
->Argc
;
907 if (OldArgc
!= NULL
) {
908 *OldArgv
= ShellParameters
->Argv
;
911 return (ParseCommandLineToArgs(NewCommandLine
, &(ShellParameters
->Argv
), &(ShellParameters
->Argc
)));
915 Funcion will replace the current Argc and Argv in the ShellParameters protocol
916 structure with Argv and Argc. The current values are de-allocated and the
917 OldArgv must not be deallocated by the caller.
919 @param[in,out] ShellParameters pointer to parameter structure to modify
920 @param[in] OldArgv pointer to old list of parameters
921 @param[in] OldArgc pointer to old number of items in Argv list
926 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
927 IN CHAR16
***OldArgv
,
932 ASSERT(ShellParameters
!= NULL
);
933 ASSERT(OldArgv
!= NULL
);
934 ASSERT(OldArgc
!= NULL
);
936 if (ShellParameters
->Argv
!= NULL
) {
937 for ( LoopCounter
= 0
938 ; LoopCounter
< ShellParameters
->Argc
941 FreePool(ShellParameters
->Argv
[LoopCounter
]);
943 FreePool(ShellParameters
->Argv
);
945 ShellParameters
->Argv
= *OldArgv
;
947 ShellParameters
->Argc
= *OldArgc
;