]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Application/Shell/ShellParametersProtocol.c
ShellPkg: Correct 3 places where memory was not being properly released by the shell.
[mirror_edk2.git] / ShellPkg / Application / Shell / ShellParametersProtocol.c
1 /** @file
2 Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,
3 manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
4
5 Copyright (c) 2009 - 2012, 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
10
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.
13
14 **/
15
16 #include "ShellParametersProtocol.h"
17 #include "ConsoleWrappers.h"
18
19 /**
20 return the next parameter from a command line string;
21
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;
25
26 Temp Parameter must be large enough to hold the parameter before calling this
27 function.
28
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.
32
33 **/
34 VOID
35 EFIAPI
36 GetNextParameter(
37 CHAR16 **Walker,
38 CHAR16 **TempParameter
39 )
40 {
41 CHAR16 *NextDelim;
42 CHAR16 *TempLoc;
43
44 ASSERT(Walker != NULL);
45 ASSERT(*Walker != NULL);
46 ASSERT(TempParameter != NULL);
47 ASSERT(*TempParameter != NULL);
48
49 //
50 // make sure we dont have any leading spaces
51 //
52 while ((*Walker)[0] == L' ') {
53 (*Walker)++;
54 }
55
56 //
57 // make sure we still have some params now...
58 //
59 if (StrLen(*Walker) == 0) {
60 ASSERT((*Walker)[0] == CHAR_NULL);
61 *Walker = NULL;
62 return;
63 }
64
65 //
66 // we have a quoted parameter
67 // could be the last parameter, but SHOULD have a trailing quote
68 //
69 if ((*Walker)[0] == L'\"') {
70 NextDelim = NULL;
71 for (TempLoc = *Walker + 1 ; TempLoc != NULL && *TempLoc != CHAR_NULL ; TempLoc++) {
72 if (*TempLoc == L'^' && *(TempLoc+1) == L'\"') {
73 TempLoc++;
74 } else if (*TempLoc == L'\"') {
75 NextDelim = TempLoc;
76 break;
77 }
78 }
79
80 if (NextDelim - ((*Walker)+1) == 0) {
81 //
82 // found ""
83 //
84 StrCpy(*TempParameter, L"");
85 *Walker = NextDelim + 1;
86 } else if (NextDelim != NULL) {
87 StrnCpy(*TempParameter, (*Walker)+1, NextDelim - ((*Walker)+1));
88 *Walker = NextDelim + 1;
89 } else {
90 //
91 // last one... someone forgot the training quote!
92 //
93 StrCpy(*TempParameter, *Walker);
94 *Walker = NULL;
95 }
96 for (TempLoc = *TempParameter ; TempLoc != NULL && *TempLoc != CHAR_NULL ; TempLoc++) {
97 if (*TempLoc == L'^' && *(TempLoc+1) == L'\"') {
98 CopyMem(TempLoc, TempLoc+1, StrSize(TempLoc) - sizeof(TempLoc[0]));
99 }
100 }
101 } else {
102 //
103 // we have a regular parameter (no quote) OR
104 // we have the final parameter (no trailing space)
105 //
106 NextDelim = StrStr((*Walker), L" ");
107 if (NextDelim != NULL) {
108 StrnCpy(*TempParameter, *Walker, NextDelim - (*Walker));
109 (*TempParameter)[NextDelim - (*Walker)] = CHAR_NULL;
110 *Walker = NextDelim+1;
111 } else {
112 //
113 // last one.
114 //
115 StrCpy(*TempParameter, *Walker);
116 *Walker = NULL;
117 }
118 for (NextDelim = *TempParameter ; NextDelim != NULL && *NextDelim != CHAR_NULL ; NextDelim++) {
119 if (*NextDelim == L'^' && *(NextDelim+1) == L'^') {
120 CopyMem(NextDelim, NextDelim+1, StrSize(NextDelim) - sizeof(NextDelim[0]));
121 }
122 }
123 while ((*TempParameter)[StrLen(*TempParameter)-1] == L' ') {
124 (*TempParameter)[StrLen(*TempParameter)-1] = CHAR_NULL;
125 }
126 while ((*TempParameter)[0] == L' ') {
127 CopyMem(*TempParameter, (*TempParameter)+1, StrSize(*TempParameter) - sizeof((*TempParameter)[0]));
128 }
129 }
130 return;
131 }
132
133 /**
134 Function to populate Argc and Argv.
135
136 This function parses the CommandLine and divides it into standard C style Argc/Argv
137 parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space
138 delimited and quote surrounded parameter definition.
139
140 @param[in] CommandLine String of command line to parse
141 @param[in, out] Argv pointer to array of strings; one for each parameter
142 @param[in, out] Argc pointer to number of strings in Argv array
143
144 @return EFI_SUCCESS the operation was sucessful
145 @return EFI_OUT_OF_RESOURCES a memory allocation failed.
146 **/
147 EFI_STATUS
148 EFIAPI
149 ParseCommandLineToArgs(
150 IN CONST CHAR16 *CommandLine,
151 IN OUT CHAR16 ***Argv,
152 IN OUT UINTN *Argc
153 )
154 {
155 UINTN Count;
156 CHAR16 *TempParameter;
157 CHAR16 *Walker;
158 CHAR16 *NewParam;
159 UINTN Size;
160
161 ASSERT(Argc != NULL);
162 ASSERT(Argv != NULL);
163
164 if (CommandLine == NULL || StrLen(CommandLine)==0) {
165 (*Argc) = 0;
166 (*Argv) = NULL;
167 return (EFI_SUCCESS);
168 }
169
170 Size = StrSize(CommandLine);
171 TempParameter = AllocateZeroPool(Size);
172 if (TempParameter == NULL) {
173 return (EFI_OUT_OF_RESOURCES);
174 }
175
176 for ( Count = 0
177 , Walker = (CHAR16*)CommandLine
178 ; Walker != NULL && *Walker != CHAR_NULL
179 ; GetNextParameter(&Walker, &TempParameter)
180 , Count++
181 );
182
183 /* Count = 0;
184 Walker = (CHAR16*)CommandLine;
185 while(Walker != NULL) {
186 GetNextParameter(&Walker, &TempParameter);
187 Count++;
188 }
189 */
190 //
191 // lets allocate the pointer array
192 //
193 (*Argv) = AllocateZeroPool((Count)*sizeof(CHAR16*));
194 if (*Argv == NULL) {
195 SHELL_FREE_NON_NULL(TempParameter);
196 return (EFI_OUT_OF_RESOURCES);
197 }
198
199 *Argc = 0;
200 Walker = (CHAR16*)CommandLine;
201 while(Walker != NULL && *Walker != CHAR_NULL) {
202 SetMem16(TempParameter, Size, CHAR_NULL);
203 GetNextParameter(&Walker, &TempParameter);
204 NewParam = AllocateZeroPool(StrSize(TempParameter));
205 ASSERT(NewParam != NULL);
206 StrCpy(NewParam, TempParameter);
207 ((CHAR16**)(*Argv))[(*Argc)] = NewParam;
208 (*Argc)++;
209 }
210 ASSERT(Count >= (*Argc));
211 SHELL_FREE_NON_NULL(TempParameter);
212 return (EFI_SUCCESS);
213 }
214
215 /**
216 creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
217 installs it on our handle and if there is an existing version of the protocol
218 that one is cached for removal later.
219
220 @param[in, out] NewShellParameters on a successful return, a pointer to pointer
221 to the newly installed interface.
222 @param[in, out] RootShellInstance on a successful return, pointer to boolean.
223 TRUE if this is the root shell instance.
224
225 @retval EFI_SUCCESS the operation completed successfully.
226 @return other the operation failed.
227 @sa ReinstallProtocolInterface
228 @sa InstallProtocolInterface
229 @sa ParseCommandLineToArgs
230 **/
231 EFI_STATUS
232 EFIAPI
233 CreatePopulateInstallShellParametersProtocol (
234 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL **NewShellParameters,
235 IN OUT BOOLEAN *RootShellInstance
236 )
237 {
238 EFI_STATUS Status;
239 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
240 CHAR16 *FullCommandLine;
241 UINTN Size;
242
243 Size = 0;
244 FullCommandLine = NULL;
245 LoadedImage = NULL;
246
247 //
248 // Assert for valid parameters
249 //
250 ASSERT(NewShellParameters != NULL);
251 ASSERT(RootShellInstance != NULL);
252
253 //
254 // See if we have a shell parameters placed on us
255 //
256 Status = gBS->OpenProtocol (
257 gImageHandle,
258 &gEfiShellParametersProtocolGuid,
259 (VOID **) &ShellInfoObject.OldShellParameters,
260 gImageHandle,
261 NULL,
262 EFI_OPEN_PROTOCOL_GET_PROTOCOL
263 );
264 //
265 // if we don't then we must be the root shell (error is expected)
266 //
267 if (EFI_ERROR (Status)) {
268 *RootShellInstance = TRUE;
269 }
270
271 //
272 // Allocate the new structure
273 //
274 *NewShellParameters = AllocateZeroPool(sizeof(EFI_SHELL_PARAMETERS_PROTOCOL));
275 if ((*NewShellParameters) == NULL) {
276 return (EFI_OUT_OF_RESOURCES);
277 }
278
279 //
280 // get loaded image protocol
281 //
282 Status = gBS->OpenProtocol (
283 gImageHandle,
284 &gEfiLoadedImageProtocolGuid,
285 (VOID **) &LoadedImage,
286 gImageHandle,
287 NULL,
288 EFI_OPEN_PROTOCOL_GET_PROTOCOL
289 );
290 ASSERT_EFI_ERROR(Status);
291 //
292 // Build the full command line
293 //
294 Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, &FullCommandLine);
295 if (Status == EFI_BUFFER_TOO_SMALL) {
296 FullCommandLine = AllocateZeroPool(Size + LoadedImage->LoadOptionsSize);
297 Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, &FullCommandLine);
298 }
299 if (Status == EFI_NOT_FOUND) {
300 //
301 // no parameters via environment... ok
302 //
303 } else {
304 if (EFI_ERROR(Status)) {
305 return (Status);
306 }
307 }
308 if (Size == 0 && LoadedImage->LoadOptionsSize != 0) {
309 ASSERT(FullCommandLine == NULL);
310 //
311 // Now we need to include a NULL terminator in the size.
312 //
313 Size = LoadedImage->LoadOptionsSize + sizeof(FullCommandLine[0]);
314 FullCommandLine = AllocateZeroPool(Size);
315 }
316 if (FullCommandLine != NULL) {
317 if (LoadedImage->LoadOptionsSize != 0){
318 StrCpy(FullCommandLine, LoadedImage->LoadOptions);
319 }
320 //
321 // Populate Argc and Argv
322 //
323 Status = ParseCommandLineToArgs(FullCommandLine,
324 &(*NewShellParameters)->Argv,
325 &(*NewShellParameters)->Argc);
326
327 FreePool(FullCommandLine);
328
329 ASSERT_EFI_ERROR(Status);
330 } else {
331 (*NewShellParameters)->Argv = NULL;
332 (*NewShellParameters)->Argc = 0;
333 }
334
335 //
336 // Populate the 3 faked file systems...
337 //
338 if (*RootShellInstance) {
339 (*NewShellParameters)->StdIn = &FileInterfaceStdIn;
340 (*NewShellParameters)->StdOut = &FileInterfaceStdOut;
341 (*NewShellParameters)->StdErr = &FileInterfaceStdErr;
342 Status = gBS->InstallProtocolInterface(&gImageHandle,
343 &gEfiShellParametersProtocolGuid,
344 EFI_NATIVE_INTERFACE,
345 (VOID*)(*NewShellParameters));
346 } else {
347 //
348 // copy from the existing ones
349 //
350 (*NewShellParameters)->StdIn = ShellInfoObject.OldShellParameters->StdIn;
351 (*NewShellParameters)->StdOut = ShellInfoObject.OldShellParameters->StdOut;
352 (*NewShellParameters)->StdErr = ShellInfoObject.OldShellParameters->StdErr;
353 Status = gBS->ReinstallProtocolInterface(gImageHandle,
354 &gEfiShellParametersProtocolGuid,
355 (VOID*)ShellInfoObject.OldShellParameters,
356 (VOID*)(*NewShellParameters));
357 }
358
359 return (Status);
360 }
361
362 /**
363 frees all memory used by createion and installation of shell parameters protocol
364 and if there was an old version installed it will restore that one.
365
366 @param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
367 being cleaned up.
368
369 @retval EFI_SUCCESS the cleanup was successful
370 @return other the cleanup failed
371 @sa ReinstallProtocolInterface
372 @sa UninstallProtocolInterface
373 **/
374 EFI_STATUS
375 EFIAPI
376 CleanUpShellParametersProtocol (
377 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *NewShellParameters
378 )
379 {
380 EFI_STATUS Status;
381 UINTN LoopCounter;
382
383 //
384 // If the old exists we need to restore it
385 //
386 if (ShellInfoObject.OldShellParameters != NULL) {
387 Status = gBS->ReinstallProtocolInterface(gImageHandle,
388 &gEfiShellParametersProtocolGuid,
389 (VOID*)NewShellParameters,
390 (VOID*)ShellInfoObject.OldShellParameters);
391 DEBUG_CODE(ShellInfoObject.OldShellParameters = NULL;);
392 } else {
393 //
394 // No old one, just uninstall us...
395 //
396 Status = gBS->UninstallProtocolInterface(gImageHandle,
397 &gEfiShellParametersProtocolGuid,
398 (VOID*)NewShellParameters);
399 }
400 if (NewShellParameters->Argv != NULL) {
401 for ( LoopCounter = 0
402 ; LoopCounter < NewShellParameters->Argc
403 ; LoopCounter++
404 ){
405 FreePool(NewShellParameters->Argv[LoopCounter]);
406 }
407 FreePool(NewShellParameters->Argv);
408 }
409 FreePool(NewShellParameters);
410 return (Status);
411 }
412
413 /**
414 Determin if a file name represents a unicode file.
415
416 @param[in] FileName Pointer to the filename to open.
417
418 @retval EFI_SUCCESS The file is a unicode file.
419 @return An error upon failure.
420 **/
421 EFI_STATUS
422 EFIAPI
423 IsUnicodeFile(
424 IN CONST CHAR16 *FileName
425 )
426 {
427 SHELL_FILE_HANDLE Handle;
428 EFI_STATUS Status;
429 UINT64 OriginalFilePosition;
430 UINTN CharSize;
431 CHAR16 CharBuffer;
432
433 Status = gEfiShellProtocol->OpenFileByName(FileName, &Handle, EFI_FILE_MODE_READ);
434 if (EFI_ERROR(Status)) {
435 return (Status);
436 }
437 gEfiShellProtocol->GetFilePosition(Handle, &OriginalFilePosition);
438 gEfiShellProtocol->SetFilePosition(Handle, 0);
439 CharSize = sizeof(CHAR16);
440 Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);
441 if (EFI_ERROR(Status) || CharBuffer != gUnicodeFileTag) {
442 Status = EFI_BUFFER_TOO_SMALL;
443 }
444 gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);
445 gEfiShellProtocol->CloseFile(Handle);
446 return (Status);
447 }
448
449 /**
450 Strips out quotes sections of a string.
451
452 All of the characters between quotes is replaced with spaces.
453
454 @param[in, out] TheString A pointer to the string to update.
455 **/
456 VOID
457 EFIAPI
458 StripQuotes (
459 IN OUT CHAR16 *TheString
460 )
461 {
462 BOOLEAN RemoveNow;
463
464 for (RemoveNow = FALSE ; TheString != NULL && *TheString != CHAR_NULL ; TheString++) {
465 if (*TheString == L'^' && *(TheString + 1) == L'\"') {
466 TheString++;
467 } else if (*TheString == L'\"') {
468 RemoveNow = (BOOLEAN)!RemoveNow;
469 } else if (RemoveNow) {
470 *TheString = L' ';
471 }
472 }
473 }
474
475 /**
476 Calcualte the 32-bit CRC in a EFI table using the service provided by the
477 gRuntime service.
478
479 @param Hdr Pointer to an EFI standard header
480
481 **/
482 VOID
483 CalculateEfiHdrCrc (
484 IN OUT EFI_TABLE_HEADER *Hdr
485 )
486 {
487 UINT32 Crc;
488
489 Hdr->CRC32 = 0;
490
491 //
492 // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
493 // Crc will come back as zero if we set it to zero here
494 //
495 Crc = 0;
496 gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);
497 Hdr->CRC32 = Crc;
498 }
499
500 /**
501 Fix a string to only have the file name, removing starting at the first space of whatever is quoted.
502
503 @param[in] FileName The filename to start with.
504
505 @retval NULL FileName was invalid.
506 @return The modified FileName.
507 **/
508 CHAR16*
509 EFIAPI
510 FixFileName (
511 IN CHAR16 *FileName
512 )
513 {
514 CHAR16 *Copy;
515 CHAR16 *TempLocation;
516
517 if (FileName == NULL) {
518 return (NULL);
519 }
520
521 if (FileName[0] == L'\"') {
522 Copy = FileName+1;
523 if ((TempLocation = StrStr(Copy , L"\"")) != NULL) {
524 TempLocation[0] = CHAR_NULL;
525 }
526 } else {
527 Copy = FileName;
528 while(Copy[0] == L' ') {
529 Copy++;
530 }
531 if ((TempLocation = StrStr(Copy , L" ")) != NULL) {
532 TempLocation[0] = CHAR_NULL;
533 }
534 }
535
536 if (Copy[0] == CHAR_NULL) {
537 return (NULL);
538 }
539
540 return (Copy);
541 }
542
543 /**
544 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
545 structure by parsing NewCommandLine. The current values are returned to the
546 user.
547
548 This will also update the system table.
549
550 @param[in, out] ShellParameters Pointer to parameter structure to modify.
551 @param[in] NewCommandLine The new command line to parse and use.
552 @param[out] OldStdIn Pointer to old StdIn.
553 @param[out] OldStdOut Pointer to old StdOut.
554 @param[out] OldStdErr Pointer to old StdErr.
555 @param[out] SystemTableInfo Pointer to old system table information.
556
557 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
558 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
559 **/
560 EFI_STATUS
561 EFIAPI
562 UpdateStdInStdOutStdErr(
563 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
564 IN CHAR16 *NewCommandLine,
565 OUT SHELL_FILE_HANDLE *OldStdIn,
566 OUT SHELL_FILE_HANDLE *OldStdOut,
567 OUT SHELL_FILE_HANDLE *OldStdErr,
568 OUT SYSTEM_TABLE_INFO *SystemTableInfo
569 )
570 {
571 CHAR16 *CommandLineCopy;
572 CHAR16 *CommandLineWalker;
573 CHAR16 *StdErrFileName;
574 CHAR16 *StdOutFileName;
575 CHAR16 *StdInFileName;
576 CHAR16 *StdInVarName;
577 CHAR16 *StdOutVarName;
578 CHAR16 *StdErrVarName;
579 EFI_STATUS Status;
580 SHELL_FILE_HANDLE TempHandle;
581 UINT64 FileSize;
582 BOOLEAN OutUnicode;
583 BOOLEAN InUnicode;
584 BOOLEAN ErrUnicode;
585 BOOLEAN OutAppend;
586 BOOLEAN ErrAppend;
587 UINTN Size;
588 CHAR16 TagBuffer[2];
589 SPLIT_LIST *Split;
590 CHAR16 *FirstLocation;
591
592 OutUnicode = TRUE;
593 InUnicode = TRUE;
594 ErrUnicode = TRUE;
595 StdInVarName = NULL;
596 StdOutVarName = NULL;
597 StdErrVarName = NULL;
598 StdErrFileName = NULL;
599 StdInFileName = NULL;
600 StdOutFileName = NULL;
601 ErrAppend = FALSE;
602 OutAppend = FALSE;
603 CommandLineCopy = NULL;
604 FirstLocation = NULL;
605
606 if (ShellParameters == NULL || SystemTableInfo == NULL || OldStdIn == NULL || OldStdOut == NULL || OldStdErr == NULL) {
607 return (EFI_INVALID_PARAMETER);
608 }
609
610 SystemTableInfo->ConIn = gST->ConIn;
611 SystemTableInfo->ConInHandle = gST->ConsoleInHandle;
612 SystemTableInfo->ConOut = gST->ConOut;
613 SystemTableInfo->ConOutHandle = gST->ConsoleOutHandle;
614 SystemTableInfo->ErrOut = gST->StdErr;
615 SystemTableInfo->ErrOutHandle = gST->StandardErrorHandle;
616 *OldStdIn = ShellParameters->StdIn;
617 *OldStdOut = ShellParameters->StdOut;
618 *OldStdErr = ShellParameters->StdErr;
619
620 if (NewCommandLine == NULL) {
621 return (EFI_SUCCESS);
622 }
623
624 CommandLineCopy = StrnCatGrow(&CommandLineCopy, NULL, NewCommandLine, 0);
625 if (CommandLineCopy == NULL) {
626 return (EFI_OUT_OF_RESOURCES);
627 }
628 Status = EFI_SUCCESS;
629 Split = NULL;
630 FirstLocation = CommandLineCopy + StrLen(CommandLineCopy);
631
632 StripQuotes(CommandLineCopy);
633
634 if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
635 Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
636 if (Split != NULL && Split->SplitStdIn != NULL) {
637 ShellParameters->StdIn = Split->SplitStdIn;
638 }
639 if (Split != NULL && Split->SplitStdOut != NULL) {
640 ShellParameters->StdOut = Split->SplitStdOut;
641 }
642 }
643
644 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>>v ")) != NULL) {
645 FirstLocation = MIN(CommandLineWalker, FirstLocation);
646 SetMem16(CommandLineWalker, 12, L' ');
647 StdErrVarName = CommandLineWalker += 6;
648 ErrAppend = TRUE;
649 if (StrStr(CommandLineWalker, L" 2>>v ") != NULL) {
650 Status = EFI_NOT_FOUND;
651 }
652 }
653 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>v ")) != NULL) {
654 FirstLocation = MIN(CommandLineWalker, FirstLocation);
655 SetMem16(CommandLineWalker, 12, L' ');
656 StdOutVarName = CommandLineWalker += 6;
657 OutAppend = TRUE;
658 if (StrStr(CommandLineWalker, L" 1>>v ") != NULL) {
659 Status = EFI_NOT_FOUND;
660 }
661 } else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>v ")) != NULL) {
662 FirstLocation = MIN(CommandLineWalker, FirstLocation);
663 SetMem16(CommandLineWalker, 10, L' ');
664 StdOutVarName = CommandLineWalker += 5;
665 OutAppend = TRUE;
666 if (StrStr(CommandLineWalker, L" >>v ") != NULL) {
667 Status = EFI_NOT_FOUND;
668 }
669 } else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >v ")) != NULL) {
670 FirstLocation = MIN(CommandLineWalker, FirstLocation);
671 SetMem16(CommandLineWalker, 8, L' ');
672 StdOutVarName = CommandLineWalker += 4;
673 OutAppend = FALSE;
674 if (StrStr(CommandLineWalker, L" >v ") != NULL) {
675 Status = EFI_NOT_FOUND;
676 }
677 }
678 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>a ")) != NULL) {
679 FirstLocation = MIN(CommandLineWalker, FirstLocation);
680 SetMem16(CommandLineWalker, 12, L' ');
681 StdOutFileName = CommandLineWalker += 6;
682 OutAppend = TRUE;
683 OutUnicode = FALSE;
684 if (StrStr(CommandLineWalker, L" 1>>a ") != NULL) {
685 Status = EFI_NOT_FOUND;
686 }
687 }
688 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>> ")) != NULL) {
689 FirstLocation = MIN(CommandLineWalker, FirstLocation);
690 SetMem16(CommandLineWalker, 10, L' ');
691 if (StdOutFileName != NULL) {
692 Status = EFI_INVALID_PARAMETER;
693 } else {
694 StdOutFileName = CommandLineWalker += 5;
695 OutAppend = TRUE;
696 }
697 if (StrStr(CommandLineWalker, L" 1>> ") != NULL) {
698 Status = EFI_NOT_FOUND;
699 }
700 }
701 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >> ")) != NULL) {
702 FirstLocation = MIN(CommandLineWalker, FirstLocation);
703 SetMem16(CommandLineWalker, 8, L' ');
704 if (StdOutFileName != NULL) {
705 Status = EFI_INVALID_PARAMETER;
706 } else {
707 StdOutFileName = CommandLineWalker += 4;
708 OutAppend = TRUE;
709 }
710 if (StrStr(CommandLineWalker, L" >> ") != NULL) {
711 Status = EFI_NOT_FOUND;
712 }
713 }
714 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>a ")) != NULL) {
715 FirstLocation = MIN(CommandLineWalker, FirstLocation);
716 SetMem16(CommandLineWalker, 10, L' ');
717 if (StdOutFileName != NULL) {
718 Status = EFI_INVALID_PARAMETER;
719 } else {
720 StdOutFileName = CommandLineWalker += 5;
721 OutAppend = TRUE;
722 OutUnicode = FALSE;
723 }
724 if (StrStr(CommandLineWalker, L" >>a ") != NULL) {
725 Status = EFI_NOT_FOUND;
726 }
727 }
728 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>a ")) != NULL) {
729 FirstLocation = MIN(CommandLineWalker, FirstLocation);
730 SetMem16(CommandLineWalker, 10, L' ');
731 if (StdOutFileName != NULL) {
732 Status = EFI_INVALID_PARAMETER;
733 } else {
734 StdOutFileName = CommandLineWalker += 5;
735 OutAppend = FALSE;
736 OutUnicode = FALSE;
737 }
738 if (StrStr(CommandLineWalker, L" 1>a ") != NULL) {
739 Status = EFI_NOT_FOUND;
740 }
741 }
742 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >a ")) != NULL) {
743 FirstLocation = MIN(CommandLineWalker, FirstLocation);
744 SetMem16(CommandLineWalker, 8, L' ');
745 if (StdOutFileName != NULL) {
746 Status = EFI_INVALID_PARAMETER;
747 } else {
748 StdOutFileName = CommandLineWalker += 4;
749 OutAppend = FALSE;
750 OutUnicode = FALSE;
751 }
752 if (StrStr(CommandLineWalker, L" >a ") != NULL) {
753 Status = EFI_NOT_FOUND;
754 }
755 }
756 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>> ")) != NULL) {
757 FirstLocation = MIN(CommandLineWalker, FirstLocation);
758 SetMem16(CommandLineWalker, 10, L' ');
759 if (StdErrFileName != NULL) {
760 Status = EFI_INVALID_PARAMETER;
761 } else {
762 StdErrFileName = CommandLineWalker += 5;
763 ErrAppend = TRUE;
764 }
765 if (StrStr(CommandLineWalker, L" 2>> ") != NULL) {
766 Status = EFI_NOT_FOUND;
767 }
768 }
769
770 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>v ")) != NULL) {
771 FirstLocation = MIN(CommandLineWalker, FirstLocation);
772 SetMem16(CommandLineWalker, 10, L' ');
773 if (StdErrVarName != NULL) {
774 Status = EFI_INVALID_PARAMETER;
775 } else {
776 StdErrVarName = CommandLineWalker += 5;
777 ErrAppend = FALSE;
778 }
779 if (StrStr(CommandLineWalker, L" 2>v ") != NULL) {
780 Status = EFI_NOT_FOUND;
781 }
782 }
783 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>v ")) != NULL) {
784 FirstLocation = MIN(CommandLineWalker, FirstLocation);
785 SetMem16(CommandLineWalker, 10, L' ');
786 if (StdOutVarName != NULL) {
787 Status = EFI_INVALID_PARAMETER;
788 } else {
789 StdOutVarName = CommandLineWalker += 5;
790 OutAppend = FALSE;
791 }
792 if (StrStr(CommandLineWalker, L" 1>v ") != NULL) {
793 Status = EFI_NOT_FOUND;
794 }
795 }
796 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>a ")) != NULL) {
797 FirstLocation = MIN(CommandLineWalker, FirstLocation);
798 SetMem16(CommandLineWalker, 10, L' ');
799 if (StdErrFileName != NULL) {
800 Status = EFI_INVALID_PARAMETER;
801 } else {
802 StdErrFileName = CommandLineWalker += 5;
803 ErrAppend = FALSE;
804 ErrUnicode = FALSE;
805 }
806 if (StrStr(CommandLineWalker, L" 2>a ") != NULL) {
807 Status = EFI_NOT_FOUND;
808 }
809 }
810 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2> ")) != NULL) {
811 FirstLocation = MIN(CommandLineWalker, FirstLocation);
812 SetMem16(CommandLineWalker, 8, L' ');
813 if (StdErrFileName != NULL) {
814 Status = EFI_INVALID_PARAMETER;
815 } else {
816 StdErrFileName = CommandLineWalker += 4;
817 ErrAppend = FALSE;
818 }
819 if (StrStr(CommandLineWalker, L" 2> ") != NULL) {
820 Status = EFI_NOT_FOUND;
821 }
822 }
823
824 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1> ")) != NULL) {
825 FirstLocation = MIN(CommandLineWalker, FirstLocation);
826 SetMem16(CommandLineWalker, 8, L' ');
827 if (StdOutFileName != NULL) {
828 Status = EFI_INVALID_PARAMETER;
829 } else {
830 StdOutFileName = CommandLineWalker += 4;
831 OutAppend = FALSE;
832 }
833 if (StrStr(CommandLineWalker, L" 1> ") != NULL) {
834 Status = EFI_NOT_FOUND;
835 }
836 }
837
838 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" > ")) != NULL) {
839 FirstLocation = MIN(CommandLineWalker, FirstLocation);
840 SetMem16(CommandLineWalker, 6, L' ');
841 if (StdOutFileName != NULL) {
842 Status = EFI_INVALID_PARAMETER;
843 } else {
844 StdOutFileName = CommandLineWalker += 3;
845 OutAppend = FALSE;
846 }
847 if (StrStr(CommandLineWalker, L" > ") != NULL) {
848 Status = EFI_NOT_FOUND;
849 }
850 }
851
852 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" < ")) != NULL) {
853 FirstLocation = MIN(CommandLineWalker, FirstLocation);
854 SetMem16(CommandLineWalker, 6, L' ');
855 if (StdInFileName != NULL) {
856 Status = EFI_INVALID_PARAMETER;
857 } else {
858 StdInFileName = CommandLineWalker += 3;
859 }
860 if (StrStr(CommandLineWalker, L" < ") != NULL) {
861 Status = EFI_NOT_FOUND;
862 }
863 }
864 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <a ")) != NULL) {
865 FirstLocation = MIN(CommandLineWalker, FirstLocation);
866 SetMem16(CommandLineWalker, 8, L' ');
867 if (StdInFileName != NULL) {
868 Status = EFI_INVALID_PARAMETER;
869 } else {
870 StdInFileName = CommandLineWalker += 4;
871 InUnicode = FALSE;
872 }
873 if (StrStr(CommandLineWalker, L" <a ") != NULL) {
874 Status = EFI_NOT_FOUND;
875 }
876 }
877 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <v ")) != NULL) {
878 FirstLocation = MIN(CommandLineWalker, FirstLocation);
879 SetMem16(CommandLineWalker, 8, L' ');
880 if (StdInVarName != NULL) {
881 Status = EFI_INVALID_PARAMETER;
882 } else {
883 StdInVarName = CommandLineWalker += 4;
884 }
885 if (StrStr(CommandLineWalker, L" <v ") != NULL) {
886 Status = EFI_NOT_FOUND;
887 }
888 }
889
890 //
891 // re-populate the string to support any filenames that were in quotes.
892 //
893 StrCpy(CommandLineCopy, NewCommandLine);
894
895 if (FirstLocation != CommandLineCopy + StrLen(CommandLineCopy)
896 && ((UINTN)(FirstLocation - CommandLineCopy) < StrLen(NewCommandLine))
897 ){
898 *(NewCommandLine + (UINTN)(FirstLocation - CommandLineCopy)) = CHAR_NULL;
899 }
900
901 if (!EFI_ERROR(Status)) {
902
903 if (StdErrFileName != NULL) {
904 if ((StdErrFileName = FixFileName(StdErrFileName)) == NULL) {
905 Status = EFI_INVALID_PARAMETER;
906 }
907 }
908 if (StdOutFileName != NULL) {
909 if ((StdOutFileName = FixFileName(StdOutFileName)) == NULL) {
910 Status = EFI_INVALID_PARAMETER;
911 }
912 }
913 if (StdInFileName != NULL) {
914 if ((StdInFileName = FixFileName(StdInFileName)) == NULL) {
915 Status = EFI_INVALID_PARAMETER;
916 }
917 }
918 if (StdErrVarName != NULL) {
919 if ((StdErrVarName = FixFileName(StdErrVarName)) == NULL) {
920 Status = EFI_INVALID_PARAMETER;
921 }
922 }
923 if (StdOutVarName != NULL) {
924 if ((StdOutVarName = FixFileName(StdOutVarName)) == NULL) {
925 Status = EFI_INVALID_PARAMETER;
926 }
927 }
928 if (StdInVarName != NULL) {
929 if ((StdInVarName = FixFileName(StdInVarName)) == NULL) {
930 Status = EFI_INVALID_PARAMETER;
931 }
932 }
933
934 //
935 // Verify not the same and not duplicating something from a split
936 //
937 if (
938 //
939 // Check that no 2 filenames are the same
940 //
941 (StdErrFileName != NULL && StdOutFileName!= NULL && StringNoCaseCompare(&StdErrFileName, &StdOutFileName) == 0)
942 ||(StdErrFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdErrFileName, &StdInFileName ) == 0)
943 ||(StdOutFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdOutFileName, &StdInFileName ) == 0)
944 //
945 // Check that no 2 variable names are the same
946 //
947 ||(StdErrVarName != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdInVarName ) == 0)
948 ||(StdOutVarName != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdOutVarName , &StdInVarName ) == 0)
949 ||(StdErrVarName != NULL && StdOutVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdOutVarName ) == 0)
950 //
951 // When a split (using | operator) is in place some are not allowed
952 //
953 ||(Split != NULL && Split->SplitStdIn != NULL && (StdInVarName != NULL || StdInFileName != NULL))
954 ||(Split != NULL && Split->SplitStdOut != NULL && (StdOutVarName != NULL || StdOutFileName != NULL))
955 //
956 // Check that nothing is trying to be output to 2 locations.
957 //
958 ||(StdErrFileName != NULL && StdErrVarName != NULL)
959 ||(StdOutFileName != NULL && StdOutVarName != NULL)
960 ||(StdInFileName != NULL && StdInVarName != NULL)
961 //
962 // Check for no volatile environment variables
963 //
964 ||(StdErrVarName != NULL && !IsVolatileEnv(StdErrVarName))
965 ||(StdOutVarName != NULL && !IsVolatileEnv(StdOutVarName))
966 //
967 // Cant redirect during a reconnect operation.
968 //
969 ||(StrStr(NewCommandLine, L"connect -r") != NULL
970 && (StdOutVarName != NULL || StdOutFileName != NULL || StdErrFileName != NULL || StdErrVarName != NULL))
971 //
972 // Check that filetypes (Unicode/Ascii) do not change during an append
973 //
974 ||(StdOutFileName != NULL && OutUnicode && OutAppend && (!EFI_ERROR(ShellFileExists(StdOutFileName)) && EFI_ERROR(IsUnicodeFile(StdOutFileName))))
975 ||(StdErrFileName != NULL && ErrUnicode && ErrAppend && (!EFI_ERROR(ShellFileExists(StdErrFileName)) && EFI_ERROR(IsUnicodeFile(StdErrFileName))))
976 ||(StdOutFileName != NULL && !OutUnicode && OutAppend && (!EFI_ERROR(ShellFileExists(StdOutFileName)) && !EFI_ERROR(IsUnicodeFile(StdOutFileName))))
977 ||(StdErrFileName != NULL && !ErrUnicode && ErrAppend && (!EFI_ERROR(ShellFileExists(StdErrFileName)) && !EFI_ERROR(IsUnicodeFile(StdErrFileName))))
978 ){
979 Status = EFI_INVALID_PARAMETER;
980 ShellParameters->StdIn = *OldStdIn;
981 ShellParameters->StdOut = *OldStdOut;
982 ShellParameters->StdErr = *OldStdErr;
983 } else if (!EFI_ERROR(Status)){
984 //
985 // Open the Std<Whatever> and we should not have conflicts here...
986 //
987
988 //
989 // StdErr to a file
990 //
991 if (StdErrFileName != NULL) {
992 if (!ErrAppend) {
993 //
994 // delete existing file.
995 //
996 ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdErrFileName);
997 }
998 Status = ShellOpenFileByName(StdErrFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
999 if (!ErrAppend && ErrUnicode && !EFI_ERROR(Status)) {
1000 //
1001 // Write out the gUnicodeFileTag
1002 //
1003 Size = sizeof(CHAR16);
1004 TagBuffer[0] = gUnicodeFileTag;
1005 TagBuffer[1] = CHAR_NULL;
1006 ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
1007 }
1008 if (!ErrUnicode && !EFI_ERROR(Status)) {
1009 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1010 ASSERT(TempHandle != NULL);
1011 }
1012 if (!EFI_ERROR(Status)) {
1013 ShellParameters->StdErr = TempHandle;
1014 gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);
1015 }
1016 }
1017
1018 //
1019 // StdOut to a file
1020 //
1021 if (!EFI_ERROR(Status) && StdOutFileName != NULL) {
1022 if (!OutAppend) {
1023 //
1024 // delete existing file.
1025 //
1026 ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdOutFileName);
1027 }
1028 Status = ShellOpenFileByName(StdOutFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
1029 if (TempHandle == NULL) {
1030 Status = EFI_INVALID_PARAMETER;
1031 } else {
1032 if (StrStr(StdOutFileName, L"NUL")==StdOutFileName) {
1033 //no-op
1034 } else if (!OutAppend && OutUnicode && !EFI_ERROR(Status)) {
1035 //
1036 // Write out the gUnicodeFileTag
1037 //
1038 Size = sizeof(CHAR16);
1039 TagBuffer[0] = gUnicodeFileTag;
1040 TagBuffer[1] = CHAR_NULL;
1041 ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
1042 } else if (OutAppend) {
1043 //
1044 // Move to end of file
1045 //
1046 Status = ShellInfoObject.NewEfiShellProtocol->GetFileSize(TempHandle, &FileSize);
1047 if (!EFI_ERROR(Status)) {
1048 Status = ShellInfoObject.NewEfiShellProtocol->SetFilePosition(TempHandle, FileSize);
1049 }
1050 }
1051 if (!OutUnicode && !EFI_ERROR(Status)) {
1052 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1053 ASSERT(TempHandle != NULL);
1054 }
1055 if (!EFI_ERROR(Status)) {
1056 ShellParameters->StdOut = TempHandle;
1057 gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);
1058 }
1059 }
1060 }
1061
1062 //
1063 // StdOut to a var
1064 //
1065 if (!EFI_ERROR(Status) && StdOutVarName != NULL) {
1066 if (!OutAppend) {
1067 //
1068 // delete existing variable.
1069 //
1070 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName, 0, L"");
1071 }
1072 TempHandle = CreateFileInterfaceEnv(StdOutVarName);
1073 ASSERT(TempHandle != NULL);
1074 ShellParameters->StdOut = TempHandle;
1075 gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);
1076 }
1077
1078 //
1079 // StdErr to a var
1080 //
1081 if (!EFI_ERROR(Status) && StdErrVarName != NULL) {
1082 if (!ErrAppend) {
1083 //
1084 // delete existing variable.
1085 //
1086 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName, 0, L"");
1087 }
1088 TempHandle = CreateFileInterfaceEnv(StdErrVarName);
1089 ASSERT(TempHandle != NULL);
1090 ShellParameters->StdErr = TempHandle;
1091 gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);
1092 }
1093
1094 //
1095 // StdIn from a var
1096 //
1097 if (!EFI_ERROR(Status) && StdInVarName != NULL) {
1098 TempHandle = CreateFileInterfaceEnv(StdInVarName);
1099 if (TempHandle == NULL) {
1100 Status = EFI_OUT_OF_RESOURCES;
1101 } else {
1102 if (!InUnicode) {
1103 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1104 }
1105 Size = 0;
1106 if (TempHandle == NULL || ((EFI_FILE_PROTOCOL*)TempHandle)->Read(TempHandle, &Size, NULL) != EFI_BUFFER_TOO_SMALL) {
1107 Status = EFI_INVALID_PARAMETER;
1108 } else {
1109 ShellParameters->StdIn = TempHandle;
1110 gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
1111 }
1112 }
1113 }
1114
1115 //
1116 // StdIn from a file
1117 //
1118 if (!EFI_ERROR(Status) && StdInFileName != NULL) {
1119 Status = ShellOpenFileByName(
1120 StdInFileName,
1121 &TempHandle,
1122 EFI_FILE_MODE_READ,
1123 0);
1124 if (!InUnicode && !EFI_ERROR(Status)) {
1125 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1126 }
1127 if (!EFI_ERROR(Status)) {
1128 ShellParameters->StdIn = TempHandle;
1129 gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
1130 }
1131 }
1132 }
1133 }
1134 FreePool(CommandLineCopy);
1135
1136 CalculateEfiHdrCrc(&gST->Hdr);
1137
1138 if (gST->ConIn == NULL ||gST->ConOut == NULL) {
1139 return (EFI_OUT_OF_RESOURCES);
1140 }
1141 return (Status);
1142 }
1143
1144 /**
1145 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
1146 structure with StdIn and StdOut. The current values are de-allocated.
1147
1148 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1149 @param[in] OldStdIn Pointer to old StdIn.
1150 @param[in] OldStdOut Pointer to old StdOut.
1151 @param[in] OldStdErr Pointer to old StdErr.
1152 @param[in] SystemTableInfo Pointer to old system table information.
1153 **/
1154 EFI_STATUS
1155 EFIAPI
1156 RestoreStdInStdOutStdErr (
1157 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1158 IN SHELL_FILE_HANDLE *OldStdIn,
1159 IN SHELL_FILE_HANDLE *OldStdOut,
1160 IN SHELL_FILE_HANDLE *OldStdErr,
1161 IN SYSTEM_TABLE_INFO *SystemTableInfo
1162 )
1163 {
1164 SPLIT_LIST *Split;
1165
1166 if (ShellParameters == NULL
1167 ||OldStdIn == NULL
1168 ||OldStdOut == NULL
1169 ||OldStdErr == NULL
1170 ||SystemTableInfo == NULL) {
1171 return (EFI_INVALID_PARAMETER);
1172 }
1173 if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
1174 Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
1175 } else {
1176 Split = NULL;
1177 }
1178 if (ShellParameters->StdIn != *OldStdIn) {
1179 if ((Split != NULL && Split->SplitStdIn != ShellParameters->StdIn) || Split == NULL) {
1180 gEfiShellProtocol->CloseFile(ShellParameters->StdIn);
1181 }
1182 ShellParameters->StdIn = *OldStdIn;
1183 }
1184 if (ShellParameters->StdOut != *OldStdOut) {
1185 if ((Split != NULL && Split->SplitStdOut != ShellParameters->StdOut) || Split == NULL) {
1186 gEfiShellProtocol->CloseFile(ShellParameters->StdOut);
1187 }
1188 ShellParameters->StdOut = *OldStdOut;
1189 }
1190 if (ShellParameters->StdErr != *OldStdErr) {
1191 gEfiShellProtocol->CloseFile(ShellParameters->StdErr);
1192 ShellParameters->StdErr = *OldStdErr;
1193 }
1194
1195 if (gST->ConIn != SystemTableInfo->ConIn) {
1196 CloseSimpleTextInOnFile(gST->ConIn);
1197 gST->ConIn = SystemTableInfo->ConIn;
1198 gST->ConsoleInHandle = SystemTableInfo->ConInHandle;
1199 }
1200 if (gST->ConOut != SystemTableInfo->ConOut) {
1201 CloseSimpleTextOutOnFile(gST->ConOut);
1202 gST->ConOut = SystemTableInfo->ConOut;
1203 gST->ConsoleOutHandle = SystemTableInfo->ConOutHandle;
1204 }
1205 if (gST->StdErr != SystemTableInfo->ErrOut) {
1206 CloseSimpleTextOutOnFile(gST->StdErr);
1207 gST->StdErr = SystemTableInfo->ErrOut;
1208 gST->StandardErrorHandle = SystemTableInfo->ErrOutHandle;
1209 }
1210
1211 CalculateEfiHdrCrc(&gST->Hdr);
1212
1213 return (EFI_SUCCESS);
1214 }
1215 /**
1216 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1217 structure by parsing NewCommandLine. The current values are returned to the
1218 user.
1219
1220 If OldArgv or OldArgc is NULL then that value is not returned.
1221
1222 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1223 @param[in] NewCommandLine The new command line to parse and use.
1224 @param[out] OldArgv Pointer to old list of parameters.
1225 @param[out] OldArgc Pointer to old number of items in Argv list.
1226
1227 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
1228 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1229 **/
1230 EFI_STATUS
1231 EFIAPI
1232 UpdateArgcArgv(
1233 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1234 IN CONST CHAR16 *NewCommandLine,
1235 OUT CHAR16 ***OldArgv OPTIONAL,
1236 OUT UINTN *OldArgc OPTIONAL
1237 )
1238 {
1239 ASSERT(ShellParameters != NULL);
1240
1241 if (OldArgc != NULL) {
1242 *OldArgc = ShellParameters->Argc;
1243 }
1244 if (OldArgc != NULL) {
1245 *OldArgv = ShellParameters->Argv;
1246 }
1247
1248 return (ParseCommandLineToArgs(NewCommandLine, &(ShellParameters->Argv), &(ShellParameters->Argc)));
1249 }
1250
1251 /**
1252 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1253 structure with Argv and Argc. The current values are de-allocated and the
1254 OldArgv must not be deallocated by the caller.
1255
1256 @param[in, out] ShellParameters pointer to parameter structure to modify
1257 @param[in] OldArgv pointer to old list of parameters
1258 @param[in] OldArgc pointer to old number of items in Argv list
1259 **/
1260 VOID
1261 EFIAPI
1262 RestoreArgcArgv(
1263 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1264 IN CHAR16 ***OldArgv,
1265 IN UINTN *OldArgc
1266 )
1267 {
1268 UINTN LoopCounter;
1269 ASSERT(ShellParameters != NULL);
1270 ASSERT(OldArgv != NULL);
1271 ASSERT(OldArgc != NULL);
1272
1273 if (ShellParameters->Argv != NULL) {
1274 for ( LoopCounter = 0
1275 ; LoopCounter < ShellParameters->Argc
1276 ; LoopCounter++
1277 ){
1278 FreePool(ShellParameters->Argv[LoopCounter]);
1279 }
1280 FreePool(ShellParameters->Argv);
1281 }
1282 ShellParameters->Argv = *OldArgv;
1283 *OldArgv = NULL;
1284 ShellParameters->Argc = *OldArgc;
1285 *OldArgc = 0;
1286 }