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