]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Application/Shell/ShellParametersProtocol.c
ShellPkg: Apply uncrustify changes
[mirror_edk2.git] / ShellPkg / Application / Shell / ShellParametersProtocol.c
CommitLineData
a405b86d 1/** @file\r
2 Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,\r
3 manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.\r
4\r
583448b4 5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
94c2a044 6 Copyright (C) 2014, Red Hat, Inc.\r
c011b6c9 7 (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>\r
ba0014b9 8 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
56ba3746 9 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a405b86d 10\r
11**/\r
12\r
0406a571 13#include "Shell.h"\r
a405b86d 14\r
47d20b54 15BOOLEAN AsciiRedirection = FALSE;\r
48cb33ec 16\r
1219c85d
RN
17/**\r
18 Return the next parameter's end from a command line string.\r
19\r
20 @param[in] String the string to parse\r
21**/\r
47d20b54
MK
22CONST CHAR16 *\r
23FindEndOfParameter (\r
24 IN CONST CHAR16 *String\r
1219c85d
RN
25 )\r
26{\r
47d20b54
MK
27 CONST CHAR16 *First;\r
28 CONST CHAR16 *CloseQuote;\r
1219c85d 29\r
47d20b54 30 First = FindFirstCharacter (String, L" \"", L'^');\r
1219c85d
RN
31\r
32 //\r
33 // nothing, all one parameter remaining\r
34 //\r
35 if (*First == CHAR_NULL) {\r
36 return (First);\r
37 }\r
38\r
39 //\r
40 // If space before a quote (or neither found, i.e. both CHAR_NULL),\r
41 // then that's the end.\r
42 //\r
43 if (*First == L' ') {\r
44 return (First);\r
45 }\r
46\r
47 CloseQuote = FindFirstCharacter (First+1, L"\"", L'^');\r
48\r
49 //\r
50 // We did not find a terminator...\r
51 //\r
52 if (*CloseQuote == CHAR_NULL) {\r
53 return (NULL);\r
54 }\r
55\r
56 return (FindEndOfParameter (CloseQuote+1));\r
57}\r
58\r
59/**\r
60 Return the next parameter from a command line string.\r
61\r
62 This function moves the next parameter from Walker into TempParameter and moves\r
63 Walker up past that parameter for recursive calling. When the final parameter\r
64 is moved *Walker will be set to NULL;\r
65\r
66 Temp Parameter must be large enough to hold the parameter before calling this\r
67 function.\r
68\r
69 This will also remove all remaining ^ characters after processing.\r
70\r
71 @param[in, out] Walker pointer to string of command line. Adjusted to\r
6a5033ca 72 remaining command line on return\r
1219c85d
RN
73 @param[in, out] TempParameter pointer to string of command line item extracted.\r
74 @param[in] Length buffer size of TempParameter.\r
75 @param[in] StripQuotation if TRUE then strip the quotation marks surrounding\r
76 the parameters.\r
77\r
6a5033ca 78 @return EFI_INVALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string.\r
1219c85d
RN
79 @return EFI_NOT_FOUND A closing " could not be found on the specified string\r
80**/\r
81EFI_STATUS\r
47d20b54 82GetNextParameter (\r
1219c85d
RN
83 IN OUT CHAR16 **Walker,\r
84 IN OUT CHAR16 **TempParameter,\r
85 IN CONST UINTN Length,\r
86 IN BOOLEAN StripQuotation\r
87 )\r
88{\r
47d20b54
MK
89 CONST CHAR16 *NextDelim;\r
90\r
91 if ( (Walker == NULL)\r
92 || (*Walker == NULL)\r
93 || (TempParameter == NULL)\r
94 || (*TempParameter == NULL)\r
95 )\r
96 {\r
1219c85d
RN
97 return (EFI_INVALID_PARAMETER);\r
98 }\r
99\r
1219c85d
RN
100 //\r
101 // make sure we dont have any leading spaces\r
102 //\r
103 while ((*Walker)[0] == L' ') {\r
47d20b54 104 (*Walker)++;\r
1219c85d
RN
105 }\r
106\r
107 //\r
108 // make sure we still have some params now...\r
109 //\r
47d20b54
MK
110 if (StrLen (*Walker) == 0) {\r
111 DEBUG_CODE_BEGIN ();\r
112 *Walker = NULL;\r
113 DEBUG_CODE_END ();\r
1219c85d
RN
114 return (EFI_INVALID_PARAMETER);\r
115 }\r
116\r
47d20b54 117 NextDelim = FindEndOfParameter (*Walker);\r
1219c85d 118\r
47d20b54
MK
119 if (NextDelim == NULL) {\r
120 DEBUG_CODE_BEGIN ();\r
121 *Walker = NULL;\r
122 DEBUG_CODE_END ();\r
1219c85d
RN
123 return (EFI_NOT_FOUND);\r
124 }\r
125\r
47d20b54 126 StrnCpyS (*TempParameter, Length / sizeof (CHAR16), (*Walker), NextDelim - *Walker);\r
1219c85d
RN
127\r
128 //\r
6a5033ca 129 // Add a CHAR_NULL if we didn't get one via the copy\r
1219c85d
RN
130 //\r
131 if (*NextDelim != CHAR_NULL) {\r
132 (*TempParameter)[NextDelim - *Walker] = CHAR_NULL;\r
133 }\r
134\r
135 //\r
136 // Update Walker for the next iteration through the function\r
137 //\r
47d20b54 138 *Walker = (CHAR16 *)NextDelim;\r
1219c85d
RN
139\r
140 //\r
141 // Remove any non-escaped quotes in the string\r
142 // Remove any remaining escape characters in the string\r
143 //\r
47d20b54
MK
144 for (NextDelim = FindFirstCharacter (*TempParameter, L"\"^", CHAR_NULL)\r
145 ; *NextDelim != CHAR_NULL\r
146 ; NextDelim = FindFirstCharacter (NextDelim, L"\"^", CHAR_NULL)\r
147 )\r
148 {\r
1219c85d 149 if (*NextDelim == L'^') {\r
1219c85d
RN
150 //\r
151 // eliminate the escape ^\r
152 //\r
47d20b54 153 CopyMem ((CHAR16 *)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));\r
1219c85d
RN
154 NextDelim++;\r
155 } else if (*NextDelim == L'\"') {\r
1219c85d
RN
156 //\r
157 // eliminate the unescaped quote\r
158 //\r
159 if (StripQuotation) {\r
47d20b54
MK
160 CopyMem ((CHAR16 *)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));\r
161 } else {\r
1219c85d 162 NextDelim++;\r
47d20b54 163 }\r
1219c85d
RN
164 }\r
165 }\r
166\r
167 return EFI_SUCCESS;\r
168}\r
169\r
a405b86d 170/**\r
733f138d 171 Function to populate Argc and Argv.\r
a405b86d 172\r
173 This function parses the CommandLine and divides it into standard C style Argc/Argv\r
174 parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL. this supports space\r
175 delimited and quote surrounded parameter definition.\r
176\r
ba0014b9 177 All special character processing (alias, environment variable, redirection,\r
14030c5c
JC
178 etc... must be complete before calling this API.\r
179\r
d1c275c6
QS
180 @param[in] CommandLine String of command line to parse\r
181 @param[in] StripQuotation if TRUE then strip the quotation marks surrounding\r
182 the parameters.\r
183 @param[in, out] Argv pointer to array of strings; one for each parameter\r
184 @param[in, out] Argc pointer to number of strings in Argv array\r
a405b86d 185\r
6a5033ca 186 @return EFI_SUCCESS the operation was successful\r
ddb7050c 187 @return EFI_INVALID_PARAMETER some parameters are invalid\r
a405b86d 188 @return EFI_OUT_OF_RESOURCES a memory allocation failed.\r
189**/\r
190EFI_STATUS\r
47d20b54
MK
191ParseCommandLineToArgs (\r
192 IN CONST CHAR16 *CommandLine,\r
193 IN BOOLEAN StripQuotation,\r
194 IN OUT CHAR16 ***Argv,\r
195 IN OUT UINTN *Argc\r
a405b86d 196 )\r
197{\r
198 UINTN Count;\r
199 CHAR16 *TempParameter;\r
200 CHAR16 *Walker;\r
201 CHAR16 *NewParam;\r
1fab9176 202 CHAR16 *NewCommandLine;\r
a405b86d 203 UINTN Size;\r
1fab9176 204 EFI_STATUS Status;\r
a405b86d 205\r
47d20b54
MK
206 ASSERT (Argc != NULL);\r
207 ASSERT (Argv != NULL);\r
a405b86d 208\r
47d20b54 209 if ((CommandLine == NULL) || (StrLen (CommandLine) == 0)) {\r
a405b86d 210 (*Argc) = 0;\r
211 (*Argv) = NULL;\r
212 return (EFI_SUCCESS);\r
213 }\r
214\r
47d20b54
MK
215 NewCommandLine = AllocateCopyPool (StrSize (CommandLine), CommandLine);\r
216 if (NewCommandLine == NULL) {\r
1fab9176
QS
217 return (EFI_OUT_OF_RESOURCES);\r
218 }\r
219\r
47d20b54
MK
220 TrimSpaces (&NewCommandLine);\r
221 Size = StrSize (NewCommandLine);\r
222 TempParameter = AllocateZeroPool (Size);\r
a405b86d 223 if (TempParameter == NULL) {\r
47d20b54 224 SHELL_FREE_NON_NULL (NewCommandLine);\r
a405b86d 225 return (EFI_OUT_OF_RESOURCES);\r
226 }\r
227\r
47d20b54
MK
228 for ( Count = 0,\r
229 Walker = (CHAR16 *)NewCommandLine\r
230 ; Walker != NULL && *Walker != CHAR_NULL\r
231 ; Count++\r
232 )\r
233 {\r
234 if (EFI_ERROR (GetNextParameter (&Walker, &TempParameter, Size, TRUE))) {\r
14030c5c
JC
235 break;\r
236 }\r
237 }\r
a405b86d 238\r
a405b86d 239 //\r
240 // lets allocate the pointer array\r
241 //\r
47d20b54 242 (*Argv) = AllocateZeroPool ((Count)*sizeof (CHAR16 *));\r
a405b86d 243 if (*Argv == NULL) {\r
1fab9176
QS
244 Status = EFI_OUT_OF_RESOURCES;\r
245 goto Done;\r
a405b86d 246 }\r
247\r
47d20b54
MK
248 *Argc = 0;\r
249 Walker = (CHAR16 *)NewCommandLine;\r
250 while (Walker != NULL && *Walker != CHAR_NULL) {\r
251 SetMem16 (TempParameter, Size, CHAR_NULL);\r
252 if (EFI_ERROR (GetNextParameter (&Walker, &TempParameter, Size, StripQuotation))) {\r
1fab9176
QS
253 Status = EFI_INVALID_PARAMETER;\r
254 goto Done;\r
14030c5c
JC
255 }\r
256\r
47d20b54
MK
257 NewParam = AllocateCopyPool (StrSize (TempParameter), TempParameter);\r
258 if (NewParam == NULL) {\r
1fab9176
QS
259 Status = EFI_OUT_OF_RESOURCES;\r
260 goto Done;\r
7f79b01e 261 }\r
47d20b54
MK
262\r
263 ((CHAR16 **)(*Argv))[(*Argc)] = NewParam;\r
a405b86d 264 (*Argc)++;\r
265 }\r
47d20b54
MK
266\r
267 ASSERT (Count >= (*Argc));\r
1fab9176 268 Status = EFI_SUCCESS;\r
ba0014b9 269\r
1fab9176 270Done:\r
47d20b54
MK
271 SHELL_FREE_NON_NULL (TempParameter);\r
272 SHELL_FREE_NON_NULL (NewCommandLine);\r
1fab9176 273 return (Status);\r
a405b86d 274}\r
275\r
276/**\r
277 creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then\r
278 installs it on our handle and if there is an existing version of the protocol\r
279 that one is cached for removal later.\r
280\r
4ff7e37b 281 @param[in, out] NewShellParameters on a successful return, a pointer to pointer\r
a405b86d 282 to the newly installed interface.\r
4ff7e37b 283 @param[in, out] RootShellInstance on a successful return, pointer to boolean.\r
a405b86d 284 TRUE if this is the root shell instance.\r
285\r
286 @retval EFI_SUCCESS the operation completed successfully.\r
287 @return other the operation failed.\r
288 @sa ReinstallProtocolInterface\r
289 @sa InstallProtocolInterface\r
290 @sa ParseCommandLineToArgs\r
291**/\r
292EFI_STATUS\r
a405b86d 293CreatePopulateInstallShellParametersProtocol (\r
294 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL **NewShellParameters,\r
295 IN OUT BOOLEAN *RootShellInstance\r
296 )\r
297{\r
47d20b54
MK
298 EFI_STATUS Status;\r
299 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
300 CHAR16 *FullCommandLine;\r
301 UINTN Size;\r
a405b86d 302\r
47d20b54 303 Size = 0;\r
a405b86d 304 FullCommandLine = NULL;\r
47d20b54 305 LoadedImage = NULL;\r
a405b86d 306\r
307 //\r
308 // Assert for valid parameters\r
309 //\r
47d20b54
MK
310 ASSERT (NewShellParameters != NULL);\r
311 ASSERT (RootShellInstance != NULL);\r
a405b86d 312\r
313 //\r
314 // See if we have a shell parameters placed on us\r
315 //\r
316 Status = gBS->OpenProtocol (\r
47d20b54
MK
317 gImageHandle,\r
318 &gEfiShellParametersProtocolGuid,\r
319 (VOID **)&ShellInfoObject.OldShellParameters,\r
320 gImageHandle,\r
321 NULL,\r
322 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
323 );\r
a405b86d 324 //\r
325 // if we don't then we must be the root shell (error is expected)\r
326 //\r
327 if (EFI_ERROR (Status)) {\r
328 *RootShellInstance = TRUE;\r
329 }\r
330\r
331 //\r
332 // Allocate the new structure\r
333 //\r
47d20b54 334 *NewShellParameters = AllocateZeroPool (sizeof (EFI_SHELL_PARAMETERS_PROTOCOL));\r
3c865f20 335 if ((*NewShellParameters) == NULL) {\r
336 return (EFI_OUT_OF_RESOURCES);\r
337 }\r
a405b86d 338\r
339 //\r
340 // get loaded image protocol\r
341 //\r
342 Status = gBS->OpenProtocol (\r
47d20b54
MK
343 gImageHandle,\r
344 &gEfiLoadedImageProtocolGuid,\r
345 (VOID **)&LoadedImage,\r
346 gImageHandle,\r
347 NULL,\r
348 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
349 );\r
350 ASSERT_EFI_ERROR (Status);\r
a405b86d 351 //\r
352 // Build the full command line\r
353 //\r
47d20b54 354 Status = SHELL_GET_ENVIRONMENT_VARIABLE (L"ShellOpt", &Size, FullCommandLine);\r
a405b86d 355 if (Status == EFI_BUFFER_TOO_SMALL) {\r
47d20b54
MK
356 FullCommandLine = AllocateZeroPool (Size + LoadedImage->LoadOptionsSize);\r
357 Status = SHELL_GET_ENVIRONMENT_VARIABLE (L"ShellOpt", &Size, FullCommandLine);\r
a405b86d 358 }\r
47d20b54 359\r
a405b86d 360 if (Status == EFI_NOT_FOUND) {\r
361 //\r
362 // no parameters via environment... ok\r
363 //\r
364 } else {\r
47d20b54 365 if (EFI_ERROR (Status)) {\r
3c865f20 366 return (Status);\r
367 }\r
a405b86d 368 }\r
47d20b54
MK
369\r
370 if ((Size == 0) && (LoadedImage->LoadOptionsSize != 0)) {\r
371 ASSERT (FullCommandLine == NULL);\r
a405b86d 372 //\r
373 // Now we need to include a NULL terminator in the size.\r
374 //\r
47d20b54
MK
375 Size = LoadedImage->LoadOptionsSize + sizeof (FullCommandLine[0]);\r
376 FullCommandLine = AllocateZeroPool (Size);\r
a405b86d 377 }\r
47d20b54 378\r
a405b86d 379 if (FullCommandLine != NULL) {\r
2c5a8aed 380 CopyMem (FullCommandLine, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize);\r
a405b86d 381 //\r
382 // Populate Argc and Argv\r
383 //\r
47d20b54
MK
384 Status = ParseCommandLineToArgs (\r
385 FullCommandLine,\r
386 TRUE,\r
387 &(*NewShellParameters)->Argv,\r
388 &(*NewShellParameters)->Argc\r
389 );\r
a405b86d 390\r
47d20b54 391 FreePool (FullCommandLine);\r
a405b86d 392\r
47d20b54 393 ASSERT_EFI_ERROR (Status);\r
a405b86d 394 } else {\r
395 (*NewShellParameters)->Argv = NULL;\r
396 (*NewShellParameters)->Argc = 0;\r
397 }\r
398\r
399 //\r
400 // Populate the 3 faked file systems...\r
401 //\r
402 if (*RootShellInstance) {\r
403 (*NewShellParameters)->StdIn = &FileInterfaceStdIn;\r
404 (*NewShellParameters)->StdOut = &FileInterfaceStdOut;\r
405 (*NewShellParameters)->StdErr = &FileInterfaceStdErr;\r
47d20b54
MK
406 Status = gBS->InstallProtocolInterface (\r
407 &gImageHandle,\r
a405b86d 408 &gEfiShellParametersProtocolGuid,\r
409 EFI_NATIVE_INTERFACE,\r
47d20b54
MK
410 (VOID *)(*NewShellParameters)\r
411 );\r
a405b86d 412 } else {\r
413 //\r
414 // copy from the existing ones\r
415 //\r
416 (*NewShellParameters)->StdIn = ShellInfoObject.OldShellParameters->StdIn;\r
417 (*NewShellParameters)->StdOut = ShellInfoObject.OldShellParameters->StdOut;\r
418 (*NewShellParameters)->StdErr = ShellInfoObject.OldShellParameters->StdErr;\r
47d20b54
MK
419 Status = gBS->ReinstallProtocolInterface (\r
420 gImageHandle,\r
421 &gEfiShellParametersProtocolGuid,\r
422 (VOID *)ShellInfoObject.OldShellParameters,\r
423 (VOID *)(*NewShellParameters)\r
424 );\r
a405b86d 425 }\r
426\r
427 return (Status);\r
428}\r
429\r
430/**\r
6a5033ca 431 frees all memory used by creation and installation of shell parameters protocol\r
a405b86d 432 and if there was an old version installed it will restore that one.\r
433\r
434 @param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is\r
435 being cleaned up.\r
436\r
437 @retval EFI_SUCCESS the cleanup was successful\r
438 @return other the cleanup failed\r
439 @sa ReinstallProtocolInterface\r
440 @sa UninstallProtocolInterface\r
441**/\r
442EFI_STATUS\r
a405b86d 443CleanUpShellParametersProtocol (\r
444 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *NewShellParameters\r
445 )\r
446{\r
47d20b54
MK
447 EFI_STATUS Status;\r
448 UINTN LoopCounter;\r
a405b86d 449\r
450 //\r
451 // If the old exists we need to restore it\r
452 //\r
453 if (ShellInfoObject.OldShellParameters != NULL) {\r
47d20b54
MK
454 Status = gBS->ReinstallProtocolInterface (\r
455 gImageHandle,\r
456 &gEfiShellParametersProtocolGuid,\r
457 (VOID *)NewShellParameters,\r
458 (VOID *)ShellInfoObject.OldShellParameters\r
459 );\r
460 DEBUG_CODE (\r
461 ShellInfoObject.OldShellParameters = NULL;\r
462 );\r
a405b86d 463 } else {\r
464 //\r
465 // No old one, just uninstall us...\r
466 //\r
47d20b54
MK
467 Status = gBS->UninstallProtocolInterface (\r
468 gImageHandle,\r
469 &gEfiShellParametersProtocolGuid,\r
470 (VOID *)NewShellParameters\r
471 );\r
a405b86d 472 }\r
47d20b54 473\r
a405b86d 474 if (NewShellParameters->Argv != NULL) {\r
475 for ( LoopCounter = 0\r
47d20b54
MK
476 ; LoopCounter < NewShellParameters->Argc\r
477 ; LoopCounter++\r
478 )\r
479 {\r
480 FreePool (NewShellParameters->Argv[LoopCounter]);\r
a405b86d 481 }\r
47d20b54
MK
482\r
483 FreePool (NewShellParameters->Argv);\r
a405b86d 484 }\r
47d20b54
MK
485\r
486 FreePool (NewShellParameters);\r
a405b86d 487 return (Status);\r
488}\r
489\r
ae724571 490/**\r
6a5033ca 491 Determine if a file name represents a unicode file.\r
ae724571 492\r
493 @param[in] FileName Pointer to the filename to open.\r
494\r
495 @retval EFI_SUCCESS The file is a unicode file.\r
496 @return An error upon failure.\r
497**/\r
733f138d 498EFI_STATUS\r
47d20b54
MK
499IsUnicodeFile (\r
500 IN CONST CHAR16 *FileName\r
733f138d 501 )\r
502{\r
47d20b54
MK
503 SHELL_FILE_HANDLE Handle;\r
504 EFI_STATUS Status;\r
505 UINT64 OriginalFilePosition;\r
506 UINTN CharSize;\r
507 CHAR16 CharBuffer;\r
508\r
509 Status = gEfiShellProtocol->OpenFileByName (FileName, &Handle, EFI_FILE_MODE_READ);\r
510 if (EFI_ERROR (Status)) {\r
733f138d 511 return (Status);\r
512 }\r
47d20b54
MK
513\r
514 gEfiShellProtocol->GetFilePosition (Handle, &OriginalFilePosition);\r
515 gEfiShellProtocol->SetFilePosition (Handle, 0);\r
516 CharSize = sizeof (CHAR16);\r
517 Status = gEfiShellProtocol->ReadFile (Handle, &CharSize, &CharBuffer);\r
518 if (EFI_ERROR (Status) || (CharBuffer != gUnicodeFileTag)) {\r
733f138d 519 Status = EFI_BUFFER_TOO_SMALL;\r
520 }\r
47d20b54
MK
521\r
522 gEfiShellProtocol->SetFilePosition (Handle, OriginalFilePosition);\r
523 gEfiShellProtocol->CloseFile (Handle);\r
ba0014b9 524 return (Status);\r
733f138d 525}\r
526\r
fb84495a 527/**\r
528 Strips out quotes sections of a string.\r
529\r
530 All of the characters between quotes is replaced with spaces.\r
a1d4bfcc 531\r
4ff7e37b 532 @param[in, out] TheString A pointer to the string to update.\r
fb84495a 533**/\r
534VOID\r
fb84495a 535StripQuotes (\r
47d20b54 536 IN OUT CHAR16 *TheString\r
fb84495a 537 )\r
538{\r
47d20b54 539 BOOLEAN RemoveNow;\r
fb84495a 540\r
47d20b54
MK
541 for (RemoveNow = FALSE; TheString != NULL && *TheString != CHAR_NULL; TheString++) {\r
542 if ((*TheString == L'^') && (*(TheString + 1) == L'\"')) {\r
fb84495a 543 TheString++;\r
544 } else if (*TheString == L'\"') {\r
47d20b54 545 RemoveNow = (BOOLEAN) !RemoveNow;\r
fb84495a 546 } else if (RemoveNow) {\r
547 *TheString = L' ';\r
548 }\r
549 }\r
550}\r
551\r
cf6a8f14 552/**\r
6a5033ca 553 Calculate the 32-bit CRC in a EFI table using the service provided by the\r
cf6a8f14 554 gRuntime service.\r
555\r
556 @param Hdr Pointer to an EFI standard header\r
557\r
558**/\r
559VOID\r
560CalculateEfiHdrCrc (\r
47d20b54 561 IN OUT EFI_TABLE_HEADER *Hdr\r
cf6a8f14 562 )\r
563{\r
47d20b54 564 UINT32 Crc;\r
cf6a8f14 565\r
566 Hdr->CRC32 = 0;\r
567\r
568 //\r
569 // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then\r
570 // Crc will come back as zero if we set it to zero here\r
571 //\r
572 Crc = 0;\r
573 gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);\r
574 Hdr->CRC32 = Crc;\r
575}\r
576\r
031acf63 577/**\r
578 Fix a string to only have the file name, removing starting at the first space of whatever is quoted.\r
579\r
580 @param[in] FileName The filename to start with.\r
581\r
582 @retval NULL FileName was invalid.\r
583 @return The modified FileName.\r
584**/\r
47d20b54 585CHAR16 *\r
031acf63 586FixFileName (\r
47d20b54 587 IN CHAR16 *FileName\r
031acf63 588 )\r
589{\r
590 CHAR16 *Copy;\r
591 CHAR16 *TempLocation;\r
592\r
593 if (FileName == NULL) {\r
594 return (NULL);\r
595 }\r
596\r
597 if (FileName[0] == L'\"') {\r
598 Copy = FileName+1;\r
47d20b54 599 if ((TempLocation = StrStr (Copy, L"\"")) != NULL) {\r
031acf63 600 TempLocation[0] = CHAR_NULL;\r
ba0014b9 601 }\r
031acf63 602 } else {\r
603 Copy = FileName;\r
47d20b54 604 while (Copy[0] == L' ') {\r
f9aefb6a 605 Copy++;\r
606 }\r
47d20b54
MK
607\r
608 if ((TempLocation = StrStr (Copy, L" ")) != NULL) {\r
031acf63 609 TempLocation[0] = CHAR_NULL;\r
ba0014b9 610 }\r
031acf63 611 }\r
612\r
613 if (Copy[0] == CHAR_NULL) {\r
614 return (NULL);\r
615 }\r
616\r
617 return (Copy);\r
618}\r
619\r
6813ba40
JC
620/**\r
621 Fix a string to only have the environment variable name, removing starting at the first space of whatever is quoted and removing the leading and trailing %.\r
622\r
623 @param[in] FileName The filename to start with.\r
624\r
625 @retval NULL FileName was invalid.\r
626 @return The modified FileName.\r
627**/\r
47d20b54 628CHAR16 *\r
6813ba40 629FixVarName (\r
47d20b54 630 IN CHAR16 *FileName\r
6813ba40
JC
631 )\r
632{\r
633 CHAR16 *Copy;\r
634 CHAR16 *TempLocation;\r
635\r
636 Copy = FileName;\r
637\r
638 if (FileName[0] == L'%') {\r
639 Copy = FileName+1;\r
47d20b54 640 if ((TempLocation = StrStr (Copy, L"%")) != NULL) {\r
6813ba40 641 TempLocation[0] = CHAR_NULL;\r
ba0014b9 642 }\r
6813ba40
JC
643 }\r
644\r
47d20b54 645 return (FixFileName (Copy));\r
6813ba40
JC
646}\r
647\r
94c2a044
LE
648/**\r
649 Write the unicode file tag to the specified file.\r
650\r
651 It is the caller's responsibility to ensure that\r
652 ShellInfoObject.NewEfiShellProtocol has been initialized before calling this\r
653 function.\r
654\r
655 @param[in] FileHandle The file to write the unicode file tag to.\r
656\r
657 @return Status code from ShellInfoObject.NewEfiShellProtocol->WriteFile.\r
658**/\r
94c2a044
LE
659EFI_STATUS\r
660WriteFileTag (\r
47d20b54 661 IN SHELL_FILE_HANDLE FileHandle\r
94c2a044
LE
662 )\r
663{\r
47d20b54
MK
664 CHAR16 FileTag;\r
665 UINTN Size;\r
666 EFI_STATUS Status;\r
94c2a044
LE
667\r
668 FileTag = gUnicodeFileTag;\r
47d20b54
MK
669 Size = sizeof FileTag;\r
670 Status = ShellInfoObject.NewEfiShellProtocol->WriteFile (\r
671 FileHandle,\r
672 &Size,\r
673 &FileTag\r
674 );\r
94c2a044
LE
675 ASSERT (EFI_ERROR (Status) || Size == sizeof FileTag);\r
676 return Status;\r
677}\r
678\r
a405b86d 679/**\r
6a5033ca 680 Function will replace the current StdIn and StdOut in the ShellParameters protocol\r
a405b86d 681 structure by parsing NewCommandLine. The current values are returned to the\r
682 user.\r
683\r
8be0ba36 684 This will also update the system table.\r
a405b86d 685\r
4ff7e37b
ED
686 @param[in, out] ShellParameters Pointer to parameter structure to modify.\r
687 @param[in] NewCommandLine The new command line to parse and use.\r
688 @param[out] OldStdIn Pointer to old StdIn.\r
689 @param[out] OldStdOut Pointer to old StdOut.\r
690 @param[out] OldStdErr Pointer to old StdErr.\r
691 @param[out] SystemTableInfo Pointer to old system table information.\r
a405b86d 692\r
6a5033ca 693 @retval EFI_SUCCESS Operation was successful, Argv and Argc are valid.\r
a405b86d 694 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
695**/\r
696EFI_STATUS\r
47d20b54 697UpdateStdInStdOutStdErr (\r
a405b86d 698 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
fb84495a 699 IN CHAR16 *NewCommandLine,\r
a405b86d 700 OUT SHELL_FILE_HANDLE *OldStdIn,\r
701 OUT SHELL_FILE_HANDLE *OldStdOut,\r
8be0ba36 702 OUT SHELL_FILE_HANDLE *OldStdErr,\r
703 OUT SYSTEM_TABLE_INFO *SystemTableInfo\r
a405b86d 704 )\r
705{\r
47d20b54
MK
706 CHAR16 *CommandLineCopy;\r
707 CHAR16 *CommandLineWalker;\r
708 CHAR16 *StdErrFileName;\r
709 CHAR16 *StdOutFileName;\r
710 CHAR16 *StdInFileName;\r
711 CHAR16 *StdInVarName;\r
712 CHAR16 *StdOutVarName;\r
713 CHAR16 *StdErrVarName;\r
714 EFI_STATUS Status;\r
715 SHELL_FILE_HANDLE TempHandle;\r
716 UINT64 FileSize;\r
717 BOOLEAN OutUnicode;\r
718 BOOLEAN InUnicode;\r
719 BOOLEAN ErrUnicode;\r
720 BOOLEAN OutAppend;\r
721 BOOLEAN ErrAppend;\r
722 UINTN Size;\r
723 SPLIT_LIST *Split;\r
724 CHAR16 *FirstLocation;\r
725 BOOLEAN Volatile;\r
726\r
727 OutUnicode = TRUE;\r
728 InUnicode = TRUE;\r
48cb33ec 729 AsciiRedirection = FALSE;\r
47d20b54
MK
730 ErrUnicode = TRUE;\r
731 StdInVarName = NULL;\r
732 StdOutVarName = NULL;\r
733 StdErrVarName = NULL;\r
734 StdErrFileName = NULL;\r
735 StdInFileName = NULL;\r
736 StdOutFileName = NULL;\r
737 ErrAppend = FALSE;\r
738 OutAppend = FALSE;\r
739 CommandLineCopy = NULL;\r
740 FirstLocation = NULL;\r
741\r
742 if ((ShellParameters == NULL) || (SystemTableInfo == NULL) || (OldStdIn == NULL) || (OldStdOut == NULL) || (OldStdErr == NULL)) {\r
8be0ba36 743 return (EFI_INVALID_PARAMETER);\r
a405b86d 744 }\r
745\r
47d20b54
MK
746 SystemTableInfo->ConIn = gST->ConIn;\r
747 SystemTableInfo->ConInHandle = gST->ConsoleInHandle;\r
748 SystemTableInfo->ConOut = gST->ConOut;\r
749 SystemTableInfo->ConOutHandle = gST->ConsoleOutHandle;\r
750 SystemTableInfo->ErrOut = gST->StdErr;\r
751 SystemTableInfo->ErrOutHandle = gST->StandardErrorHandle;\r
752 *OldStdIn = ShellParameters->StdIn;\r
753 *OldStdOut = ShellParameters->StdOut;\r
754 *OldStdErr = ShellParameters->StdErr;\r
8be0ba36 755\r
a405b86d 756 if (NewCommandLine == NULL) {\r
757 return (EFI_SUCCESS);\r
758 }\r
759\r
47d20b54 760 CommandLineCopy = StrnCatGrow (&CommandLineCopy, NULL, NewCommandLine, 0);\r
532691c8 761 if (CommandLineCopy == NULL) {\r
762 return (EFI_OUT_OF_RESOURCES);\r
763 }\r
a405b86d 764\r
47d20b54
MK
765 Status = EFI_SUCCESS;\r
766 Split = NULL;\r
767 FirstLocation = CommandLineCopy + StrLen (CommandLineCopy);\r
768\r
769 StripQuotes (CommandLineCopy);\r
fb84495a 770\r
47d20b54
MK
771 if (!IsListEmpty (&ShellInfoObject.SplitList.Link)) {\r
772 Split = (SPLIT_LIST *)GetFirstNode (&ShellInfoObject.SplitList.Link);\r
773 if ((Split != NULL) && (Split->SplitStdIn != NULL)) {\r
774 ShellParameters->StdIn = Split->SplitStdIn;\r
a405b86d 775 }\r
47d20b54
MK
776\r
777 if ((Split != NULL) && (Split->SplitStdOut != NULL)) {\r
a405b86d 778 ShellParameters->StdOut = Split->SplitStdOut;\r
779 }\r
780 }\r
781\r
47d20b54
MK
782 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 2>>v ")) != NULL)) {\r
783 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
784 SetMem16 (CommandLineWalker, 12, L' ');\r
785 StdErrVarName = CommandLineWalker += 6;\r
786 ErrAppend = TRUE;\r
787 if (StrStr (CommandLineWalker, L" 2>>v ") != NULL) {\r
733f138d 788 Status = EFI_NOT_FOUND;\r
789 }\r
a405b86d 790 }\r
47d20b54
MK
791\r
792 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 1>>v ")) != NULL)) {\r
793 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
794 SetMem16 (CommandLineWalker, 12, L' ');\r
795 StdOutVarName = CommandLineWalker += 6;\r
796 OutAppend = TRUE;\r
797 if (StrStr (CommandLineWalker, L" 1>>v ") != NULL) {\r
733f138d 798 Status = EFI_NOT_FOUND;\r
799 }\r
47d20b54
MK
800 } else if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" >>v ")) != NULL)) {\r
801 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
802 SetMem16 (CommandLineWalker, 10, L' ');\r
803 StdOutVarName = CommandLineWalker += 5;\r
804 OutAppend = TRUE;\r
805 if (StrStr (CommandLineWalker, L" >>v ") != NULL) {\r
733f138d 806 Status = EFI_NOT_FOUND;\r
807 }\r
47d20b54
MK
808 } else if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" >v ")) != NULL)) {\r
809 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
810 SetMem16 (CommandLineWalker, 8, L' ');\r
811 StdOutVarName = CommandLineWalker += 4;\r
812 OutAppend = FALSE;\r
813 if (StrStr (CommandLineWalker, L" >v ") != NULL) {\r
733f138d 814 Status = EFI_NOT_FOUND;\r
815 }\r
a405b86d 816 }\r
47d20b54
MK
817\r
818 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 1>>a ")) != NULL)) {\r
819 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
820 SetMem16 (CommandLineWalker, 12, L' ');\r
821 StdOutFileName = CommandLineWalker += 6;\r
822 OutAppend = TRUE;\r
823 OutUnicode = FALSE;\r
824 if (StrStr (CommandLineWalker, L" 1>>a ") != NULL) {\r
733f138d 825 Status = EFI_NOT_FOUND;\r
826 }\r
a405b86d 827 }\r
47d20b54
MK
828\r
829 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 1>> ")) != NULL)) {\r
830 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
831 SetMem16 (CommandLineWalker, 10, L' ');\r
a405b86d 832 if (StdOutFileName != NULL) {\r
833 Status = EFI_INVALID_PARAMETER;\r
834 } else {\r
47d20b54
MK
835 StdOutFileName = CommandLineWalker += 5;\r
836 OutAppend = TRUE;\r
a405b86d 837 }\r
47d20b54
MK
838\r
839 if (StrStr (CommandLineWalker, L" 1>> ") != NULL) {\r
733f138d 840 Status = EFI_NOT_FOUND;\r
841 }\r
ba0014b9 842 }\r
47d20b54
MK
843\r
844 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" >> ")) != NULL)) {\r
845 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
846 SetMem16 (CommandLineWalker, 8, L' ');\r
a405b86d 847 if (StdOutFileName != NULL) {\r
848 Status = EFI_INVALID_PARAMETER;\r
849 } else {\r
47d20b54
MK
850 StdOutFileName = CommandLineWalker += 4;\r
851 OutAppend = TRUE;\r
a405b86d 852 }\r
47d20b54
MK
853\r
854 if (StrStr (CommandLineWalker, L" >> ") != NULL) {\r
733f138d 855 Status = EFI_NOT_FOUND;\r
856 }\r
a405b86d 857 }\r
47d20b54
MK
858\r
859 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" >>a ")) != NULL)) {\r
860 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
861 SetMem16 (CommandLineWalker, 10, L' ');\r
a405b86d 862 if (StdOutFileName != NULL) {\r
863 Status = EFI_INVALID_PARAMETER;\r
864 } else {\r
47d20b54
MK
865 StdOutFileName = CommandLineWalker += 5;\r
866 OutAppend = TRUE;\r
867 OutUnicode = FALSE;\r
a405b86d 868 }\r
47d20b54
MK
869\r
870 if (StrStr (CommandLineWalker, L" >>a ") != NULL) {\r
733f138d 871 Status = EFI_NOT_FOUND;\r
872 }\r
ba0014b9 873 }\r
47d20b54
MK
874\r
875 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 1>a ")) != NULL)) {\r
876 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
877 SetMem16 (CommandLineWalker, 10, L' ');\r
a405b86d 878 if (StdOutFileName != NULL) {\r
879 Status = EFI_INVALID_PARAMETER;\r
880 } else {\r
47d20b54
MK
881 StdOutFileName = CommandLineWalker += 5;\r
882 OutAppend = FALSE;\r
883 OutUnicode = FALSE;\r
a405b86d 884 }\r
47d20b54
MK
885\r
886 if (StrStr (CommandLineWalker, L" 1>a ") != NULL) {\r
733f138d 887 Status = EFI_NOT_FOUND;\r
888 }\r
ba0014b9 889 }\r
47d20b54
MK
890\r
891 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" >a ")) != NULL)) {\r
892 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
893 SetMem16 (CommandLineWalker, 8, L' ');\r
a405b86d 894 if (StdOutFileName != NULL) {\r
895 Status = EFI_INVALID_PARAMETER;\r
896 } else {\r
47d20b54
MK
897 StdOutFileName = CommandLineWalker += 4;\r
898 OutAppend = FALSE;\r
899 OutUnicode = FALSE;\r
a405b86d 900 }\r
47d20b54
MK
901\r
902 if (StrStr (CommandLineWalker, L" >a ") != NULL) {\r
733f138d 903 Status = EFI_NOT_FOUND;\r
904 }\r
a405b86d 905 }\r
47d20b54
MK
906\r
907 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 2>> ")) != NULL)) {\r
908 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
909 SetMem16 (CommandLineWalker, 10, L' ');\r
a405b86d 910 if (StdErrFileName != NULL) {\r
911 Status = EFI_INVALID_PARAMETER;\r
912 } else {\r
47d20b54
MK
913 StdErrFileName = CommandLineWalker += 5;\r
914 ErrAppend = TRUE;\r
a405b86d 915 }\r
47d20b54
MK
916\r
917 if (StrStr (CommandLineWalker, L" 2>> ") != NULL) {\r
733f138d 918 Status = EFI_NOT_FOUND;\r
919 }\r
a405b86d 920 }\r
921\r
47d20b54
MK
922 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 2>v ")) != NULL)) {\r
923 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
924 SetMem16 (CommandLineWalker, 10, L' ');\r
a405b86d 925 if (StdErrVarName != NULL) {\r
926 Status = EFI_INVALID_PARAMETER;\r
927 } else {\r
47d20b54
MK
928 StdErrVarName = CommandLineWalker += 5;\r
929 ErrAppend = FALSE;\r
a405b86d 930 }\r
47d20b54
MK
931\r
932 if (StrStr (CommandLineWalker, L" 2>v ") != NULL) {\r
733f138d 933 Status = EFI_NOT_FOUND;\r
934 }\r
a405b86d 935 }\r
47d20b54
MK
936\r
937 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 1>v ")) != NULL)) {\r
938 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
939 SetMem16 (CommandLineWalker, 10, L' ');\r
a405b86d 940 if (StdOutVarName != NULL) {\r
941 Status = EFI_INVALID_PARAMETER;\r
942 } else {\r
47d20b54
MK
943 StdOutVarName = CommandLineWalker += 5;\r
944 OutAppend = FALSE;\r
a405b86d 945 }\r
47d20b54
MK
946\r
947 if (StrStr (CommandLineWalker, L" 1>v ") != NULL) {\r
733f138d 948 Status = EFI_NOT_FOUND;\r
949 }\r
a405b86d 950 }\r
47d20b54
MK
951\r
952 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 2>a ")) != NULL)) {\r
953 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
954 SetMem16 (CommandLineWalker, 10, L' ');\r
a405b86d 955 if (StdErrFileName != NULL) {\r
956 Status = EFI_INVALID_PARAMETER;\r
957 } else {\r
47d20b54
MK
958 StdErrFileName = CommandLineWalker += 5;\r
959 ErrAppend = FALSE;\r
960 ErrUnicode = FALSE;\r
a405b86d 961 }\r
47d20b54
MK
962\r
963 if (StrStr (CommandLineWalker, L" 2>a ") != NULL) {\r
733f138d 964 Status = EFI_NOT_FOUND;\r
965 }\r
a405b86d 966 }\r
47d20b54
MK
967\r
968 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 2> ")) != NULL)) {\r
969 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
970 SetMem16 (CommandLineWalker, 8, L' ');\r
a405b86d 971 if (StdErrFileName != NULL) {\r
972 Status = EFI_INVALID_PARAMETER;\r
973 } else {\r
47d20b54
MK
974 StdErrFileName = CommandLineWalker += 4;\r
975 ErrAppend = FALSE;\r
a405b86d 976 }\r
47d20b54
MK
977\r
978 if (StrStr (CommandLineWalker, L" 2> ") != NULL) {\r
733f138d 979 Status = EFI_NOT_FOUND;\r
980 }\r
a405b86d 981 }\r
982\r
47d20b54
MK
983 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" 1> ")) != NULL)) {\r
984 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
985 SetMem16 (CommandLineWalker, 8, L' ');\r
a405b86d 986 if (StdOutFileName != NULL) {\r
987 Status = EFI_INVALID_PARAMETER;\r
988 } else {\r
47d20b54
MK
989 StdOutFileName = CommandLineWalker += 4;\r
990 OutAppend = FALSE;\r
a405b86d 991 }\r
47d20b54
MK
992\r
993 if (StrStr (CommandLineWalker, L" 1> ") != NULL) {\r
733f138d 994 Status = EFI_NOT_FOUND;\r
995 }\r
a405b86d 996 }\r
997\r
47d20b54
MK
998 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" > ")) != NULL)) {\r
999 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
1000 SetMem16 (CommandLineWalker, 6, L' ');\r
a405b86d 1001 if (StdOutFileName != NULL) {\r
1002 Status = EFI_INVALID_PARAMETER;\r
1003 } else {\r
47d20b54
MK
1004 StdOutFileName = CommandLineWalker += 3;\r
1005 OutAppend = FALSE;\r
a405b86d 1006 }\r
47d20b54
MK
1007\r
1008 if (StrStr (CommandLineWalker, L" > ") != NULL) {\r
733f138d 1009 Status = EFI_NOT_FOUND;\r
1010 }\r
a405b86d 1011 }\r
1012\r
47d20b54
MK
1013 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" < ")) != NULL)) {\r
1014 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
1015 SetMem16 (CommandLineWalker, 6, L' ');\r
a405b86d 1016 if (StdInFileName != NULL) {\r
1017 Status = EFI_INVALID_PARAMETER;\r
1018 } else {\r
47d20b54 1019 StdInFileName = CommandLineWalker += 3;\r
733f138d 1020 }\r
47d20b54
MK
1021\r
1022 if (StrStr (CommandLineWalker, L" < ") != NULL) {\r
733f138d 1023 Status = EFI_NOT_FOUND;\r
a405b86d 1024 }\r
1025 }\r
47d20b54
MK
1026\r
1027 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" <a ")) != NULL)) {\r
1028 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
1029 SetMem16 (CommandLineWalker, 8, L' ');\r
a405b86d 1030 if (StdInFileName != NULL) {\r
1031 Status = EFI_INVALID_PARAMETER;\r
1032 } else {\r
47d20b54
MK
1033 StdInFileName = CommandLineWalker += 4;\r
1034 InUnicode = FALSE;\r
48cb33ec 1035 AsciiRedirection = TRUE;\r
733f138d 1036 }\r
47d20b54
MK
1037\r
1038 if (StrStr (CommandLineWalker, L" <a ") != NULL) {\r
733f138d 1039 Status = EFI_NOT_FOUND;\r
a405b86d 1040 }\r
1041 }\r
47d20b54
MK
1042\r
1043 if (!EFI_ERROR (Status) && ((CommandLineWalker = StrStr (CommandLineCopy, L" <v ")) != NULL)) {\r
1044 FirstLocation = MIN (CommandLineWalker, FirstLocation);\r
1045 SetMem16 (CommandLineWalker, 8, L' ');\r
a405b86d 1046 if (StdInVarName != NULL) {\r
1047 Status = EFI_INVALID_PARAMETER;\r
1048 } else {\r
47d20b54 1049 StdInVarName = CommandLineWalker += 4;\r
733f138d 1050 }\r
47d20b54
MK
1051\r
1052 if (StrStr (CommandLineWalker, L" <v ") != NULL) {\r
733f138d 1053 Status = EFI_NOT_FOUND;\r
a405b86d 1054 }\r
1055 }\r
1056\r
031acf63 1057 //\r
1058 // re-populate the string to support any filenames that were in quotes.\r
1059 //\r
47d20b54 1060 StrnCpyS (CommandLineCopy, StrSize (CommandLineCopy)/sizeof (CHAR16), NewCommandLine, StrLen (NewCommandLine));\r
031acf63 1061\r
47d20b54
MK
1062 if ( (FirstLocation != CommandLineCopy + StrLen (CommandLineCopy))\r
1063 && (((UINTN)FirstLocation - (UINTN)CommandLineCopy)/sizeof (CHAR16) < StrLen (NewCommandLine))\r
1064 )\r
1065 {\r
1066 *(NewCommandLine + ((UINTN)FirstLocation - (UINTN)CommandLineCopy)/sizeof (CHAR16)) = CHAR_NULL;\r
fb84495a 1067 }\r
1068\r
47d20b54 1069 if (!EFI_ERROR (Status)) {\r
031acf63 1070 if (StdErrFileName != NULL) {\r
47d20b54 1071 if ((StdErrFileName = FixFileName (StdErrFileName)) == NULL) {\r
031acf63 1072 Status = EFI_INVALID_PARAMETER;\r
1073 }\r
a405b86d 1074 }\r
47d20b54 1075\r
031acf63 1076 if (StdOutFileName != NULL) {\r
47d20b54 1077 if ((StdOutFileName = FixFileName (StdOutFileName)) == NULL) {\r
031acf63 1078 Status = EFI_INVALID_PARAMETER;\r
1079 }\r
a405b86d 1080 }\r
47d20b54 1081\r
031acf63 1082 if (StdInFileName != NULL) {\r
47d20b54 1083 if ((StdInFileName = FixFileName (StdInFileName)) == NULL) {\r
031acf63 1084 Status = EFI_INVALID_PARAMETER;\r
1085 }\r
a405b86d 1086 }\r
47d20b54 1087\r
031acf63 1088 if (StdErrVarName != NULL) {\r
47d20b54 1089 if ((StdErrVarName = FixVarName (StdErrVarName)) == NULL) {\r
031acf63 1090 Status = EFI_INVALID_PARAMETER;\r
1091 }\r
a405b86d 1092 }\r
47d20b54 1093\r
031acf63 1094 if (StdOutVarName != NULL) {\r
47d20b54 1095 if ((StdOutVarName = FixVarName (StdOutVarName)) == NULL) {\r
031acf63 1096 Status = EFI_INVALID_PARAMETER;\r
1097 }\r
a405b86d 1098 }\r
47d20b54 1099\r
031acf63 1100 if (StdInVarName != NULL) {\r
47d20b54 1101 if ((StdInVarName = FixVarName (StdInVarName)) == NULL) {\r
031acf63 1102 Status = EFI_INVALID_PARAMETER;\r
1103 }\r
a405b86d 1104 }\r
1105\r
0c956e0d 1106 //\r
1107 // Verify not the same and not duplicating something from a split\r
1108 //\r
733f138d 1109 if (\r
47d20b54
MK
1110 //\r
1111 // Check that no 2 filenames are the same\r
1112 //\r
1113 ((StdErrFileName != NULL) && (StdOutFileName != NULL) && (StringNoCaseCompare (&StdErrFileName, &StdOutFileName) == 0))\r
1114 || ((StdErrFileName != NULL) && (StdInFileName != NULL) && (StringNoCaseCompare (&StdErrFileName, &StdInFileName) == 0))\r
1115 || ((StdOutFileName != NULL) && (StdInFileName != NULL) && (StringNoCaseCompare (&StdOutFileName, &StdInFileName) == 0))\r
1116 //\r
1117 // Check that no 2 variable names are the same\r
1118 //\r
1119 || ((StdErrVarName != NULL) && (StdInVarName != NULL) && (StringNoCaseCompare (&StdErrVarName, &StdInVarName) == 0))\r
1120 || ((StdOutVarName != NULL) && (StdInVarName != NULL) && (StringNoCaseCompare (&StdOutVarName, &StdInVarName) == 0))\r
1121 || ((StdErrVarName != NULL) && (StdOutVarName != NULL) && (StringNoCaseCompare (&StdErrVarName, &StdOutVarName) == 0))\r
1122 //\r
1123 // When a split (using | operator) is in place some are not allowed\r
1124 //\r
1125 || ((Split != NULL) && (Split->SplitStdIn != NULL) && ((StdInVarName != NULL) || (StdInFileName != NULL)))\r
1126 || ((Split != NULL) && (Split->SplitStdOut != NULL) && ((StdOutVarName != NULL) || (StdOutFileName != NULL)))\r
1127 //\r
1128 // Check that nothing is trying to be output to 2 locations.\r
1129 //\r
1130 || ((StdErrFileName != NULL) && (StdErrVarName != NULL))\r
1131 || ((StdOutFileName != NULL) && (StdOutVarName != NULL))\r
1132 || ((StdInFileName != NULL) && (StdInVarName != NULL))\r
1133 //\r
1134 // Check for no volatile environment variables\r
1135 //\r
1136 || ((StdErrVarName != NULL) && !EFI_ERROR (IsVolatileEnv (StdErrVarName, &Volatile)) && !Volatile)\r
1137 || ((StdOutVarName != NULL) && !EFI_ERROR (IsVolatileEnv (StdOutVarName, &Volatile)) && !Volatile)\r
1138 //\r
1139 // Cant redirect during a reconnect operation.\r
1140 //\r
1141 || ( (StrStr (NewCommandLine, L"connect -r") != NULL)\r
1142 && ((StdOutVarName != NULL) || (StdOutFileName != NULL) || (StdErrFileName != NULL) || (StdErrVarName != NULL)))\r
1143 //\r
1144 // Check that filetypes (Unicode/Ascii) do not change during an append\r
1145 //\r
1146 || ((StdOutFileName != NULL) && OutUnicode && OutAppend && (!EFI_ERROR (ShellFileExists (StdOutFileName)) && EFI_ERROR (IsUnicodeFile (StdOutFileName))))\r
1147 || ((StdErrFileName != NULL) && ErrUnicode && ErrAppend && (!EFI_ERROR (ShellFileExists (StdErrFileName)) && EFI_ERROR (IsUnicodeFile (StdErrFileName))))\r
1148 || ((StdOutFileName != NULL) && !OutUnicode && OutAppend && (!EFI_ERROR (ShellFileExists (StdOutFileName)) && !EFI_ERROR (IsUnicodeFile (StdOutFileName))))\r
1149 || ((StdErrFileName != NULL) && !ErrUnicode && ErrAppend && (!EFI_ERROR (ShellFileExists (StdErrFileName)) && !EFI_ERROR (IsUnicodeFile (StdErrFileName))))\r
1150 )\r
1151 {\r
1152 Status = EFI_INVALID_PARAMETER;\r
a9ca0684 1153 ShellParameters->StdIn = *OldStdIn;\r
1154 ShellParameters->StdOut = *OldStdOut;\r
1155 ShellParameters->StdErr = *OldStdErr;\r
47d20b54 1156 } else if (!EFI_ERROR (Status)) {\r
a405b86d 1157 //\r
1158 // Open the Std<Whatever> and we should not have conflicts here...\r
1159 //\r
1160\r
1161 //\r
1162 // StdErr to a file\r
1163 //\r
1164 if (StdErrFileName != NULL) {\r
1165 if (!ErrAppend) {\r
1166 //\r
1167 // delete existing file.\r
1168 //\r
47d20b54 1169 ShellInfoObject.NewEfiShellProtocol->DeleteFileByName (StdErrFileName);\r
a405b86d 1170 }\r
47d20b54
MK
1171\r
1172 Status = ShellOpenFileByName (StdErrFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, 0);\r
1173 if (!ErrAppend && ErrUnicode && !EFI_ERROR (Status)) {\r
94c2a044 1174 Status = WriteFileTag (TempHandle);\r
a405b86d 1175 }\r
47d20b54
MK
1176\r
1177 if (!ErrUnicode && !EFI_ERROR (Status)) {\r
1178 TempHandle = CreateFileInterfaceFile (TempHandle, FALSE);\r
1179 ASSERT (TempHandle != NULL);\r
a405b86d 1180 }\r
47d20b54
MK
1181\r
1182 if (!EFI_ERROR (Status)) {\r
a405b86d 1183 ShellParameters->StdErr = TempHandle;\r
47d20b54 1184 gST->StdErr = CreateSimpleTextOutOnFile (TempHandle, &gST->StandardErrorHandle, gST->StdErr);\r
a405b86d 1185 }\r
1186 }\r
1187\r
1188 //\r
1189 // StdOut to a file\r
1190 //\r
47d20b54 1191 if (!EFI_ERROR (Status) && (StdOutFileName != NULL)) {\r
a405b86d 1192 if (!OutAppend) {\r
1193 //\r
1194 // delete existing file.\r
1195 //\r
47d20b54 1196 ShellInfoObject.NewEfiShellProtocol->DeleteFileByName (StdOutFileName);\r
a405b86d 1197 }\r
47d20b54
MK
1198\r
1199 Status = ShellOpenFileByName (StdOutFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, 0);\r
3c865f20 1200 if (TempHandle == NULL) {\r
1201 Status = EFI_INVALID_PARAMETER;\r
1202 } else {\r
583448b4 1203 if (gUnicodeCollation->MetaiMatch (gUnicodeCollation, StdOutFileName, L"NUL")) {\r
47d20b54
MK
1204 // no-op\r
1205 } else if (!OutAppend && OutUnicode && !EFI_ERROR (Status)) {\r
94c2a044 1206 Status = WriteFileTag (TempHandle);\r
3c865f20 1207 } else if (OutAppend) {\r
47d20b54
MK
1208 Status = ShellInfoObject.NewEfiShellProtocol->GetFileSize (TempHandle, &FileSize);\r
1209 if (!EFI_ERROR (Status)) {\r
5967886d
LE
1210 //\r
1211 // When appending to a new unicode file, write the file tag.\r
1212 // Otherwise (ie. when appending to a new ASCII file, or an\r
1213 // existent file with any encoding), just seek to the end.\r
1214 //\r
1215 Status = (FileSize == 0 && OutUnicode) ?\r
47d20b54
MK
1216 WriteFileTag (TempHandle) :\r
1217 ShellInfoObject.NewEfiShellProtocol->SetFilePosition (\r
1218 TempHandle,\r
1219 FileSize\r
1220 );\r
3c865f20 1221 }\r
1222 }\r
47d20b54
MK
1223\r
1224 if (!OutUnicode && !EFI_ERROR (Status)) {\r
1225 TempHandle = CreateFileInterfaceFile (TempHandle, FALSE);\r
1226 ASSERT (TempHandle != NULL);\r
3c865f20 1227 }\r
47d20b54
MK
1228\r
1229 if (!EFI_ERROR (Status)) {\r
3c865f20 1230 ShellParameters->StdOut = TempHandle;\r
47d20b54 1231 gST->ConOut = CreateSimpleTextOutOnFile (TempHandle, &gST->ConsoleOutHandle, gST->ConOut);\r
a405b86d 1232 }\r
1233 }\r
a405b86d 1234 }\r
1235\r
1236 //\r
1237 // StdOut to a var\r
1238 //\r
47d20b54 1239 if (!EFI_ERROR (Status) && (StdOutVarName != NULL)) {\r
a405b86d 1240 if (!OutAppend) {\r
1241 //\r
1242 // delete existing variable.\r
1243 //\r
47d20b54 1244 SHELL_SET_ENVIRONMENT_VARIABLE_V (StdOutVarName, 0, L"");\r
a405b86d 1245 }\r
47d20b54
MK
1246\r
1247 TempHandle = CreateFileInterfaceEnv (StdOutVarName);\r
1248 ASSERT (TempHandle != NULL);\r
a405b86d 1249 ShellParameters->StdOut = TempHandle;\r
47d20b54 1250 gST->ConOut = CreateSimpleTextOutOnFile (TempHandle, &gST->ConsoleOutHandle, gST->ConOut);\r
a405b86d 1251 }\r
1252\r
1253 //\r
1254 // StdErr to a var\r
1255 //\r
47d20b54 1256 if (!EFI_ERROR (Status) && (StdErrVarName != NULL)) {\r
a405b86d 1257 if (!ErrAppend) {\r
1258 //\r
1259 // delete existing variable.\r
1260 //\r
47d20b54 1261 SHELL_SET_ENVIRONMENT_VARIABLE_V (StdErrVarName, 0, L"");\r
a405b86d 1262 }\r
47d20b54
MK
1263\r
1264 TempHandle = CreateFileInterfaceEnv (StdErrVarName);\r
1265 ASSERT (TempHandle != NULL);\r
a405b86d 1266 ShellParameters->StdErr = TempHandle;\r
47d20b54 1267 gST->StdErr = CreateSimpleTextOutOnFile (TempHandle, &gST->StandardErrorHandle, gST->StdErr);\r
a405b86d 1268 }\r
1269\r
1270 //\r
1271 // StdIn from a var\r
1272 //\r
47d20b54
MK
1273 if (!EFI_ERROR (Status) && (StdInVarName != NULL)) {\r
1274 TempHandle = CreateFileInterfaceEnv (StdInVarName);\r
532691c8 1275 if (TempHandle == NULL) {\r
1276 Status = EFI_OUT_OF_RESOURCES;\r
a405b86d 1277 } else {\r
532691c8 1278 if (!InUnicode) {\r
47d20b54 1279 TempHandle = CreateFileInterfaceFile (TempHandle, FALSE);\r
532691c8 1280 }\r
47d20b54 1281\r
532691c8 1282 Size = 0;\r
47d20b54 1283 if ((TempHandle == NULL) || (((EFI_FILE_PROTOCOL *)TempHandle)->Read (TempHandle, &Size, NULL) != EFI_BUFFER_TOO_SMALL)) {\r
532691c8 1284 Status = EFI_INVALID_PARAMETER;\r
1285 } else {\r
1286 ShellParameters->StdIn = TempHandle;\r
47d20b54 1287 gST->ConIn = CreateSimpleTextInOnFile (TempHandle, &gST->ConsoleInHandle);\r
532691c8 1288 }\r
a405b86d 1289 }\r
1290 }\r
1291\r
1292 //\r
1293 // StdIn from a file\r
1294 //\r
47d20b54
MK
1295 if (!EFI_ERROR (Status) && (StdInFileName != NULL)) {\r
1296 Status = ShellOpenFileByName (\r
1297 StdInFileName,\r
1298 &TempHandle,\r
1299 EFI_FILE_MODE_READ,\r
1300 0\r
1301 );\r
1302 if (!EFI_ERROR (Status)) {\r
231ad7d8
QS
1303 if (!InUnicode) {\r
1304 //\r
1305 // Create the ASCII->Unicode conversion layer\r
1306 //\r
47d20b54 1307 TempHandle = CreateFileInterfaceFile (TempHandle, FALSE);\r
231ad7d8 1308 }\r
47d20b54 1309\r
a405b86d 1310 ShellParameters->StdIn = TempHandle;\r
47d20b54 1311 gST->ConIn = CreateSimpleTextInOnFile (TempHandle, &gST->ConsoleInHandle);\r
a405b86d 1312 }\r
1313 }\r
1314 }\r
1315 }\r
8be0ba36 1316\r
47d20b54
MK
1317 FreePool (CommandLineCopy);\r
1318\r
1319 CalculateEfiHdrCrc (&gST->Hdr);\r
cf6a8f14 1320\r
47d20b54 1321 if ((gST->ConIn == NULL) || (gST->ConOut == NULL)) {\r
cc31ac1e 1322 Status = EFI_OUT_OF_RESOURCES;\r
8be0ba36 1323 }\r
cc31ac1e
JC
1324\r
1325 if (Status == EFI_NOT_FOUND) {\r
47d20b54
MK
1326 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);\r
1327 } else if (EFI_ERROR (Status)) {\r
1328 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);\r
cc31ac1e
JC
1329 }\r
1330\r
a405b86d 1331 return (Status);\r
1332}\r
1333\r
1334/**\r
6a5033ca 1335 Function will replace the current StdIn and StdOut in the ShellParameters protocol\r
a405b86d 1336 structure with StdIn and StdOut. The current values are de-allocated.\r
1337\r
4ff7e37b
ED
1338 @param[in, out] ShellParameters Pointer to parameter structure to modify.\r
1339 @param[in] OldStdIn Pointer to old StdIn.\r
1340 @param[in] OldStdOut Pointer to old StdOut.\r
1341 @param[in] OldStdErr Pointer to old StdErr.\r
1342 @param[in] SystemTableInfo Pointer to old system table information.\r
a405b86d 1343**/\r
1344EFI_STATUS\r
a405b86d 1345RestoreStdInStdOutStdErr (\r
1346 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
8be0ba36 1347 IN SHELL_FILE_HANDLE *OldStdIn,\r
1348 IN SHELL_FILE_HANDLE *OldStdOut,\r
1349 IN SHELL_FILE_HANDLE *OldStdErr,\r
1350 IN SYSTEM_TABLE_INFO *SystemTableInfo\r
a405b86d 1351 )\r
1352{\r
47d20b54
MK
1353 SPLIT_LIST *Split;\r
1354\r
1355 if ( (ShellParameters == NULL)\r
1356 || (OldStdIn == NULL)\r
1357 || (OldStdOut == NULL)\r
1358 || (OldStdErr == NULL)\r
1359 || (SystemTableInfo == NULL))\r
1360 {\r
8be0ba36 1361 return (EFI_INVALID_PARAMETER);\r
1362 }\r
47d20b54
MK
1363\r
1364 if (!IsListEmpty (&ShellInfoObject.SplitList.Link)) {\r
1365 Split = (SPLIT_LIST *)GetFirstNode (&ShellInfoObject.SplitList.Link);\r
a405b86d 1366 } else {\r
1367 Split = NULL;\r
1368 }\r
47d20b54 1369\r
8be0ba36 1370 if (ShellParameters->StdIn != *OldStdIn) {\r
47d20b54
MK
1371 if (((Split != NULL) && (Split->SplitStdIn != ShellParameters->StdIn)) || (Split == NULL)) {\r
1372 gEfiShellProtocol->CloseFile (ShellParameters->StdIn);\r
a405b86d 1373 }\r
47d20b54 1374\r
8be0ba36 1375 ShellParameters->StdIn = *OldStdIn;\r
a405b86d 1376 }\r
47d20b54 1377\r
8be0ba36 1378 if (ShellParameters->StdOut != *OldStdOut) {\r
47d20b54
MK
1379 if (((Split != NULL) && (Split->SplitStdOut != ShellParameters->StdOut)) || (Split == NULL)) {\r
1380 gEfiShellProtocol->CloseFile (ShellParameters->StdOut);\r
a405b86d 1381 }\r
47d20b54 1382\r
8be0ba36 1383 ShellParameters->StdOut = *OldStdOut;\r
1384 }\r
47d20b54 1385\r
8be0ba36 1386 if (ShellParameters->StdErr != *OldStdErr) {\r
47d20b54 1387 gEfiShellProtocol->CloseFile (ShellParameters->StdErr);\r
8be0ba36 1388 ShellParameters->StdErr = *OldStdErr;\r
1389 }\r
1390\r
1391 if (gST->ConIn != SystemTableInfo->ConIn) {\r
47d20b54
MK
1392 CloseSimpleTextInOnFile (gST->ConIn);\r
1393 gST->ConIn = SystemTableInfo->ConIn;\r
1394 gST->ConsoleInHandle = SystemTableInfo->ConInHandle;\r
a405b86d 1395 }\r
47d20b54 1396\r
8be0ba36 1397 if (gST->ConOut != SystemTableInfo->ConOut) {\r
47d20b54
MK
1398 CloseSimpleTextOutOnFile (gST->ConOut);\r
1399 gST->ConOut = SystemTableInfo->ConOut;\r
1400 gST->ConsoleOutHandle = SystemTableInfo->ConOutHandle;\r
8be0ba36 1401 }\r
47d20b54 1402\r
4ccd9214 1403 if (gST->StdErr != SystemTableInfo->ErrOut) {\r
47d20b54
MK
1404 CloseSimpleTextOutOnFile (gST->StdErr);\r
1405 gST->StdErr = SystemTableInfo->ErrOut;\r
1406 gST->StandardErrorHandle = SystemTableInfo->ErrOutHandle;\r
8be0ba36 1407 }\r
1408\r
47d20b54 1409 CalculateEfiHdrCrc (&gST->Hdr);\r
cf6a8f14 1410\r
a405b86d 1411 return (EFI_SUCCESS);\r
1412}\r
47d20b54 1413\r
a405b86d 1414/**\r
6a5033ca 1415 Function will replace the current Argc and Argv in the ShellParameters protocol\r
a405b86d 1416 structure by parsing NewCommandLine. The current values are returned to the\r
1417 user.\r
1418\r
1419 If OldArgv or OldArgc is NULL then that value is not returned.\r
1420\r
4ff7e37b
ED
1421 @param[in, out] ShellParameters Pointer to parameter structure to modify.\r
1422 @param[in] NewCommandLine The new command line to parse and use.\r
d1c275c6 1423 @param[in] Type The type of operation.\r
4ff7e37b
ED
1424 @param[out] OldArgv Pointer to old list of parameters.\r
1425 @param[out] OldArgc Pointer to old number of items in Argv list.\r
a405b86d 1426\r
7f9e354a 1427\r
6a5033ca 1428 @retval EFI_SUCCESS Operation was successful, Argv and Argc are valid.\r
7f9e354a 1429 @return EFI_INVALID_PARAMETER Some parameters are invalid.\r
a405b86d 1430 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
1431**/\r
1432EFI_STATUS\r
47d20b54 1433UpdateArgcArgv (\r
a405b86d 1434 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
1435 IN CONST CHAR16 *NewCommandLine,\r
d1c275c6 1436 IN SHELL_OPERATION_TYPES Type,\r
a405b86d 1437 OUT CHAR16 ***OldArgv OPTIONAL,\r
1438 OUT UINTN *OldArgc OPTIONAL\r
1439 )\r
1440{\r
47d20b54 1441 BOOLEAN StripParamQuotation;\r
ba0014b9 1442\r
47d20b54 1443 ASSERT (ShellParameters != NULL);\r
d1c275c6 1444 StripParamQuotation = TRUE;\r
a405b86d 1445\r
1446 if (OldArgc != NULL) {\r
1447 *OldArgc = ShellParameters->Argc;\r
1448 }\r
47d20b54 1449\r
a405b86d 1450 if (OldArgc != NULL) {\r
1451 *OldArgv = ShellParameters->Argv;\r
1452 }\r
1453\r
d1c275c6
QS
1454 if (Type == Script_File_Name) {\r
1455 StripParamQuotation = FALSE;\r
1456 }\r
ba0014b9 1457\r
47d20b54
MK
1458 return ParseCommandLineToArgs (\r
1459 NewCommandLine,\r
1460 StripParamQuotation,\r
1461 &(ShellParameters->Argv),\r
1462 &(ShellParameters->Argc)\r
1463 );\r
a405b86d 1464}\r
1465\r
1466/**\r
6a5033ca 1467 Function will replace the current Argc and Argv in the ShellParameters protocol\r
a405b86d 1468 structure with Argv and Argc. The current values are de-allocated and the\r
1469 OldArgv must not be deallocated by the caller.\r
1470\r
4ff7e37b
ED
1471 @param[in, out] ShellParameters pointer to parameter structure to modify\r
1472 @param[in] OldArgv pointer to old list of parameters\r
1473 @param[in] OldArgc pointer to old number of items in Argv list\r
a405b86d 1474**/\r
1475VOID\r
47d20b54 1476RestoreArgcArgv (\r
a405b86d 1477 IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
1478 IN CHAR16 ***OldArgv,\r
1479 IN UINTN *OldArgc\r
1480 )\r
1481{\r
47d20b54
MK
1482 UINTN LoopCounter;\r
1483\r
1484 ASSERT (ShellParameters != NULL);\r
1485 ASSERT (OldArgv != NULL);\r
1486 ASSERT (OldArgc != NULL);\r
a405b86d 1487\r
1488 if (ShellParameters->Argv != NULL) {\r
1489 for ( LoopCounter = 0\r
47d20b54
MK
1490 ; LoopCounter < ShellParameters->Argc\r
1491 ; LoopCounter++\r
1492 )\r
1493 {\r
1494 FreePool (ShellParameters->Argv[LoopCounter]);\r
a405b86d 1495 }\r
47d20b54
MK
1496\r
1497 FreePool (ShellParameters->Argv);\r
a405b86d 1498 }\r
47d20b54 1499\r
a405b86d 1500 ShellParameters->Argv = *OldArgv;\r
47d20b54 1501 *OldArgv = NULL;\r
a405b86d 1502 ShellParameters->Argc = *OldArgc;\r
47d20b54 1503 *OldArgc = 0;\r
a405b86d 1504}\r