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 if ((*NewShellParameters
) == NULL
) {
284 return (EFI_OUT_OF_RESOURCES
);
288 // get loaded image protocol
290 Status
= gBS
->OpenProtocol (
292 &gEfiLoadedImageProtocolGuid
,
293 (VOID
**) &LoadedImage
,
296 EFI_OPEN_PROTOCOL_GET_PROTOCOL
298 ASSERT_EFI_ERROR(Status
);
300 // Build the full command line
302 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, &FullCommandLine
);
303 if (Status
== EFI_BUFFER_TOO_SMALL
) {
304 FullCommandLine
= AllocateZeroPool(Size
+ LoadedImage
->LoadOptionsSize
);
305 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(L
"ShellOpt", &Size
, &FullCommandLine
);
307 if (Status
== EFI_NOT_FOUND
) {
309 // no parameters via environment... ok
312 if (EFI_ERROR(Status
)) {
316 if (Size
== 0 && LoadedImage
->LoadOptionsSize
!= 0) {
317 ASSERT(FullCommandLine
== NULL
);
319 // Now we need to include a NULL terminator in the size.
321 Size
= LoadedImage
->LoadOptionsSize
+ sizeof(FullCommandLine
[0]);
322 FullCommandLine
= AllocateZeroPool(Size
);
324 if (FullCommandLine
!= NULL
) {
325 if (LoadedImage
->LoadOptionsSize
!= 0){
326 StrCpy(FullCommandLine
, LoadedImage
->LoadOptions
);
329 // Populate Argc and Argv
331 Status
= ParseCommandLineToArgs(FullCommandLine
,
332 &(*NewShellParameters
)->Argv
,
333 &(*NewShellParameters
)->Argc
);
335 FreePool(FullCommandLine
);
337 ASSERT_EFI_ERROR(Status
);
339 (*NewShellParameters
)->Argv
= NULL
;
340 (*NewShellParameters
)->Argc
= 0;
344 // Populate the 3 faked file systems...
346 if (*RootShellInstance
) {
347 (*NewShellParameters
)->StdIn
= &FileInterfaceStdIn
;
348 (*NewShellParameters
)->StdOut
= &FileInterfaceStdOut
;
349 (*NewShellParameters
)->StdErr
= &FileInterfaceStdErr
;
350 Status
= gBS
->InstallProtocolInterface(&gImageHandle
,
351 &gEfiShellParametersProtocolGuid
,
352 EFI_NATIVE_INTERFACE
,
353 (VOID
*)(*NewShellParameters
));
356 // copy from the existing ones
358 (*NewShellParameters
)->StdIn
= ShellInfoObject
.OldShellParameters
->StdIn
;
359 (*NewShellParameters
)->StdOut
= ShellInfoObject
.OldShellParameters
->StdOut
;
360 (*NewShellParameters
)->StdErr
= ShellInfoObject
.OldShellParameters
->StdErr
;
361 Status
= gBS
->ReinstallProtocolInterface(gImageHandle
,
362 &gEfiShellParametersProtocolGuid
,
363 (VOID
*)ShellInfoObject
.OldShellParameters
,
364 (VOID
*)(*NewShellParameters
));
371 frees all memory used by createion and installation of shell parameters protocol
372 and if there was an old version installed it will restore that one.
374 @param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
377 @retval EFI_SUCCESS the cleanup was successful
378 @return other the cleanup failed
379 @sa ReinstallProtocolInterface
380 @sa UninstallProtocolInterface
384 CleanUpShellParametersProtocol (
385 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*NewShellParameters
392 // If the old exists we need to restore it
394 if (ShellInfoObject
.OldShellParameters
!= NULL
) {
395 Status
= gBS
->ReinstallProtocolInterface(gImageHandle
,
396 &gEfiShellParametersProtocolGuid
,
397 (VOID
*)NewShellParameters
,
398 (VOID
*)ShellInfoObject
.OldShellParameters
);
399 DEBUG_CODE(ShellInfoObject
.OldShellParameters
= NULL
;);
402 // No old one, just uninstall us...
404 Status
= gBS
->UninstallProtocolInterface(gImageHandle
,
405 &gEfiShellParametersProtocolGuid
,
406 (VOID
*)NewShellParameters
);
408 if (NewShellParameters
->Argv
!= NULL
) {
409 for ( LoopCounter
= 0
410 ; LoopCounter
< NewShellParameters
->Argc
413 FreePool(NewShellParameters
->Argv
[LoopCounter
]);
415 FreePool(NewShellParameters
->Argv
);
417 FreePool(NewShellParameters
);
422 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
423 structure by parsing NewCommandLine. The current values are returned to the
426 If OldStdIn or OldStdOut is NULL then that value is not returned.
428 @param[in,out] ShellParameters Pointer to parameter structure to modify.
429 @param[in] NewCommandLine The new command line to parse and use.
430 @param[out] OldStdIn Pointer to old StdIn.
431 @param[out] OldStdOut Pointer to old StdOut.
432 @param[out] OldStdErr Pointer to old StdErr.
434 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
435 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
439 UpdateStdInStdOutStdErr(
440 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
441 IN CONST CHAR16
*NewCommandLine
,
442 OUT SHELL_FILE_HANDLE
*OldStdIn
,
443 OUT SHELL_FILE_HANDLE
*OldStdOut
,
444 OUT SHELL_FILE_HANDLE
*OldStdErr
447 CHAR16
*CommandLineCopy
;
448 CHAR16
*CommandLineWalker
;
449 CHAR16
*StdErrFileName
;
450 CHAR16
*StdOutFileName
;
451 CHAR16
*StdInFileName
;
452 CHAR16
*StdInVarName
;
453 CHAR16
*StdOutVarName
;
454 CHAR16
*StdErrVarName
;
456 SHELL_FILE_HANDLE TempHandle
;
467 ASSERT(ShellParameters
!= NULL
);
472 StdOutVarName
= NULL
;
473 StdErrVarName
= NULL
;
474 StdErrFileName
= NULL
;
475 StdInFileName
= NULL
;
476 StdOutFileName
= NULL
;
479 CommandLineCopy
= NULL
;
481 if (OldStdIn
!= NULL
) {
482 *OldStdIn
= ShellParameters
->StdIn
;
484 if (OldStdOut
!= NULL
) {
485 *OldStdOut
= ShellParameters
->StdOut
;
487 if (OldStdErr
!= NULL
) {
488 *OldStdErr
= ShellParameters
->StdErr
;
491 if (NewCommandLine
== NULL
) {
492 return (EFI_SUCCESS
);
495 CommandLineCopy
= StrnCatGrow(&CommandLineCopy
, NULL
, NewCommandLine
, 0);
496 Status
= EFI_SUCCESS
;
499 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
500 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
501 if (Split
!= NULL
&& Split
->SplitStdIn
!= NULL
) {
502 ShellParameters
->StdIn
= Split
->SplitStdIn
;
504 if (Split
!= NULL
&& Split
->SplitStdOut
!= NULL
) {
505 ShellParameters
->StdOut
= Split
->SplitStdOut
;
509 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>>v ")) != NULL
) {
510 StdErrVarName
= CommandLineWalker
+= 6;
513 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>v ")) != NULL
) {
514 StdOutVarName
= CommandLineWalker
+= 6;
516 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>v ")) != NULL
) {
517 StdOutVarName
= CommandLineWalker
+= 5;
519 } else if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >v ")) != NULL
) {
520 StdOutVarName
= CommandLineWalker
+= 4;
523 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>>a ")) != NULL
) {
524 StdOutFileName
= CommandLineWalker
+= 6;
528 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>> ")) != NULL
) {
529 if (StdOutFileName
!= NULL
) {
530 Status
= EFI_INVALID_PARAMETER
;
532 StdOutFileName
= CommandLineWalker
+= 5;
536 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >> ")) != NULL
) {
537 if (StdOutFileName
!= NULL
) {
538 Status
= EFI_INVALID_PARAMETER
;
540 StdOutFileName
= CommandLineWalker
+= 4;
544 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >>a ")) != NULL
) {
545 if (StdOutFileName
!= NULL
) {
546 Status
= EFI_INVALID_PARAMETER
;
548 StdOutFileName
= CommandLineWalker
+= 5;
553 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>a ")) != NULL
) {
554 if (StdOutFileName
!= NULL
) {
555 Status
= EFI_INVALID_PARAMETER
;
557 StdOutFileName
= CommandLineWalker
+= 5;
562 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" >a ")) != NULL
) {
563 if (StdOutFileName
!= NULL
) {
564 Status
= EFI_INVALID_PARAMETER
;
566 StdOutFileName
= CommandLineWalker
+= 4;
571 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>> ")) != NULL
) {
572 if (StdErrFileName
!= NULL
) {
573 Status
= EFI_INVALID_PARAMETER
;
575 StdErrFileName
= CommandLineWalker
+= 5;
580 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>v ")) != NULL
) {
581 if (StdErrVarName
!= NULL
) {
582 Status
= EFI_INVALID_PARAMETER
;
584 StdErrVarName
= CommandLineWalker
+= 5;
588 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1>v ")) != NULL
) {
589 if (StdOutVarName
!= NULL
) {
590 Status
= EFI_INVALID_PARAMETER
;
592 StdOutVarName
= CommandLineWalker
+= 5;
596 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2>a ")) != NULL
) {
597 if (StdErrFileName
!= NULL
) {
598 Status
= EFI_INVALID_PARAMETER
;
600 StdErrFileName
= CommandLineWalker
+= 5;
605 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 2> ")) != NULL
) {
606 if (StdErrFileName
!= NULL
) {
607 Status
= EFI_INVALID_PARAMETER
;
609 StdErrFileName
= CommandLineWalker
+= 4;
614 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" 1> ")) != NULL
) {
615 if (StdOutFileName
!= NULL
) {
616 Status
= EFI_INVALID_PARAMETER
;
618 StdOutFileName
= CommandLineWalker
+= 4;
623 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" > ")) != NULL
) {
624 if (StdOutFileName
!= NULL
) {
625 Status
= EFI_INVALID_PARAMETER
;
627 StdOutFileName
= CommandLineWalker
+= 3;
632 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" < ")) != NULL
) {
633 if (StdInFileName
!= NULL
) {
634 Status
= EFI_INVALID_PARAMETER
;
636 StdInFileName
= CommandLineWalker
+= 3;
640 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <a ")) != NULL
) {
641 if (StdInFileName
!= NULL
) {
642 Status
= EFI_INVALID_PARAMETER
;
644 StdInFileName
= CommandLineWalker
+= 4;
648 if (!EFI_ERROR(Status
) && (CommandLineWalker
= StrStr(CommandLineCopy
, L
" <v ")) != NULL
) {
649 if (StdInVarName
!= NULL
) {
650 Status
= EFI_INVALID_PARAMETER
;
652 StdInVarName
= CommandLineWalker
+= 4;
657 if (!EFI_ERROR(Status
)) {
658 if (StdErrFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrFileName
, L
" ")) != NULL
) {
659 CommandLineWalker
[0] = CHAR_NULL
;
661 if (StdOutFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutFileName
, L
" ")) != NULL
) {
662 CommandLineWalker
[0] = CHAR_NULL
;
664 if (StdInFileName
!= NULL
&& (CommandLineWalker
= StrStr(StdInFileName
, L
" ")) != NULL
) {
665 CommandLineWalker
[0] = CHAR_NULL
;
667 if (StdErrVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdErrVarName
, L
" ")) != NULL
) {
668 CommandLineWalker
[0] = CHAR_NULL
;
670 if (StdOutVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdOutVarName
, L
" ")) != NULL
) {
671 CommandLineWalker
[0] = CHAR_NULL
;
673 if (StdInVarName
!= NULL
&& (CommandLineWalker
= StrStr(StdInVarName
, L
" ")) != NULL
) {
674 CommandLineWalker
[0] = CHAR_NULL
;
678 // Verify not the same and not duplicating something from a split
680 if ((StdErrFileName
!= NULL
&& StdOutFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdOutFileName
) == 0)
681 ||(StdErrFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdErrFileName
, &StdInFileName
) == 0)
682 ||(StdOutFileName
!= NULL
&& StdInFileName
!= NULL
&& StringNoCaseCompare(&StdOutFileName
, &StdInFileName
) == 0)
683 ||(StdErrVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdInVarName
) == 0)
684 ||(StdOutVarName
!= NULL
&& StdInVarName
!= NULL
&& StringNoCaseCompare(&StdOutVarName
, &StdInVarName
) == 0)
685 ||(StdErrVarName
!= NULL
&& StdOutVarName
!= NULL
&& StringNoCaseCompare(&StdErrVarName
, &StdOutVarName
) == 0)
686 ||(Split
!= NULL
&& Split
->SplitStdIn
!= NULL
&& (StdInVarName
!= NULL
|| StdInFileName
!= NULL
))
687 ||(Split
!= NULL
&& Split
->SplitStdOut
!= NULL
&& (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
))
688 ||(StdErrFileName
!= NULL
&& StdErrVarName
!= NULL
)
689 ||(StdOutFileName
!= NULL
&& StdOutVarName
!= NULL
)
690 ||(StdInFileName
!= NULL
&& StdInVarName
!= NULL
)
691 ||(StdErrVarName
!= NULL
&& !IsVolatileEnv(StdErrVarName
))
692 ||(StdOutVarName
!= NULL
&& !IsVolatileEnv(StdOutVarName
))
693 ||(StrStr(NewCommandLine
, L
"connect -r") != NULL
694 && (StdOutVarName
!= NULL
|| StdOutFileName
!= NULL
|| StdErrFileName
!= NULL
|| StdErrVarName
!= NULL
))
696 Status
= EFI_INVALID_PARAMETER
;
699 // Open the Std<Whatever> and we should not have conflicts here...
705 if (StdErrFileName
!= NULL
) {
708 // delete existing file.
710 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdErrFileName
);
712 Status
= ShellOpenFileByName(StdErrFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
713 ASSERT(TempHandle
!= NULL
);
714 if (!ErrAppend
&& ErrUnicode
&& !EFI_ERROR(Status
)) {
716 // Write out the UnicodeFileTag
718 Size
= sizeof(CHAR16
);
719 TagBuffer
[0] = UnicodeFileTag
;
720 TagBuffer
[1] = CHAR_NULL
;
721 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
723 if (!ErrUnicode
&& !EFI_ERROR(Status
)) {
724 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
725 ASSERT(TempHandle
!= NULL
);
727 if (!EFI_ERROR(Status
)) {
728 ShellParameters
->StdErr
= TempHandle
;
735 if (!EFI_ERROR(Status
) && StdOutFileName
!= NULL
) {
738 // delete existing file.
740 ShellInfoObject
.NewEfiShellProtocol
->DeleteFileByName(StdOutFileName
);
742 Status
= ShellOpenFileByName(StdOutFileName
, &TempHandle
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
|EFI_FILE_MODE_CREATE
,0);
743 if (TempHandle
== NULL
) {
744 Status
= EFI_INVALID_PARAMETER
;
746 if (!OutAppend
&& OutUnicode
&& !EFI_ERROR(Status
)) {
748 // Write out the UnicodeFileTag
750 Size
= sizeof(CHAR16
);
751 TagBuffer
[0] = UnicodeFileTag
;
752 TagBuffer
[1] = CHAR_NULL
;
753 ShellInfoObject
.NewEfiShellProtocol
->WriteFile(TempHandle
, &Size
, TagBuffer
);
754 } else if (OutAppend
) {
756 // Move to end of file
758 Status
= ShellInfoObject
.NewEfiShellProtocol
->GetFileSize(TempHandle
, &FileSize
);
759 if (!EFI_ERROR(Status
)) {
760 Status
= ShellInfoObject
.NewEfiShellProtocol
->SetFilePosition(TempHandle
, FileSize
);
763 if (!OutUnicode
&& !EFI_ERROR(Status
)) {
764 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
765 ASSERT(TempHandle
!= NULL
);
767 if (!EFI_ERROR(Status
)) {
768 ShellParameters
->StdOut
= TempHandle
;
776 if (!EFI_ERROR(Status
) && StdOutVarName
!= NULL
) {
779 // delete existing variable.
781 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName
, 0, L
"");
783 TempHandle
= CreateFileInterfaceEnv(StdOutVarName
);
784 ASSERT(TempHandle
!= NULL
);
786 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
787 ASSERT(TempHandle
!= NULL
);
789 ShellParameters
->StdOut
= TempHandle
;
795 if (!EFI_ERROR(Status
) && StdErrVarName
!= NULL
) {
798 // delete existing variable.
800 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName
, 0, L
"");
802 TempHandle
= CreateFileInterfaceEnv(StdErrVarName
);
803 ASSERT(TempHandle
!= NULL
);
805 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
806 ASSERT(TempHandle
!= NULL
);
808 ShellParameters
->StdErr
= TempHandle
;
814 if (!EFI_ERROR(Status
) && StdInVarName
!= NULL
) {
815 TempHandle
= CreateFileInterfaceEnv(StdInVarName
);
817 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
820 ASSERT(TempHandle
!= NULL
);
821 if (((EFI_FILE_PROTOCOL
*)TempHandle
)->Read(TempHandle
, &Size
, NULL
) != EFI_BUFFER_TOO_SMALL
) {
822 Status
= EFI_INVALID_PARAMETER
;
824 ShellParameters
->StdIn
= TempHandle
;
831 if (!EFI_ERROR(Status
) && StdInFileName
!= NULL
) {
832 Status
= ShellOpenFileByName(
837 if (!InUnicode
&& !EFI_ERROR(Status
)) {
838 TempHandle
= CreateFileInterfaceFile(TempHandle
, FALSE
);
840 if (!EFI_ERROR(Status
)) {
841 ShellParameters
->StdIn
= TempHandle
;
846 FreePool(CommandLineCopy
);
851 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
852 structure with StdIn and StdOut. The current values are de-allocated.
854 @param[in,out] ShellParameters pointer to parameter structure to modify
855 @param[out] OldStdIn Pointer to old StdIn.
856 @param[out] OldStdOut Pointer to old StdOut.
857 @param[out] OldStdErr Pointer to old StdErr.
861 RestoreStdInStdOutStdErr (
862 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
863 OUT SHELL_FILE_HANDLE
*OldStdIn OPTIONAL
,
864 OUT SHELL_FILE_HANDLE
*OldStdOut OPTIONAL
,
865 OUT SHELL_FILE_HANDLE
*OldStdErr OPTIONAL
869 if (!IsListEmpty(&ShellInfoObject
.SplitList
.Link
)) {
870 Split
= (SPLIT_LIST
*)GetFirstNode(&ShellInfoObject
.SplitList
.Link
);
874 if (OldStdIn
!= NULL
&& ShellParameters
->StdIn
!= *OldStdIn
) {
875 if ((Split
!= NULL
&& Split
->SplitStdIn
!= ShellParameters
->StdIn
) || Split
== NULL
) {
876 gEfiShellProtocol
->CloseFile(ShellParameters
->StdIn
);
878 ShellParameters
->StdIn
= OldStdIn
==NULL
?NULL
:*OldStdIn
;
880 if (OldStdOut
!= NULL
&& ShellParameters
->StdOut
!= *OldStdOut
) {
881 if ((Split
!= NULL
&& Split
->SplitStdOut
!= ShellParameters
->StdOut
) || Split
== NULL
) {
882 gEfiShellProtocol
->CloseFile(ShellParameters
->StdOut
);
884 ShellParameters
->StdOut
= OldStdOut
==NULL
?NULL
:*OldStdOut
;
886 return (EFI_SUCCESS
);
889 Funcion will replace the current Argc and Argv in the ShellParameters protocol
890 structure by parsing NewCommandLine. The current values are returned to the
893 If OldArgv or OldArgc is NULL then that value is not returned.
895 @param[in,out] ShellParameters Pointer to parameter structure to modify.
896 @param[in] NewCommandLine The new command line to parse and use.
897 @param[out] OldArgv Pointer to old list of parameters.
898 @param[out] OldArgc Pointer to old number of items in Argv list.
900 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
901 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
906 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
907 IN CONST CHAR16
*NewCommandLine
,
908 OUT CHAR16
***OldArgv OPTIONAL
,
909 OUT UINTN
*OldArgc OPTIONAL
912 ASSERT(ShellParameters
!= NULL
);
914 if (OldArgc
!= NULL
) {
915 *OldArgc
= ShellParameters
->Argc
;
917 if (OldArgc
!= NULL
) {
918 *OldArgv
= ShellParameters
->Argv
;
921 return (ParseCommandLineToArgs(NewCommandLine
, &(ShellParameters
->Argv
), &(ShellParameters
->Argc
)));
925 Funcion will replace the current Argc and Argv in the ShellParameters protocol
926 structure with Argv and Argc. The current values are de-allocated and the
927 OldArgv must not be deallocated by the caller.
929 @param[in,out] ShellParameters pointer to parameter structure to modify
930 @param[in] OldArgv pointer to old list of parameters
931 @param[in] OldArgc pointer to old number of items in Argv list
936 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
937 IN CHAR16
***OldArgv
,
942 ASSERT(ShellParameters
!= NULL
);
943 ASSERT(OldArgv
!= NULL
);
944 ASSERT(OldArgc
!= NULL
);
946 if (ShellParameters
->Argv
!= NULL
) {
947 for ( LoopCounter
= 0
948 ; LoopCounter
< ShellParameters
->Argc
951 FreePool(ShellParameters
->Argv
[LoopCounter
]);
953 FreePool(ShellParameters
->Argv
);
955 ShellParameters
->Argv
= *OldArgv
;
957 ShellParameters
->Argc
= *OldArgc
;