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