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