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