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