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