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