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