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