]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Application/Shell/ShellParametersProtocol.c
ShellPkg: Add checking for memory allocation and pointer returns from functions.
[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 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
500 structure by parsing NewCommandLine. The current values are returned to the
501 user.
502
503 This will also update the system table.
504
505 @param[in, out] ShellParameters Pointer to parameter structure to modify.
506 @param[in] NewCommandLine The new command line to parse and use.
507 @param[out] OldStdIn Pointer to old StdIn.
508 @param[out] OldStdOut Pointer to old StdOut.
509 @param[out] OldStdErr Pointer to old StdErr.
510 @param[out] SystemTableInfo Pointer to old system table information.
511
512 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
513 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
514 **/
515 EFI_STATUS
516 EFIAPI
517 UpdateStdInStdOutStdErr(
518 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
519 IN CHAR16 *NewCommandLine,
520 OUT SHELL_FILE_HANDLE *OldStdIn,
521 OUT SHELL_FILE_HANDLE *OldStdOut,
522 OUT SHELL_FILE_HANDLE *OldStdErr,
523 OUT SYSTEM_TABLE_INFO *SystemTableInfo
524 )
525 {
526 CHAR16 *CommandLineCopy;
527 CHAR16 *CommandLineWalker;
528 CHAR16 *StdErrFileName;
529 CHAR16 *StdOutFileName;
530 CHAR16 *StdInFileName;
531 CHAR16 *StdInVarName;
532 CHAR16 *StdOutVarName;
533 CHAR16 *StdErrVarName;
534 EFI_STATUS Status;
535 SHELL_FILE_HANDLE TempHandle;
536 UINT64 FileSize;
537 BOOLEAN OutUnicode;
538 BOOLEAN InUnicode;
539 BOOLEAN ErrUnicode;
540 BOOLEAN OutAppend;
541 BOOLEAN ErrAppend;
542 UINTN Size;
543 CHAR16 TagBuffer[2];
544 SPLIT_LIST *Split;
545 CHAR16 *FirstLocation;
546
547 OutUnicode = TRUE;
548 InUnicode = TRUE;
549 ErrUnicode = TRUE;
550 StdInVarName = NULL;
551 StdOutVarName = NULL;
552 StdErrVarName = NULL;
553 StdErrFileName = NULL;
554 StdInFileName = NULL;
555 StdOutFileName = NULL;
556 ErrAppend = FALSE;
557 OutAppend = FALSE;
558 CommandLineCopy = NULL;
559 FirstLocation = NULL;
560
561 if (ShellParameters == NULL || SystemTableInfo == NULL || OldStdIn == NULL || OldStdOut == NULL || OldStdErr == NULL) {
562 return (EFI_INVALID_PARAMETER);
563 }
564
565 SystemTableInfo->ConIn = gST->ConIn;
566 SystemTableInfo->ConInHandle = gST->ConsoleInHandle;
567 SystemTableInfo->ConOut = gST->ConOut;
568 SystemTableInfo->ConOutHandle = gST->ConsoleOutHandle;
569 SystemTableInfo->ConErr = gST->StdErr;
570 SystemTableInfo->ConErrHandle = gST->StandardErrorHandle;
571 *OldStdIn = ShellParameters->StdIn;
572 *OldStdOut = ShellParameters->StdOut;
573 *OldStdErr = ShellParameters->StdErr;
574
575 if (NewCommandLine == NULL) {
576 return (EFI_SUCCESS);
577 }
578
579 CommandLineCopy = StrnCatGrow(&CommandLineCopy, NULL, NewCommandLine, 0);
580 if (CommandLineCopy == NULL) {
581 return (EFI_OUT_OF_RESOURCES);
582 }
583 Status = EFI_SUCCESS;
584 Split = NULL;
585 FirstLocation = CommandLineCopy + StrLen(CommandLineCopy);
586
587 StripQuotes(CommandLineCopy);
588
589 if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
590 Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
591 if (Split != NULL && Split->SplitStdIn != NULL) {
592 ShellParameters->StdIn = Split->SplitStdIn;
593 }
594 if (Split != NULL && Split->SplitStdOut != NULL) {
595 ShellParameters->StdOut = Split->SplitStdOut;
596 }
597 }
598
599 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>>v ")) != NULL) {
600 FirstLocation = MIN(CommandLineWalker, FirstLocation);
601 SetMem16(CommandLineWalker, 12, L' ');
602 StdErrVarName = CommandLineWalker += 6;
603 ErrAppend = TRUE;
604 if (StrStr(CommandLineWalker, L" 2>>v ") != NULL) {
605 Status = EFI_NOT_FOUND;
606 }
607 }
608 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>v ")) != NULL) {
609 FirstLocation = MIN(CommandLineWalker, FirstLocation);
610 SetMem16(CommandLineWalker, 12, L' ');
611 StdOutVarName = CommandLineWalker += 6;
612 OutAppend = TRUE;
613 if (StrStr(CommandLineWalker, L" 1>>v ") != NULL) {
614 Status = EFI_NOT_FOUND;
615 }
616 } else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>v ")) != NULL) {
617 FirstLocation = MIN(CommandLineWalker, FirstLocation);
618 SetMem16(CommandLineWalker, 10, L' ');
619 StdOutVarName = CommandLineWalker += 5;
620 OutAppend = TRUE;
621 if (StrStr(CommandLineWalker, L" >>v ") != NULL) {
622 Status = EFI_NOT_FOUND;
623 }
624 } else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >v ")) != NULL) {
625 FirstLocation = MIN(CommandLineWalker, FirstLocation);
626 SetMem16(CommandLineWalker, 8, L' ');
627 StdOutVarName = CommandLineWalker += 4;
628 OutAppend = FALSE;
629 if (StrStr(CommandLineWalker, L" >v ") != NULL) {
630 Status = EFI_NOT_FOUND;
631 }
632 }
633 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>a ")) != NULL) {
634 FirstLocation = MIN(CommandLineWalker, FirstLocation);
635 SetMem16(CommandLineWalker, 12, L' ');
636 StdOutFileName = CommandLineWalker += 6;
637 OutAppend = TRUE;
638 OutUnicode = FALSE;
639 if (StrStr(CommandLineWalker, L" 1>>a ") != NULL) {
640 Status = EFI_NOT_FOUND;
641 }
642 }
643 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>> ")) != NULL) {
644 FirstLocation = MIN(CommandLineWalker, FirstLocation);
645 SetMem16(CommandLineWalker, 10, L' ');
646 if (StdOutFileName != NULL) {
647 Status = EFI_INVALID_PARAMETER;
648 } else {
649 StdOutFileName = CommandLineWalker += 5;
650 OutAppend = TRUE;
651 }
652 if (StrStr(CommandLineWalker, L" 1>> ") != NULL) {
653 Status = EFI_NOT_FOUND;
654 }
655 }
656 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >> ")) != NULL) {
657 FirstLocation = MIN(CommandLineWalker, FirstLocation);
658 SetMem16(CommandLineWalker, 8, L' ');
659 if (StdOutFileName != NULL) {
660 Status = EFI_INVALID_PARAMETER;
661 } else {
662 StdOutFileName = CommandLineWalker += 4;
663 OutAppend = TRUE;
664 }
665 if (StrStr(CommandLineWalker, L" >> ") != NULL) {
666 Status = EFI_NOT_FOUND;
667 }
668 }
669 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>a ")) != NULL) {
670 FirstLocation = MIN(CommandLineWalker, FirstLocation);
671 SetMem16(CommandLineWalker, 10, L' ');
672 if (StdOutFileName != NULL) {
673 Status = EFI_INVALID_PARAMETER;
674 } else {
675 StdOutFileName = CommandLineWalker += 5;
676 OutAppend = TRUE;
677 OutUnicode = FALSE;
678 }
679 if (StrStr(CommandLineWalker, L" >>a ") != NULL) {
680 Status = EFI_NOT_FOUND;
681 }
682 }
683 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>a ")) != 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 = FALSE;
691 OutUnicode = FALSE;
692 }
693 if (StrStr(CommandLineWalker, L" 1>a ") != NULL) {
694 Status = EFI_NOT_FOUND;
695 }
696 }
697 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >a ")) != NULL) {
698 FirstLocation = MIN(CommandLineWalker, FirstLocation);
699 SetMem16(CommandLineWalker, 8, L' ');
700 if (StdOutFileName != NULL) {
701 Status = EFI_INVALID_PARAMETER;
702 } else {
703 StdOutFileName = CommandLineWalker += 4;
704 OutAppend = FALSE;
705 OutUnicode = FALSE;
706 }
707 if (StrStr(CommandLineWalker, L" >a ") != NULL) {
708 Status = EFI_NOT_FOUND;
709 }
710 }
711 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>> ")) != NULL) {
712 FirstLocation = MIN(CommandLineWalker, FirstLocation);
713 SetMem16(CommandLineWalker, 10, L' ');
714 if (StdErrFileName != NULL) {
715 Status = EFI_INVALID_PARAMETER;
716 } else {
717 StdErrFileName = CommandLineWalker += 5;
718 ErrAppend = TRUE;
719 }
720 if (StrStr(CommandLineWalker, L" 2>> ") != NULL) {
721 Status = EFI_NOT_FOUND;
722 }
723 }
724
725 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>v ")) != NULL) {
726 FirstLocation = MIN(CommandLineWalker, FirstLocation);
727 SetMem16(CommandLineWalker, 10, L' ');
728 if (StdErrVarName != NULL) {
729 Status = EFI_INVALID_PARAMETER;
730 } else {
731 StdErrVarName = CommandLineWalker += 5;
732 ErrAppend = FALSE;
733 }
734 if (StrStr(CommandLineWalker, L" 2>v ") != NULL) {
735 Status = EFI_NOT_FOUND;
736 }
737 }
738 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>v ")) != NULL) {
739 FirstLocation = MIN(CommandLineWalker, FirstLocation);
740 SetMem16(CommandLineWalker, 10, L' ');
741 if (StdOutVarName != NULL) {
742 Status = EFI_INVALID_PARAMETER;
743 } else {
744 StdOutVarName = CommandLineWalker += 5;
745 OutAppend = FALSE;
746 }
747 if (StrStr(CommandLineWalker, L" 1>v ") != NULL) {
748 Status = EFI_NOT_FOUND;
749 }
750 }
751 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>a ")) != 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 = FALSE;
759 ErrUnicode = FALSE;
760 }
761 if (StrStr(CommandLineWalker, L" 2>a ") != NULL) {
762 Status = EFI_NOT_FOUND;
763 }
764 }
765 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2> ")) != NULL) {
766 FirstLocation = MIN(CommandLineWalker, FirstLocation);
767 SetMem16(CommandLineWalker, 8, L' ');
768 if (StdErrFileName != NULL) {
769 Status = EFI_INVALID_PARAMETER;
770 } else {
771 StdErrFileName = CommandLineWalker += 4;
772 ErrAppend = FALSE;
773 }
774 if (StrStr(CommandLineWalker, L" 2> ") != NULL) {
775 Status = EFI_NOT_FOUND;
776 }
777 }
778
779 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1> ")) != NULL) {
780 FirstLocation = MIN(CommandLineWalker, FirstLocation);
781 SetMem16(CommandLineWalker, 8, L' ');
782 if (StdOutFileName != NULL) {
783 Status = EFI_INVALID_PARAMETER;
784 } else {
785 StdOutFileName = CommandLineWalker += 4;
786 OutAppend = FALSE;
787 }
788 if (StrStr(CommandLineWalker, L" 1> ") != NULL) {
789 Status = EFI_NOT_FOUND;
790 }
791 }
792
793 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" > ")) != NULL) {
794 FirstLocation = MIN(CommandLineWalker, FirstLocation);
795 SetMem16(CommandLineWalker, 6, L' ');
796 if (StdOutFileName != NULL) {
797 Status = EFI_INVALID_PARAMETER;
798 } else {
799 StdOutFileName = CommandLineWalker += 3;
800 OutAppend = FALSE;
801 }
802 if (StrStr(CommandLineWalker, L" > ") != NULL) {
803 Status = EFI_NOT_FOUND;
804 }
805 }
806
807 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" < ")) != NULL) {
808 FirstLocation = MIN(CommandLineWalker, FirstLocation);
809 SetMem16(CommandLineWalker, 6, L' ');
810 if (StdInFileName != NULL) {
811 Status = EFI_INVALID_PARAMETER;
812 } else {
813 StdInFileName = CommandLineWalker += 3;
814 }
815 if (StrStr(CommandLineWalker, L" < ") != NULL) {
816 Status = EFI_NOT_FOUND;
817 }
818 }
819 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <a ")) != NULL) {
820 FirstLocation = MIN(CommandLineWalker, FirstLocation);
821 SetMem16(CommandLineWalker, 8, L' ');
822 if (StdInFileName != NULL) {
823 Status = EFI_INVALID_PARAMETER;
824 } else {
825 StdInFileName = CommandLineWalker += 4;
826 InUnicode = FALSE;
827 }
828 if (StrStr(CommandLineWalker, L" <a ") != NULL) {
829 Status = EFI_NOT_FOUND;
830 }
831 }
832 if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <v ")) != NULL) {
833 FirstLocation = MIN(CommandLineWalker, FirstLocation);
834 SetMem16(CommandLineWalker, 8, L' ');
835 if (StdInVarName != NULL) {
836 Status = EFI_INVALID_PARAMETER;
837 } else {
838 StdInVarName = CommandLineWalker += 4;
839 }
840 if (StrStr(CommandLineWalker, L" <v ") != NULL) {
841 Status = EFI_NOT_FOUND;
842 }
843 }
844
845 if (FirstLocation != CommandLineCopy + StrLen(CommandLineCopy)
846 && ((UINTN)(FirstLocation - CommandLineCopy) < StrLen(NewCommandLine))
847 ){
848 *(NewCommandLine + (UINTN)(FirstLocation - CommandLineCopy)) = CHAR_NULL;
849 }
850
851 if (!EFI_ERROR(Status)) {
852 if (StdErrFileName != NULL && (CommandLineWalker = StrStr(StdErrFileName, L" ")) != NULL) {
853 CommandLineWalker[0] = CHAR_NULL;
854 }
855 if (StdOutFileName != NULL && (CommandLineWalker = StrStr(StdOutFileName, L" ")) != NULL) {
856 CommandLineWalker[0] = CHAR_NULL;
857 }
858 if (StdInFileName != NULL && (CommandLineWalker = StrStr(StdInFileName , L" ")) != NULL) {
859 CommandLineWalker[0] = CHAR_NULL;
860 }
861 if (StdErrVarName != NULL && (CommandLineWalker = StrStr(StdErrVarName , L" ")) != NULL) {
862 CommandLineWalker[0] = CHAR_NULL;
863 }
864 if (StdOutVarName != NULL && (CommandLineWalker = StrStr(StdOutVarName , L" ")) != NULL) {
865 CommandLineWalker[0] = CHAR_NULL;
866 }
867 if (StdInVarName != NULL && (CommandLineWalker = StrStr(StdInVarName , L" ")) != NULL) {
868 CommandLineWalker[0] = CHAR_NULL;
869 }
870
871 //
872 // Verify not the same and not duplicating something from a split
873 //
874 if (
875 //
876 // Check that no 2 filenames are the same
877 //
878 (StdErrFileName != NULL && StdOutFileName!= NULL && StringNoCaseCompare(&StdErrFileName, &StdOutFileName) == 0)
879 ||(StdErrFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdErrFileName, &StdInFileName ) == 0)
880 ||(StdOutFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdOutFileName, &StdInFileName ) == 0)
881 //
882 // Check that no 2 variable names are the same
883 //
884 ||(StdErrVarName != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdInVarName ) == 0)
885 ||(StdOutVarName != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdOutVarName , &StdInVarName ) == 0)
886 ||(StdErrVarName != NULL && StdOutVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdOutVarName ) == 0)
887 //
888 // When a split (using | operator) is in place some are not allowed
889 //
890 ||(Split != NULL && Split->SplitStdIn != NULL && (StdInVarName != NULL || StdInFileName != NULL))
891 ||(Split != NULL && Split->SplitStdOut != NULL && (StdOutVarName != NULL || StdOutFileName != NULL))
892 //
893 // Check that nothing is trying to be output to 2 locations.
894 //
895 ||(StdErrFileName != NULL && StdErrVarName != NULL)
896 ||(StdOutFileName != NULL && StdOutVarName != NULL)
897 ||(StdInFileName != NULL && StdInVarName != NULL)
898 //
899 // Check for no volatile environment variables
900 //
901 ||(StdErrVarName != NULL && !IsVolatileEnv(StdErrVarName))
902 ||(StdOutVarName != NULL && !IsVolatileEnv(StdOutVarName))
903 //
904 // Cant redirect during a reconnect operation.
905 //
906 ||(StrStr(NewCommandLine, L"connect -r") != NULL
907 && (StdOutVarName != NULL || StdOutFileName != NULL || StdErrFileName != NULL || StdErrVarName != NULL))
908 //
909 // Check that filetypes (Unicode/Ascii) do not change during an append
910 //
911 ||(StdOutFileName != NULL && OutUnicode && OutAppend && (!EFI_ERROR(ShellFileExists(StdOutFileName)) && EFI_ERROR(IsUnicodeFile(StdOutFileName))))
912 ||(StdErrFileName != NULL && ErrUnicode && ErrAppend && (!EFI_ERROR(ShellFileExists(StdErrFileName)) && EFI_ERROR(IsUnicodeFile(StdErrFileName))))
913 ||(StdOutFileName != NULL && !OutUnicode && OutAppend && (!EFI_ERROR(ShellFileExists(StdOutFileName)) && !EFI_ERROR(IsUnicodeFile(StdOutFileName))))
914 ||(StdErrFileName != NULL && !ErrUnicode && ErrAppend && (!EFI_ERROR(ShellFileExists(StdErrFileName)) && !EFI_ERROR(IsUnicodeFile(StdErrFileName))))
915 ){
916 Status = EFI_INVALID_PARAMETER;
917 ShellParameters->StdIn = *OldStdIn;
918 ShellParameters->StdOut = *OldStdOut;
919 ShellParameters->StdErr = *OldStdErr;
920 } else if (!EFI_ERROR(Status)){
921 //
922 // Open the Std<Whatever> and we should not have conflicts here...
923 //
924
925 //
926 // StdErr to a file
927 //
928 if (StdErrFileName != NULL) {
929 if (!ErrAppend) {
930 //
931 // delete existing file.
932 //
933 ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdErrFileName);
934 }
935 Status = ShellOpenFileByName(StdErrFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
936 if (!ErrAppend && ErrUnicode && !EFI_ERROR(Status)) {
937 //
938 // Write out the gUnicodeFileTag
939 //
940 Size = sizeof(CHAR16);
941 TagBuffer[0] = gUnicodeFileTag;
942 TagBuffer[1] = CHAR_NULL;
943 ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
944 }
945 if (!ErrUnicode && !EFI_ERROR(Status)) {
946 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
947 ASSERT(TempHandle != NULL);
948 }
949 if (!EFI_ERROR(Status)) {
950 ShellParameters->StdErr = TempHandle;
951 gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);
952 }
953 }
954
955 //
956 // StdOut to a file
957 //
958 if (!EFI_ERROR(Status) && StdOutFileName != NULL) {
959 if (!OutAppend) {
960 //
961 // delete existing file.
962 //
963 ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdOutFileName);
964 }
965 Status = ShellOpenFileByName(StdOutFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
966 if (TempHandle == NULL) {
967 Status = EFI_INVALID_PARAMETER;
968 } else {
969 if (StrStr(StdOutFileName, L"NUL")==StdOutFileName) {
970 //no-op
971 } else if (!OutAppend && OutUnicode && !EFI_ERROR(Status)) {
972 //
973 // Write out the gUnicodeFileTag
974 //
975 Size = sizeof(CHAR16);
976 TagBuffer[0] = gUnicodeFileTag;
977 TagBuffer[1] = CHAR_NULL;
978 ShellInfoObject.NewEfiShellProtocol->WriteFile(TempHandle, &Size, TagBuffer);
979 } else if (OutAppend) {
980 //
981 // Move to end of file
982 //
983 Status = ShellInfoObject.NewEfiShellProtocol->GetFileSize(TempHandle, &FileSize);
984 if (!EFI_ERROR(Status)) {
985 Status = ShellInfoObject.NewEfiShellProtocol->SetFilePosition(TempHandle, FileSize);
986 }
987 }
988 if (!OutUnicode && !EFI_ERROR(Status)) {
989 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
990 ASSERT(TempHandle != NULL);
991 }
992 if (!EFI_ERROR(Status)) {
993 ShellParameters->StdOut = TempHandle;
994 gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);
995 }
996 }
997 }
998
999 //
1000 // StdOut to a var
1001 //
1002 if (!EFI_ERROR(Status) && StdOutVarName != NULL) {
1003 if (!OutAppend) {
1004 //
1005 // delete existing variable.
1006 //
1007 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName, 0, L"");
1008 }
1009 TempHandle = CreateFileInterfaceEnv(StdOutVarName);
1010 ASSERT(TempHandle != NULL);
1011 ShellParameters->StdOut = TempHandle;
1012 gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);
1013 }
1014
1015 //
1016 // StdErr to a var
1017 //
1018 if (!EFI_ERROR(Status) && StdErrVarName != NULL) {
1019 if (!ErrAppend) {
1020 //
1021 // delete existing variable.
1022 //
1023 SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName, 0, L"");
1024 }
1025 TempHandle = CreateFileInterfaceEnv(StdErrVarName);
1026 ASSERT(TempHandle != NULL);
1027 ShellParameters->StdErr = TempHandle;
1028 gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);
1029 }
1030
1031 //
1032 // StdIn from a var
1033 //
1034 if (!EFI_ERROR(Status) && StdInVarName != NULL) {
1035 TempHandle = CreateFileInterfaceEnv(StdInVarName);
1036 if (TempHandle == NULL) {
1037 Status = EFI_OUT_OF_RESOURCES;
1038 } else {
1039 if (!InUnicode) {
1040 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1041 }
1042 Size = 0;
1043 if (((EFI_FILE_PROTOCOL*)TempHandle)->Read(TempHandle, &Size, NULL) != EFI_BUFFER_TOO_SMALL) {
1044 Status = EFI_INVALID_PARAMETER;
1045 } else {
1046 ShellParameters->StdIn = TempHandle;
1047 gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
1048 }
1049 }
1050 }
1051
1052 //
1053 // StdIn from a file
1054 //
1055 if (!EFI_ERROR(Status) && StdInFileName != NULL) {
1056 Status = ShellOpenFileByName(
1057 StdInFileName,
1058 &TempHandle,
1059 EFI_FILE_MODE_READ,
1060 0);
1061 if (!InUnicode && !EFI_ERROR(Status)) {
1062 TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
1063 }
1064 if (!EFI_ERROR(Status)) {
1065 ShellParameters->StdIn = TempHandle;
1066 gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
1067 }
1068 }
1069 }
1070 }
1071 FreePool(CommandLineCopy);
1072
1073 CalculateEfiHdrCrc(&gST->Hdr);
1074
1075 if (gST->ConIn == NULL ||gST->ConOut == NULL) {
1076 return (EFI_OUT_OF_RESOURCES);
1077 }
1078 return (Status);
1079 }
1080
1081 /**
1082 Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
1083 structure with StdIn and StdOut. The current values are de-allocated.
1084
1085 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1086 @param[in] OldStdIn Pointer to old StdIn.
1087 @param[in] OldStdOut Pointer to old StdOut.
1088 @param[in] OldStdErr Pointer to old StdErr.
1089 @param[in] SystemTableInfo Pointer to old system table information.
1090 **/
1091 EFI_STATUS
1092 EFIAPI
1093 RestoreStdInStdOutStdErr (
1094 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1095 IN SHELL_FILE_HANDLE *OldStdIn,
1096 IN SHELL_FILE_HANDLE *OldStdOut,
1097 IN SHELL_FILE_HANDLE *OldStdErr,
1098 IN SYSTEM_TABLE_INFO *SystemTableInfo
1099 )
1100 {
1101 SPLIT_LIST *Split;
1102
1103 if (ShellParameters == NULL
1104 ||OldStdIn == NULL
1105 ||OldStdOut == NULL
1106 ||OldStdErr == NULL
1107 ||SystemTableInfo == NULL) {
1108 return (EFI_INVALID_PARAMETER);
1109 }
1110 if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
1111 Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
1112 } else {
1113 Split = NULL;
1114 }
1115 if (ShellParameters->StdIn != *OldStdIn) {
1116 if ((Split != NULL && Split->SplitStdIn != ShellParameters->StdIn) || Split == NULL) {
1117 gEfiShellProtocol->CloseFile(ShellParameters->StdIn);
1118 }
1119 ShellParameters->StdIn = *OldStdIn;
1120 }
1121 if (ShellParameters->StdOut != *OldStdOut) {
1122 if ((Split != NULL && Split->SplitStdOut != ShellParameters->StdOut) || Split == NULL) {
1123 gEfiShellProtocol->CloseFile(ShellParameters->StdOut);
1124 }
1125 ShellParameters->StdOut = *OldStdOut;
1126 }
1127 if (ShellParameters->StdErr != *OldStdErr) {
1128 gEfiShellProtocol->CloseFile(ShellParameters->StdErr);
1129 ShellParameters->StdErr = *OldStdErr;
1130 }
1131
1132 if (gST->ConIn != SystemTableInfo->ConIn) {
1133 CloseSimpleTextInOnFile(gST->ConIn);
1134 gST->ConIn = SystemTableInfo->ConIn;
1135 gST->ConsoleInHandle = SystemTableInfo->ConInHandle;
1136 }
1137 if (gST->ConOut != SystemTableInfo->ConOut) {
1138 CloseSimpleTextOutOnFile(gST->ConOut);
1139 gST->ConOut = SystemTableInfo->ConOut;
1140 gST->ConsoleOutHandle = SystemTableInfo->ConOutHandle;
1141 }
1142 if (gST->StdErr != SystemTableInfo->ConErr) {
1143 CloseSimpleTextOutOnFile(gST->StdErr);
1144 gST->StdErr = SystemTableInfo->ConErr;
1145 gST->StandardErrorHandle = SystemTableInfo->ConErrHandle;
1146 }
1147
1148 CalculateEfiHdrCrc(&gST->Hdr);
1149
1150 return (EFI_SUCCESS);
1151 }
1152 /**
1153 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1154 structure by parsing NewCommandLine. The current values are returned to the
1155 user.
1156
1157 If OldArgv or OldArgc is NULL then that value is not returned.
1158
1159 @param[in, out] ShellParameters Pointer to parameter structure to modify.
1160 @param[in] NewCommandLine The new command line to parse and use.
1161 @param[out] OldArgv Pointer to old list of parameters.
1162 @param[out] OldArgc Pointer to old number of items in Argv list.
1163
1164 @retval EFI_SUCCESS Operation was sucessful, Argv and Argc are valid.
1165 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
1166 **/
1167 EFI_STATUS
1168 EFIAPI
1169 UpdateArgcArgv(
1170 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1171 IN CONST CHAR16 *NewCommandLine,
1172 OUT CHAR16 ***OldArgv OPTIONAL,
1173 OUT UINTN *OldArgc OPTIONAL
1174 )
1175 {
1176 ASSERT(ShellParameters != NULL);
1177
1178 if (OldArgc != NULL) {
1179 *OldArgc = ShellParameters->Argc;
1180 }
1181 if (OldArgc != NULL) {
1182 *OldArgv = ShellParameters->Argv;
1183 }
1184
1185 return (ParseCommandLineToArgs(NewCommandLine, &(ShellParameters->Argv), &(ShellParameters->Argc)));
1186 }
1187
1188 /**
1189 Funcion will replace the current Argc and Argv in the ShellParameters protocol
1190 structure with Argv and Argc. The current values are de-allocated and the
1191 OldArgv must not be deallocated by the caller.
1192
1193 @param[in, out] ShellParameters pointer to parameter structure to modify
1194 @param[in] OldArgv pointer to old list of parameters
1195 @param[in] OldArgc pointer to old number of items in Argv list
1196 **/
1197 VOID
1198 EFIAPI
1199 RestoreArgcArgv(
1200 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
1201 IN CHAR16 ***OldArgv,
1202 IN UINTN *OldArgc
1203 )
1204 {
1205 UINTN LoopCounter;
1206 ASSERT(ShellParameters != NULL);
1207 ASSERT(OldArgv != NULL);
1208 ASSERT(OldArgc != NULL);
1209
1210 if (ShellParameters->Argv != NULL) {
1211 for ( LoopCounter = 0
1212 ; LoopCounter < ShellParameters->Argc
1213 ; LoopCounter++
1214 ){
1215 FreePool(ShellParameters->Argv[LoopCounter]);
1216 }
1217 FreePool(ShellParameters->Argv);
1218 }
1219 ShellParameters->Argv = *OldArgv;
1220 *OldArgv = NULL;
1221 ShellParameters->Argc = *OldArgc;
1222 *OldArgc = 0;
1223 }