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