]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Application/Shell/ShellParametersProtocol.c
Fix CRLF format
[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) 2013 Hewlett-Packard Development Company, L.P.
6 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include "Shell.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 CopyMem (FullCommandLine, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize);
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 while(Copy[0] == L' ') {
527 Copy++;
528 }
529 if ((TempLocation = StrStr(Copy , L" ")) != NULL) {
530 TempLocation[0] = CHAR_NULL;
531 }
532 }
533
534 if (Copy[0] == CHAR_NULL) {
535 return (NULL);
536 }
537
538 return (Copy);
539 }
540
541 /**
542 Fix a string to only have the environment variable name, removing starting at the first space of whatever is quoted and removing the leading and trailing %.
543
544 @param[in] FileName The filename to start with.
545
546 @retval NULL FileName was invalid.
547 @return The modified FileName.
548 **/
549 CHAR16*
550 EFIAPI
551 FixVarName (
552 IN CHAR16 *FileName
553 )
554 {
555 CHAR16 *Copy;
556 CHAR16 *TempLocation;
557
558 Copy = FileName;
559
560 if (FileName[0] == L'%') {
561 Copy = FileName+1;
562 if ((TempLocation = StrStr(Copy , L"%")) != NULL) {
563 TempLocation[0] = CHAR_NULL;
564 }
565 }
566
567 return (FixFileName(Copy));
568 }
569
570 /**
571 Remove the unicode file tag from the begining of the file buffer since that will not be
572 used by StdIn.
573 **/
574 EFI_STATUS
575 EFIAPI
576 RemoveFileTag(
577 IN SHELL_FILE_HANDLE *Handle
578 )
579 {
580 UINTN CharSize;
581 CHAR16 CharBuffer;
582
583 CharSize = sizeof(CHAR16);
584 CharBuffer = 0;
585 gEfiShellProtocol->ReadFile(*Handle, &CharSize, &CharBuffer);
586 if (CharBuffer != gUnicodeFileTag) {
587 gEfiShellProtocol->SetFilePosition(*Handle, 0);
588 }
589 return (EFI_SUCCESS);
590 }
591
592 /**
593 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
594 structure by parsing NewCommandLine. The current values are returned to the
595 user.
596
597 This will also update the system table.
598
599 @param[in, out] ShellParameters Pointer to parameter structure to modify.
600 @param[in] NewCommandLine The new command line to parse and use.
601 @param[out] OldStdIn Pointer to old StdIn.
602 @param[out] OldStdOut Pointer to old StdOut.
603 @param[out] OldStdErr Pointer to old StdErr.
604 @param[out] SystemTableInfo Pointer to old system table information.
605
606 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
607 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
608 **/
609 EFI_STATUS
610 EFIAPI
611 UpdateStdInStdOutStdErr(
612 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
613 IN CHAR16 *NewCommandLine,
614 OUT SHELL_FILE_HANDLE *OldStdIn,
615 OUT SHELL_FILE_HANDLE *OldStdOut,
616 OUT SHELL_FILE_HANDLE *OldStdErr,
617 OUT SYSTEM_TABLE_INFO *SystemTableInfo
618 )
619 {
620 CHAR16 *CommandLineCopy;
621 CHAR16 *CommandLineWalker;
622 CHAR16 *StdErrFileName;
623 CHAR16 *StdOutFileName;
624 CHAR16 *StdInFileName;
625 CHAR16 *StdInVarName;
626 CHAR16 *StdOutVarName;
627 CHAR16 *StdErrVarName;
628 EFI_STATUS Status;
629 SHELL_FILE_HANDLE TempHandle;
630 UINT64 FileSize;
631 BOOLEAN OutUnicode;
632 BOOLEAN InUnicode;
633 BOOLEAN ErrUnicode;
634 BOOLEAN OutAppend;
635 BOOLEAN ErrAppend;
636 UINTN Size;
637 CHAR16 TagBuffer[2];
638 SPLIT_LIST *Split;
639 CHAR16 *FirstLocation;
640
641 OutUnicode = TRUE;
642 InUnicode = TRUE;
643 ErrUnicode = TRUE;
644 StdInVarName = NULL;
645 StdOutVarName = NULL;
646 StdErrVarName = NULL;
647 StdErrFileName = NULL;
648 StdInFileName = NULL;
649 StdOutFileName = NULL;
650 ErrAppend = FALSE;
651 OutAppend = FALSE;
652 CommandLineCopy = NULL;
653 FirstLocation = NULL;
654
655 if (ShellParameters == NULL || SystemTableInfo == NULL || OldStdIn == NULL || OldStdOut == NULL || OldStdErr == NULL) {
656 return (EFI_INVALID_PARAMETER);
657 }
658
659 SystemTableInfo->ConIn = gST->ConIn;
660 SystemTableInfo->ConInHandle = gST->ConsoleInHandle;
661 SystemTableInfo->ConOut = gST->ConOut;
662 SystemTableInfo->ConOutHandle = gST->ConsoleOutHandle;
663 SystemTableInfo->ErrOut = gST->StdErr;
664 SystemTableInfo->ErrOutHandle = gST->StandardErrorHandle;
665 *OldStdIn = ShellParameters->StdIn;
666 *OldStdOut = ShellParameters->StdOut;
667 *OldStdErr = ShellParameters->StdErr;
668
669 if (NewCommandLine == NULL) {
670 return (EFI_SUCCESS);
671 }
672
673 CommandLineCopy = StrnCatGrow(&CommandLineCopy, NULL, NewCommandLine, 0);
674 if (CommandLineCopy == NULL) {
675 return (EFI_OUT_OF_RESOURCES);
676 }
677 Status = EFI_SUCCESS;
678 Split = NULL;
679 FirstLocation = CommandLineCopy + StrLen(CommandLineCopy);
680
681 StripQuotes(CommandLineCopy);
682
683 if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
684 Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
685 if (Split != NULL && Split->SplitStdIn != NULL) {
686 ShellParameters->StdIn = Split->SplitStdIn;
687 }
688 if (Split != NULL && Split->SplitStdOut != NULL) {
689 ShellParameters->StdOut = Split->SplitStdOut;
690 }
691 }
692
693 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>>v ")) != NULL) {
694 FirstLocation = MIN(CommandLineWalker, FirstLocation);
695 SetMem16(CommandLineWalker, 12, L' ');
696 StdErrVarName = CommandLineWalker += 6;
697 ErrAppend = TRUE;
698 if (StrStr(CommandLineWalker, L" 2>>v ") != NULL) {
699 Status = EFI_NOT_FOUND;
700 }
701 }
702 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>v ")) != NULL) {
703 FirstLocation = MIN(CommandLineWalker, FirstLocation);
704 SetMem16(CommandLineWalker, 12, L' ');
705 StdOutVarName = CommandLineWalker += 6;
706 OutAppend = TRUE;
707 if (StrStr(CommandLineWalker, L" 1>>v ") != NULL) {
708 Status = EFI_NOT_FOUND;
709 }
710 } else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>v ")) != NULL) {
711 FirstLocation = MIN(CommandLineWalker, FirstLocation);
712 SetMem16(CommandLineWalker, 10, L' ');
713 StdOutVarName = CommandLineWalker += 5;
714 OutAppend = TRUE;
715 if (StrStr(CommandLineWalker, L" >>v ") != NULL) {
716 Status = EFI_NOT_FOUND;
717 }
718 } else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >v ")) != NULL) {
719 FirstLocation = MIN(CommandLineWalker, FirstLocation);
720 SetMem16(CommandLineWalker, 8, L' ');
721 StdOutVarName = CommandLineWalker += 4;
722 OutAppend = FALSE;
723 if (StrStr(CommandLineWalker, L" >v ") != NULL) {
724 Status = EFI_NOT_FOUND;
725 }
726 }
727 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>a ")) != NULL) {
728 FirstLocation = MIN(CommandLineWalker, FirstLocation);
729 SetMem16(CommandLineWalker, 12, L' ');
730 StdOutFileName = CommandLineWalker += 6;
731 OutAppend = TRUE;
732 OutUnicode = FALSE;
733 if (StrStr(CommandLineWalker, L" 1>>a ") != NULL) {
734 Status = EFI_NOT_FOUND;
735 }
736 }
737 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>> ")) != NULL) {
738 FirstLocation = MIN(CommandLineWalker, FirstLocation);
739 SetMem16(CommandLineWalker, 10, L' ');
740 if (StdOutFileName != NULL) {
741 Status = EFI_INVALID_PARAMETER;
742 } else {
743 StdOutFileName = CommandLineWalker += 5;
744 OutAppend = TRUE;
745 }
746 if (StrStr(CommandLineWalker, L" 1>> ") != NULL) {
747 Status = EFI_NOT_FOUND;
748 }
749 }
750 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >> ")) != NULL) {
751 FirstLocation = MIN(CommandLineWalker, FirstLocation);
752 SetMem16(CommandLineWalker, 8, L' ');
753 if (StdOutFileName != NULL) {
754 Status = EFI_INVALID_PARAMETER;
755 } else {
756 StdOutFileName = CommandLineWalker += 4;
757 OutAppend = TRUE;
758 }
759 if (StrStr(CommandLineWalker, L" >> ") != NULL) {
760 Status = EFI_NOT_FOUND;
761 }
762 }
763 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>a ")) != NULL) {
764 FirstLocation = MIN(CommandLineWalker, FirstLocation);
765 SetMem16(CommandLineWalker, 10, L' ');
766 if (StdOutFileName != NULL) {
767 Status = EFI_INVALID_PARAMETER;
768 } else {
769 StdOutFileName = CommandLineWalker += 5;
770 OutAppend = TRUE;
771 OutUnicode = FALSE;
772 }
773 if (StrStr(CommandLineWalker, L" >>a ") != NULL) {
774 Status = EFI_NOT_FOUND;
775 }
776 }
777 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>a ")) != NULL) {
778 FirstLocation = MIN(CommandLineWalker, FirstLocation);
779 SetMem16(CommandLineWalker, 10, L' ');
780 if (StdOutFileName != NULL) {
781 Status = EFI_INVALID_PARAMETER;
782 } else {
783 StdOutFileName = CommandLineWalker += 5;
784 OutAppend = FALSE;
785 OutUnicode = FALSE;
786 }
787 if (StrStr(CommandLineWalker, L" 1>a ") != NULL) {
788 Status = EFI_NOT_FOUND;
789 }
790 }
791 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >a ")) != NULL) {
792 FirstLocation = MIN(CommandLineWalker, FirstLocation);
793 SetMem16(CommandLineWalker, 8, L' ');
794 if (StdOutFileName != NULL) {
795 Status = EFI_INVALID_PARAMETER;
796 } else {
797 StdOutFileName = CommandLineWalker += 4;
798 OutAppend = FALSE;
799 OutUnicode = FALSE;
800 }
801 if (StrStr(CommandLineWalker, L" >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, 10, L' ');
808 if (StdErrFileName != NULL) {
809 Status = EFI_INVALID_PARAMETER;
810 } else {
811 StdErrFileName = CommandLineWalker += 5;
812 ErrAppend = TRUE;
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" 2>v ")) != NULL) {
820 FirstLocation = MIN(CommandLineWalker, FirstLocation);
821 SetMem16(CommandLineWalker, 10, L' ');
822 if (StdErrVarName != NULL) {
823 Status = EFI_INVALID_PARAMETER;
824 } else {
825 StdErrVarName = CommandLineWalker += 5;
826 ErrAppend = FALSE;
827 }
828 if (StrStr(CommandLineWalker, L" 2>v ") != NULL) {
829 Status = EFI_NOT_FOUND;
830 }
831 }
832 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>v ")) != NULL) {
833 FirstLocation = MIN(CommandLineWalker, FirstLocation);
834 SetMem16(CommandLineWalker, 10, L' ');
835 if (StdOutVarName != NULL) {
836 Status = EFI_INVALID_PARAMETER;
837 } else {
838 StdOutVarName = CommandLineWalker += 5;
839 OutAppend = FALSE;
840 }
841 if (StrStr(CommandLineWalker, L" 1>v ") != NULL) {
842 Status = EFI_NOT_FOUND;
843 }
844 }
845 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>a ")) != NULL) {
846 FirstLocation = MIN(CommandLineWalker, FirstLocation);
847 SetMem16(CommandLineWalker, 10, L' ');
848 if (StdErrFileName != NULL) {
849 Status = EFI_INVALID_PARAMETER;
850 } else {
851 StdErrFileName = CommandLineWalker += 5;
852 ErrAppend = FALSE;
853 ErrUnicode = FALSE;
854 }
855 if (StrStr(CommandLineWalker, L" 2>a ") != NULL) {
856 Status = EFI_NOT_FOUND;
857 }
858 }
859 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2> ")) != NULL) {
860 FirstLocation = MIN(CommandLineWalker, FirstLocation);
861 SetMem16(CommandLineWalker, 8, L' ');
862 if (StdErrFileName != NULL) {
863 Status = EFI_INVALID_PARAMETER;
864 } else {
865 StdErrFileName = CommandLineWalker += 4;
866 ErrAppend = FALSE;
867 }
868 if (StrStr(CommandLineWalker, L" 2> ") != NULL) {
869 Status = EFI_NOT_FOUND;
870 }
871 }
872
873 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1> ")) != NULL) {
874 FirstLocation = MIN(CommandLineWalker, FirstLocation);
875 SetMem16(CommandLineWalker, 8, L' ');
876 if (StdOutFileName != NULL) {
877 Status = EFI_INVALID_PARAMETER;
878 } else {
879 StdOutFileName = CommandLineWalker += 4;
880 OutAppend = FALSE;
881 }
882 if (StrStr(CommandLineWalker, L" 1> ") != NULL) {
883 Status = EFI_NOT_FOUND;
884 }
885 }
886
887 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" > ")) != NULL) {
888 FirstLocation = MIN(CommandLineWalker, FirstLocation);
889 SetMem16(CommandLineWalker, 6, L' ');
890 if (StdOutFileName != NULL) {
891 Status = EFI_INVALID_PARAMETER;
892 } else {
893 StdOutFileName = CommandLineWalker += 3;
894 OutAppend = FALSE;
895 }
896 if (StrStr(CommandLineWalker, L" > ") != NULL) {
897 Status = EFI_NOT_FOUND;
898 }
899 }
900
901 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" < ")) != NULL) {
902 FirstLocation = MIN(CommandLineWalker, FirstLocation);
903 SetMem16(CommandLineWalker, 6, L' ');
904 if (StdInFileName != NULL) {
905 Status = EFI_INVALID_PARAMETER;
906 } else {
907 StdInFileName = CommandLineWalker += 3;
908 }
909 if (StrStr(CommandLineWalker, L" < ") != NULL) {
910 Status = EFI_NOT_FOUND;
911 }
912 }
913 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <a ")) != NULL) {
914 FirstLocation = MIN(CommandLineWalker, FirstLocation);
915 SetMem16(CommandLineWalker, 8, L' ');
916 if (StdInFileName != NULL) {
917 Status = EFI_INVALID_PARAMETER;
918 } else {
919 StdInFileName = CommandLineWalker += 4;
920 InUnicode = FALSE;
921 }
922 if (StrStr(CommandLineWalker, L" <a ") != NULL) {
923 Status = EFI_NOT_FOUND;
924 }
925 }
926 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <v ")) != NULL) {
927 FirstLocation = MIN(CommandLineWalker, FirstLocation);
928 SetMem16(CommandLineWalker, 8, L' ');
929 if (StdInVarName != NULL) {
930 Status = EFI_INVALID_PARAMETER;
931 } else {
932 StdInVarName = CommandLineWalker += 4;
933 }
934 if (StrStr(CommandLineWalker, L" <v ") != NULL) {
935 Status = EFI_NOT_FOUND;
936 }
937 }
938
939 //
940 // re-populate the string to support any filenames that were in quotes.
941 //
942 StrCpy(CommandLineCopy, NewCommandLine);
943
944 if (FirstLocation != CommandLineCopy + StrLen(CommandLineCopy)
945 && ((UINTN)(FirstLocation - CommandLineCopy) < StrLen(NewCommandLine))
946 ){
947 *(NewCommandLine + (UINTN)(FirstLocation - CommandLineCopy)) = CHAR_NULL;
948 }
949
950 if (!EFI_ERROR(Status)) {
951
952 if (StdErrFileName != NULL) {
953 if ((StdErrFileName = FixFileName(StdErrFileName)) == NULL) {
954 Status = EFI_INVALID_PARAMETER;
955 }
956 }
957 if (StdOutFileName != NULL) {
958 if ((StdOutFileName = FixFileName(StdOutFileName)) == NULL) {
959 Status = EFI_INVALID_PARAMETER;
960 }
961 }
962 if (StdInFileName != NULL) {
963 if ((StdInFileName = FixFileName(StdInFileName)) == NULL) {
964 Status = EFI_INVALID_PARAMETER;
965 }
966 }
967 if (StdErrVarName != NULL) {
968 if ((StdErrVarName = FixVarName(StdErrVarName)) == NULL) {
969 Status = EFI_INVALID_PARAMETER;
970 }
971 }
972 if (StdOutVarName != NULL) {
973 if ((StdOutVarName = FixVarName(StdOutVarName)) == NULL) {
974 Status = EFI_INVALID_PARAMETER;
975 }
976 }
977 if (StdInVarName != NULL) {
978 if ((StdInVarName = FixVarName(StdInVarName)) == NULL) {
979 Status = EFI_INVALID_PARAMETER;
980 }
981 }
982
983 //
984 // Verify not the same and not duplicating something from a split
985 //
986 if (
987 //
988 // Check that no 2 filenames are the same
989 //
990 (StdErrFileName != NULL && StdOutFileName!= NULL && StringNoCaseCompare(&StdErrFileName, &StdOutFileName) == 0)
991 ||(StdErrFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdErrFileName, &StdInFileName ) == 0)
992 ||(StdOutFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdOutFileName, &StdInFileName ) == 0)
993 //
994 // Check that no 2 variable names are the same
995 //
996 ||(StdErrVarName != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdInVarName ) == 0)
997 ||(StdOutVarName != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdOutVarName , &StdInVarName ) == 0)
998 ||(StdErrVarName != NULL && StdOutVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdOutVarName ) == 0)
999 //
1000 // When a split (using | operator) is in place some are not allowed
1001 //
1002 ||(Split != NULL && Split->SplitStdIn != NULL && (StdInVarName != NULL || StdInFileName != NULL))
1003 ||(Split != NULL && Split->SplitStdOut != NULL && (StdOutVarName != NULL || StdOutFileName != NULL))
1004 //
1005 // Check that nothing is trying to be output to 2 locations.
1006 //
1007 ||(StdErrFileName != NULL && StdErrVarName != NULL)
1008 ||(StdOutFileName != NULL && StdOutVarName != NULL)
1009 ||(StdInFileName != NULL && StdInVarName != NULL)
1010 //
1011 // Check for no volatile environment variables
1012 //
1013 ||(StdErrVarName != NULL && !IsVolatileEnv(StdErrVarName))
1014 ||(StdOutVarName != NULL && !IsVolatileEnv(StdOutVarName))
1015 //
1016 // Cant redirect during a reconnect operation.
1017 //
1018 ||(StrStr(NewCommandLine, L"connect -r") != NULL
1019 && (StdOutVarName != NULL || StdOutFileName != NULL || StdErrFileName != NULL || StdErrVarName != NULL))
1020 //
1021 // Check that filetypes (Unicode/Ascii) do not change during an append
1022 //
1023 ||(StdOutFileName != NULL && OutUnicode && OutAppend && (!EFI_ERROR(ShellFileExists(StdOutFileName)) && EFI_ERROR(IsUnicodeFile(StdOutFileName))))
1024 ||(StdErrFileName != NULL && ErrUnicode && ErrAppend && (!EFI_ERROR(ShellFileExists(StdErrFileName)) && EFI_ERROR(IsUnicodeFile(StdErrFileName))))
1025 ||(StdOutFileName != NULL && !OutUnicode && OutAppend && (!EFI_ERROR(ShellFileExists(StdOutFileName)) && !EFI_ERROR(IsUnicodeFile(StdOutFileName))))
1026 ||(StdErrFileName != NULL && !ErrUnicode && ErrAppend && (!EFI_ERROR(ShellFileExists(StdErrFileName)) && !EFI_ERROR(IsUnicodeFile(StdErrFileName))))
1027 ){
1028 Status = EFI_INVALID_PARAMETER;
1029 ShellParameters->StdIn = *OldStdIn;
1030 ShellParameters->StdOut = *OldStdOut;
1031 ShellParameters->StdErr = *OldStdErr;
1032 } else if (!EFI_ERROR(Status)){
1033 //
1034 // Open the Std<Whatever> and we should not have conflicts here...
1035 //
1036
1037 //
1038 // StdErr to a file
1039 //
1040 if (StdErrFileName != NULL) {
1041 if (!ErrAppend) {
1042 //
1043 // delete existing file.
1044 //
1045 ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdErrFileName);
1046 }
1047 Status = ShellOpenFileByName(StdErrFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
1048 if (!ErrAppend && ErrUnicode && !EFI_ERROR(Status)) {
1049 //
1050 // Write out the gUnicodeFileTag
1051 //
1052 Size = sizeof(CHAR16);
1053 TagBuffer[0] = gUnicodeFileTag;
1054 TagBuffer[1] = CHAR_NULL;
1055 ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
1056 }
1057 if (!ErrUnicode && !EFI_ERROR(Status)) {
1058 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1059 ASSERT(TempHandle != NULL);
1060 }
1061 if (!EFI_ERROR(Status)) {
1062 ShellParameters->StdErr = TempHandle;
1063 gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle, gST->StdErr);
1064 }
1065 }
1066
1067 //
1068 // StdOut to a file
1069 //
1070 if (!EFI_ERROR(Status) && StdOutFileName != NULL) {
1071 if (!OutAppend) {
1072 //
1073 // delete existing file.
1074 //
1075 ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdOutFileName);
1076 }
1077 Status = ShellOpenFileByName(StdOutFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
1078 if (TempHandle == NULL) {
1079 Status = EFI_INVALID_PARAMETER;
1080 } else {
1081 if (StrStr(StdOutFileName, L"NUL")==StdOutFileName) {
1082 //no-op
1083 } else if (!OutAppend && OutUnicode && !EFI_ERROR(Status)) {
1084 //
1085 // Write out the gUnicodeFileTag
1086 //
1087 Size = sizeof(CHAR16);
1088 TagBuffer[0] = gUnicodeFileTag;
1089 TagBuffer[1] = CHAR_NULL;
1090 ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
1091 } else if (OutAppend) {
1092 //
1093 // Move to end of file
1094 //
1095 Status = ShellInfoObject.NewEfiShellProtocol->GetFileSize(TempHandle, &FileSize);
1096 if (!EFI_ERROR(Status)) {
1097 Status = ShellInfoObject.NewEfiShellProtocol->SetFilePosition(TempHandle, FileSize);
1098 }
1099 }
1100 if (!OutUnicode && !EFI_ERROR(Status)) {
1101 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1102 ASSERT(TempHandle != NULL);
1103 }
1104 if (!EFI_ERROR(Status)) {
1105 ShellParameters->StdOut = TempHandle;
1106 gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle, gST->ConOut);
1107 }
1108 }
1109 }
1110
1111 //
1112 // StdOut to a var
1113 //
1114 if (!EFI_ERROR(Status) && StdOutVarName != NULL) {
1115 if (!OutAppend) {
1116 //
1117 // delete existing variable.
1118 //
1119 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName, 0, L"");
1120 }
1121 TempHandle = CreateFileInterfaceEnv(StdOutVarName);
1122 ASSERT(TempHandle != NULL);
1123 ShellParameters->StdOut = TempHandle;
1124 gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle, gST->ConOut);
1125 }
1126
1127 //
1128 // StdErr to a var
1129 //
1130 if (!EFI_ERROR(Status) && StdErrVarName != NULL) {
1131 if (!ErrAppend) {
1132 //
1133 // delete existing variable.
1134 //
1135 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName, 0, L"");
1136 }
1137 TempHandle = CreateFileInterfaceEnv(StdErrVarName);
1138 ASSERT(TempHandle != NULL);
1139 ShellParameters->StdErr = TempHandle;
1140 gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle, gST->StdErr);
1141 }
1142
1143 //
1144 // StdIn from a var
1145 //
1146 if (!EFI_ERROR(Status) && StdInVarName != NULL) {
1147 TempHandle = CreateFileInterfaceEnv(StdInVarName);
1148 if (TempHandle == NULL) {
1149 Status = EFI_OUT_OF_RESOURCES;
1150 } else {
1151 if (!InUnicode) {
1152 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1153 }
1154 Size = 0;
1155 if (TempHandle == NULL || ((EFI_FILE_PROTOCOL*)TempHandle)->Read(TempHandle, &Size, NULL) != EFI_BUFFER_TOO_SMALL) {
1156 Status = EFI_INVALID_PARAMETER;
1157 } else {
1158 ShellParameters->StdIn = TempHandle;
1159 gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
1160 }
1161 }
1162 }
1163
1164 //
1165 // StdIn from a file
1166 //
1167 if (!EFI_ERROR(Status) && StdInFileName != NULL) {
1168 Status = ShellOpenFileByName(
1169 StdInFileName,
1170 &TempHandle,
1171 EFI_FILE_MODE_READ,
1172 0);
1173 if (InUnicode) {
1174 //
1175 // Chop off the 0xFEFF if it's there...
1176 //
1177 RemoveFileTag(&TempHandle);
1178 } else if (!EFI_ERROR(Status)) {
1179 //
1180 // Create the ASCII->Unicode conversion layer
1181 //
1182 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1183 }
1184 if (!EFI_ERROR(Status)) {
1185 ShellParameters->StdIn = TempHandle;
1186 gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
1187 }
1188 }
1189 }
1190 }
1191 FreePool(CommandLineCopy);
1192
1193 CalculateEfiHdrCrc(&gST->Hdr);
1194
1195 if (gST->ConIn == NULL ||gST->ConOut == NULL) {
1196 Status = EFI_OUT_OF_RESOURCES;
1197 }
1198
1199 if (Status == EFI_NOT_FOUND) {
1200 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);
1201 } else if (EFI_ERROR(Status)) {
1202 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);
1203 }
1204
1205 return (Status);
1206 }
1207
1208 /**
1209 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
1210 structure with StdIn and StdOut. The current values are de-allocated.
1211
1212 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1213 @param[in] OldStdIn Pointer to old StdIn.
1214 @param[in] OldStdOut Pointer to old StdOut.
1215 @param[in] OldStdErr Pointer to old StdErr.
1216 @param[in] SystemTableInfo Pointer to old system table information.
1217 **/
1218 EFI_STATUS
1219 EFIAPI
1220 RestoreStdInStdOutStdErr (
1221 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1222 IN SHELL_FILE_HANDLE *OldStdIn,
1223 IN SHELL_FILE_HANDLE *OldStdOut,
1224 IN SHELL_FILE_HANDLE *OldStdErr,
1225 IN SYSTEM_TABLE_INFO *SystemTableInfo
1226 )
1227 {
1228 SPLIT_LIST *Split;
1229
1230 if (ShellParameters == NULL
1231 ||OldStdIn == NULL
1232 ||OldStdOut == NULL
1233 ||OldStdErr == NULL
1234 ||SystemTableInfo == NULL) {
1235 return (EFI_INVALID_PARAMETER);
1236 }
1237 if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
1238 Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
1239 } else {
1240 Split = NULL;
1241 }
1242 if (ShellParameters->StdIn != *OldStdIn) {
1243 if ((Split != NULL && Split->SplitStdIn != ShellParameters->StdIn) || Split == NULL) {
1244 gEfiShellProtocol->CloseFile(ShellParameters->StdIn);
1245 }
1246 ShellParameters->StdIn = *OldStdIn;
1247 }
1248 if (ShellParameters->StdOut != *OldStdOut) {
1249 if ((Split != NULL && Split->SplitStdOut != ShellParameters->StdOut) || Split == NULL) {
1250 gEfiShellProtocol->CloseFile(ShellParameters->StdOut);
1251 }
1252 ShellParameters->StdOut = *OldStdOut;
1253 }
1254 if (ShellParameters->StdErr != *OldStdErr) {
1255 gEfiShellProtocol->CloseFile(ShellParameters->StdErr);
1256 ShellParameters->StdErr = *OldStdErr;
1257 }
1258
1259 if (gST->ConIn != SystemTableInfo->ConIn) {
1260 CloseSimpleTextInOnFile(gST->ConIn);
1261 gST->ConIn = SystemTableInfo->ConIn;
1262 gST->ConsoleInHandle = SystemTableInfo->ConInHandle;
1263 }
1264 if (gST->ConOut != SystemTableInfo->ConOut) {
1265 CloseSimpleTextOutOnFile(gST->ConOut);
1266 gST->ConOut = SystemTableInfo->ConOut;
1267 gST->ConsoleOutHandle = SystemTableInfo->ConOutHandle;
1268 }
1269 if (gST->StdErr != SystemTableInfo->ErrOut) {
1270 CloseSimpleTextOutOnFile(gST->StdErr);
1271 gST->StdErr = SystemTableInfo->ErrOut;
1272 gST->StandardErrorHandle = SystemTableInfo->ErrOutHandle;
1273 }
1274
1275 CalculateEfiHdrCrc(&gST->Hdr);
1276
1277 return (EFI_SUCCESS);
1278 }
1279 /**
1280 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1281 structure by parsing NewCommandLine. The current values are returned to the
1282 user.
1283
1284 If OldArgv or OldArgc is NULL then that value is not returned.
1285
1286 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1287 @param[in] NewCommandLine The new command line to parse and use.
1288 @param[out] OldArgv Pointer to old list of parameters.
1289 @param[out] OldArgc Pointer to old number of items in Argv list.
1290
1291 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
1292 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1293 **/
1294 EFI_STATUS
1295 EFIAPI
1296 UpdateArgcArgv(
1297 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1298 IN CONST CHAR16 *NewCommandLine,
1299 OUT CHAR16 ***OldArgv OPTIONAL,
1300 OUT UINTN *OldArgc OPTIONAL
1301 )
1302 {
1303 ASSERT(ShellParameters != NULL);
1304
1305 if (OldArgc != NULL) {
1306 *OldArgc = ShellParameters->Argc;
1307 }
1308 if (OldArgc != NULL) {
1309 *OldArgv = ShellParameters->Argv;
1310 }
1311
1312 return (ParseCommandLineToArgs(NewCommandLine, &(ShellParameters->Argv), &(ShellParameters->Argc)));
1313 }
1314
1315 /**
1316 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1317 structure with Argv and Argc. The current values are de-allocated and the
1318 OldArgv must not be deallocated by the caller.
1319
1320 @param[in, out] ShellParameters pointer to parameter structure to modify
1321 @param[in] OldArgv pointer to old list of parameters
1322 @param[in] OldArgc pointer to old number of items in Argv list
1323 **/
1324 VOID
1325 EFIAPI
1326 RestoreArgcArgv(
1327 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1328 IN CHAR16 ***OldArgv,
1329 IN UINTN *OldArgc
1330 )
1331 {
1332 UINTN LoopCounter;
1333 ASSERT(ShellParameters != NULL);
1334 ASSERT(OldArgv != NULL);
1335 ASSERT(OldArgc != NULL);
1336
1337 if (ShellParameters->Argv != NULL) {
1338 for ( LoopCounter = 0
1339 ; LoopCounter < ShellParameters->Argc
1340 ; LoopCounter++
1341 ){
1342 FreePool(ShellParameters->Argv[LoopCounter]);
1343 }
1344 FreePool(ShellParameters->Argv);
1345 }
1346 ShellParameters->Argv = *OldArgv;
1347 *OldArgv = NULL;
1348 ShellParameters->Argc = *OldArgc;
1349 *OldArgc = 0;
1350 }