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