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