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