TianoCore EDK2 master
Loading...
Searching...
No Matches
ShellProtocol.c
Go to the documentation of this file.
1
12#include "Shell.h"
13
14#define INIT_NAME_BUFFER_SIZE 128
15
28EFIAPI
30 IN SHELL_FILE_HANDLE FileHandle
31 )
32{
33 ShellFileHandleRemove (FileHandle);
35}
36
46BOOLEAN
49 )
50{
51 EFI_DEVICE_PATH_PROTOCOL *DevicePathCopy;
52 EFI_STATUS Status;
53 EFI_HANDLE Handle;
54
55 Handle = NULL;
56
57 DevicePathCopy = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
58 Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathCopy, &Handle);
59
60 if ((Handle != NULL) && (!EFI_ERROR (Status))) {
61 return (TRUE);
62 }
63
64 return (FALSE);
65}
66
76BOOLEAN
79 )
80{
81 EFI_DEVICE_PATH_PROTOCOL *DevicePathCopy;
82 EFI_STATUS Status;
83 EFI_HANDLE Handle;
84
85 Handle = NULL;
86
87 DevicePathCopy = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
88 Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathCopy, &Handle);
89
90 if ((Handle != NULL) && (!EFI_ERROR (Status))) {
91 return (TRUE);
92 }
93
94 return (FALSE);
95}
96
117EFIAPI
119 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
120 IN CONST CHAR16 *Mapping
121 )
122{
123 EFI_STATUS Status;
124 SHELL_MAP_LIST *MapListNode;
125
126 if (Mapping == NULL) {
127 return (EFI_INVALID_PARAMETER);
128 }
129
130 if (Mapping[StrLen (Mapping)-1] != ':') {
131 return (EFI_INVALID_PARAMETER);
132 }
133
134 //
135 // Delete the mapping
136 //
137 if (DevicePath == NULL) {
138 if (IsListEmpty (&gShellMapList.Link)) {
139 return (EFI_NOT_FOUND);
140 }
141
142 for ( MapListNode = (SHELL_MAP_LIST *)GetFirstNode (&gShellMapList.Link)
143 ; !IsNull (&gShellMapList.Link, &MapListNode->Link)
144 ; MapListNode = (SHELL_MAP_LIST *)GetNextNode (&gShellMapList.Link, &MapListNode->Link)
145 )
146 {
147 if (StringNoCaseCompare (&MapListNode->MapName, &Mapping) == 0) {
148 RemoveEntryList (&MapListNode->Link);
149 SHELL_FREE_NON_NULL (MapListNode->DevicePath);
150 SHELL_FREE_NON_NULL (MapListNode->MapName);
151 SHELL_FREE_NON_NULL (MapListNode->CurrentDirectoryPath);
152 FreePool (MapListNode);
153 return (EFI_SUCCESS);
154 }
155 } // for loop
156
157 //
158 // We didn't find one to delete
159 //
160 return (EFI_NOT_FOUND);
161 }
162
163 //
164 // make sure this is a valid to add device path
165 //
169 {
170 return (EFI_INVALID_PARAMETER);
171 }
172
173 //
174 // First make sure there is no old mapping
175 //
176 Status = EfiShellSetMap (NULL, Mapping);
177 if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_FOUND)) {
178 return (Status);
179 }
180
181 //
182 // now add the new one.
183 //
184 Status = ShellCommandAddMapItemAndUpdatePath (Mapping, DevicePath, 0, FALSE);
185
186 return (Status);
187}
188
203EFIAPI
205 IN CONST CHAR16 *Mapping
206 )
207{
208 SHELL_MAP_LIST *MapListItem;
209 CHAR16 *NewName;
210 UINTN Size;
211
212 NewName = NULL;
213 Size = 0;
214
215 StrnCatGrow (&NewName, &Size, Mapping, 0);
216 if (Mapping[StrLen (Mapping)-1] != L':') {
217 StrnCatGrow (&NewName, &Size, L":", 0);
218 }
219
220 MapListItem = ShellCommandFindMapItem (NewName);
221
222 FreePool (NewName);
223
224 if (MapListItem != NULL) {
225 return (MapListItem->DevicePath);
226 }
227
228 return (NULL);
229}
230
251CONST CHAR16 *
252EFIAPI
254 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
255 )
256{
257 SHELL_MAP_LIST *Node;
258 CHAR16 *PathForReturn;
259 UINTN PathSize;
260
261 // EFI_HANDLE PathHandle;
262 // EFI_HANDLE MapHandle;
263 // EFI_STATUS Status;
264 // EFI_DEVICE_PATH_PROTOCOL *DevicePathCopy;
265 // EFI_DEVICE_PATH_PROTOCOL *MapPathCopy;
266
267 if ((DevicePath == NULL) || (*DevicePath == NULL)) {
268 return (NULL);
269 }
270
271 PathForReturn = NULL;
272 PathSize = 0;
273
274 for ( Node = (SHELL_MAP_LIST *)GetFirstNode (&gShellMapList.Link)
275 ; !IsNull (&gShellMapList.Link, &Node->Link)
276 ; Node = (SHELL_MAP_LIST *)GetNextNode (&gShellMapList.Link, &Node->Link)
277 )
278 {
279 //
280 // check for exact match
281 //
282 if (DevicePathCompare (DevicePath, &Node->DevicePath) == 0) {
283 ASSERT ((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));
284 if (PathSize != 0) {
285 PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, L";", 0);
286 }
287
288 PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, Node->MapName, 0);
289 }
290 }
291
292 if (PathForReturn != NULL) {
293 while (!IsDevicePathEndType (*DevicePath)) {
294 *DevicePath = NextDevicePathNode (*DevicePath);
295 }
296
297 //
298 // Do not call SetDevicePathEndNode() if the device path node is already the
299 // end of an entire device path.
300 //
301 if (!IsDevicePathEnd (*DevicePath)) {
302 SetDevicePathEndNode (*DevicePath);
303 }
304 }
305
306 /*
308 if (PathForReturn == NULL) {
309 PathSize = 0;
310
311 DevicePathCopy = DuplicateDevicePath(*DevicePath);
312 ASSERT(DevicePathCopy != NULL);
313 Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, &DevicePathCopy, &PathHandle);
314 ASSERT_EFI_ERROR(Status);
315 //
316 // check each of the device paths we have to get the root of the path for consist mappings
317 //
318 for ( Node = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
319 ; !IsNull(&gShellMapList.Link, &Node->Link)
320 ; Node = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &Node->Link)
321 ){
322 if ((Node->Flags & SHELL_MAP_FLAGS_CONSIST) == 0) {
323 continue;
324 }
325 MapPathCopy = DuplicateDevicePath(Node->DevicePath);
326 ASSERT(MapPathCopy != NULL);
327 Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, &MapPathCopy, &MapHandle);
328 if (MapHandle == PathHandle) {
329
330 *DevicePath = DevicePathCopy;
331
332 MapPathCopy = NULL;
333 DevicePathCopy = NULL;
334 PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, Node->MapName, 0);
335 PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, L";", 0);
336 break;
337 }
338 }
339 //
340 // now add on the non-consistent mappings
341 //
342 for ( Node = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
343 ; !IsNull(&gShellMapList.Link, &Node->Link)
344 ; Node = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &Node->Link)
345 ){
346 if ((Node->Flags & SHELL_MAP_FLAGS_CONSIST) != 0) {
347 continue;
348 }
349 MapPathCopy = Node->DevicePath;
350 ASSERT(MapPathCopy != NULL);
351 Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, &MapPathCopy, &MapHandle);
352 if (MapHandle == PathHandle) {
353 PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, Node->MapName, 0);
354 PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, L";", 0);
355 break;
356 }
357 }
358 }
359 */
360
361 return (AddBufferToFreeList (PathForReturn));
362}
363
377CHAR16 *
378EFIAPI
381 )
382{
383 EFI_DEVICE_PATH_PROTOCOL *DevicePathCopy;
384 EFI_DEVICE_PATH_PROTOCOL *MapPathCopy;
385 SHELL_MAP_LIST *MapListItem;
386 CHAR16 *PathForReturn;
387 UINTN PathSize;
388 EFI_HANDLE PathHandle;
389 EFI_HANDLE MapHandle;
390 EFI_STATUS Status;
391 FILEPATH_DEVICE_PATH *FilePath;
392 FILEPATH_DEVICE_PATH *AlignedNode;
393
394 PathForReturn = NULL;
395 PathSize = 0;
396
397 DevicePathCopy = (EFI_DEVICE_PATH_PROTOCOL *)Path;
398 ASSERT (DevicePathCopy != NULL);
399 if (DevicePathCopy == NULL) {
400 return (NULL);
401 }
402
404 Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathCopy, &PathHandle);
405
406 if (EFI_ERROR (Status)) {
407 return (NULL);
408 }
409
410 //
411 // check each of the device paths we have to get the root of the path
412 //
413 for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode (&gShellMapList.Link)
414 ; !IsNull (&gShellMapList.Link, &MapListItem->Link)
415 ; MapListItem = (SHELL_MAP_LIST *)GetNextNode (&gShellMapList.Link, &MapListItem->Link)
416 )
417 {
418 MapPathCopy = (EFI_DEVICE_PATH_PROTOCOL *)MapListItem->DevicePath;
419 ASSERT (MapPathCopy != NULL);
421 Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &MapPathCopy, &MapHandle);
422 if (MapHandle == PathHandle) {
423 ASSERT ((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));
424 PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, MapListItem->MapName, 0);
425 //
426 // go through all the remaining nodes in the device path
427 //
428 for ( FilePath = (FILEPATH_DEVICE_PATH *)DevicePathCopy
429 ; !IsDevicePathEnd (&FilePath->Header)
430 ; FilePath = (FILEPATH_DEVICE_PATH *)NextDevicePathNode (&FilePath->Header)
431 )
432 {
433 //
434 // If any node is not a file path node, then the conversion can not be completed
435 //
436 if ((DevicePathType (&FilePath->Header) != MEDIA_DEVICE_PATH) ||
437 (DevicePathSubType (&FilePath->Header) != MEDIA_FILEPATH_DP))
438 {
439 if (PathForReturn != NULL) {
440 FreePool (PathForReturn);
441 }
442
443 return NULL;
444 }
445
446 //
447 // append the path part onto the filepath.
448 //
449 ASSERT ((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL));
450
451 AlignedNode = AllocateCopyPool (DevicePathNodeLength (FilePath), FilePath);
452 if (AlignedNode == NULL) {
453 if (PathForReturn != NULL) {
454 FreePool (PathForReturn);
455 }
456
457 return NULL;
458 }
459
460 // File Path Device Path Nodes 'can optionally add a "\" separator to
461 // the beginning and/or the end of the Path Name string.'
462 // (UEFI Spec 2.4 section 9.3.6.4).
463 // If necessary, add a "\", but otherwise don't
464 // (This is specified in the above section, and also implied by the
465 // UEFI Shell spec section 3.7)
466 if ((PathSize != 0) &&
467 (PathForReturn != NULL) &&
468 (PathForReturn[PathSize / sizeof (CHAR16) - 1] != L'\\') &&
469 (AlignedNode->PathName[0] != L'\\'))
470 {
471 PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, L"\\", 1);
472 }
473
474 PathForReturn = StrnCatGrow (&PathForReturn, &PathSize, AlignedNode->PathName, 0);
475 FreePool (AlignedNode);
476 } // for loop of remaining nodes
477 }
478
479 if (PathForReturn != NULL) {
480 break;
481 }
482 } // for loop of paths to check
483
484 return (PathForReturn);
485}
486
501EFIAPI
503 IN CONST CHAR16 *Path
504 )
505{
506 CHAR16 *MapName;
507 CHAR16 *NewPath;
508 CONST CHAR16 *Cwd;
509 UINTN Size;
511 EFI_DEVICE_PATH_PROTOCOL *DevicePathCopy;
512 EFI_DEVICE_PATH_PROTOCOL *DevicePathCopyForFree;
513 EFI_DEVICE_PATH_PROTOCOL *DevicePathForReturn;
514 EFI_HANDLE Handle;
515 EFI_STATUS Status;
516
517 if (Path == NULL) {
518 return (NULL);
519 }
520
521 MapName = NULL;
522 NewPath = NULL;
523
524 if (StrStr (Path, L":") == NULL) {
525 Cwd = EfiShellGetCurDir (NULL);
526 if (Cwd == NULL) {
527 return (NULL);
528 }
529
530 Size = StrSize (Cwd) + StrSize (Path);
531 NewPath = AllocateZeroPool (Size);
532 if (NewPath == NULL) {
533 return (NULL);
534 }
535
536 StrCpyS (NewPath, Size/sizeof (CHAR16), Cwd);
537 StrCatS (NewPath, Size/sizeof (CHAR16), L"\\");
538 if (*Path == L'\\') {
539 Path++;
540 while (PathRemoveLastItem (NewPath)) {
541 }
542 }
543
544 StrCatS (NewPath, Size/sizeof (CHAR16), Path);
545 DevicePathForReturn = EfiShellGetDevicePathFromFilePath (NewPath);
546 FreePool (NewPath);
547 return (DevicePathForReturn);
548 }
549
550 Size = 0;
551 //
552 // find the part before (but including) the : for the map name
553 //
554 ASSERT ((MapName == NULL && Size == 0) || (MapName != NULL));
555 MapName = StrnCatGrow (&MapName, &Size, Path, (StrStr (Path, L":")-Path+1));
556 if ((MapName == NULL) || (MapName[StrLen (MapName)-1] != L':')) {
557 return (NULL);
558 }
559
560 //
561 // look up the device path in the map
562 //
563 DevicePath = EfiShellGetDevicePathFromMap (MapName);
564 if (DevicePath == NULL) {
565 //
566 // Must have been a bad Mapname
567 //
568 return (NULL);
569 }
570
571 //
572 // make a copy for LocateDevicePath to modify (also save a pointer to call FreePool with)
573 //
574 DevicePathCopyForFree = DevicePathCopy = DuplicateDevicePath (DevicePath);
575 if (DevicePathCopy == NULL) {
576 FreePool (MapName);
577 return (NULL);
578 }
579
580 //
581 // get the handle
582 //
584 Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathCopy, &Handle);
585 if (EFI_ERROR (Status)) {
586 if (DevicePathCopyForFree != NULL) {
587 FreePool (DevicePathCopyForFree);
588 }
589
590 FreePool (MapName);
591 return (NULL);
592 }
593
594 //
595 // build the full device path
596 //
597 if ((*(Path+StrLen (MapName)) != CHAR_NULL) &&
598 (*(Path+StrLen (MapName)+1) == CHAR_NULL))
599 {
600 DevicePathForReturn = FileDevicePath (Handle, L"\\");
601 } else {
602 DevicePathForReturn = FileDevicePath (Handle, Path+StrLen (MapName));
603 }
604
605 FreePool (MapName);
606 if (DevicePathCopyForFree != NULL) {
607 FreePool (DevicePathCopyForFree);
608 }
609
610 return (DevicePathForReturn);
611}
612
650EFIAPI
652 IN EFI_HANDLE DeviceHandle,
653 IN EFI_SHELL_DEVICE_NAME_FLAGS Flags,
654 IN CHAR8 *Language,
655 OUT CHAR16 **BestDeviceName
656 )
657{
658 EFI_STATUS Status;
660 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
661 EFI_HANDLE *HandleList;
662 UINTN HandleCount;
663 UINTN LoopVar;
664 CHAR16 *DeviceNameToReturn;
665 CHAR8 *Lang;
666 UINTN ParentControllerCount;
667 EFI_HANDLE *ParentControllerBuffer;
668 UINTN ParentDriverCount;
669 EFI_HANDLE *ParentDriverBuffer;
670
671 if ((BestDeviceName == NULL) ||
672 (DeviceHandle == NULL)
673 )
674 {
675 return (EFI_INVALID_PARAMETER);
676 }
677
678 //
679 // make sure one of the 2 supported bits is on
680 //
681 if (((Flags & EFI_DEVICE_NAME_USE_COMPONENT_NAME) == 0) &&
682 ((Flags & EFI_DEVICE_NAME_USE_DEVICE_PATH) == 0))
683 {
684 return (EFI_INVALID_PARAMETER);
685 }
686
687 DeviceNameToReturn = NULL;
688 *BestDeviceName = NULL;
689 HandleList = NULL;
690 HandleCount = 0;
691 Lang = NULL;
692
693 if ((Flags & EFI_DEVICE_NAME_USE_COMPONENT_NAME) != 0) {
695 NULL,
696 DeviceHandle,
697 HR_DRIVER_BINDING_HANDLE|HR_DEVICE_DRIVER,
698 &HandleCount,
699 &HandleList
700 );
701 for (LoopVar = 0; LoopVar < HandleCount; LoopVar++) {
702 //
703 // Go through those handles until we get one that passes for GetComponentName
704 //
705 Status = gBS->OpenProtocol (
706 HandleList[LoopVar],
707 &gEfiComponentName2ProtocolGuid,
708 (VOID **)&CompName2,
710 NULL,
711 EFI_OPEN_PROTOCOL_GET_PROTOCOL
712 );
713 if (EFI_ERROR (Status)) {
714 Status = gBS->OpenProtocol (
715 HandleList[LoopVar],
716 &gEfiComponentNameProtocolGuid,
717 (VOID **)&CompName2,
719 NULL,
720 EFI_OPEN_PROTOCOL_GET_PROTOCOL
721 );
722 }
723
724 if (EFI_ERROR (Status)) {
725 continue;
726 }
727
728 Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
729 if (Lang == NULL) {
730 continue;
731 }
732
733 Status = CompName2->GetControllerName (CompName2, DeviceHandle, NULL, Lang, &DeviceNameToReturn);
734 FreePool (Lang);
735 Lang = NULL;
736 if (!EFI_ERROR (Status) && (DeviceNameToReturn != NULL)) {
737 break;
738 }
739 }
740
741 if (HandleList != NULL) {
742 FreePool (HandleList);
743 }
744
745 //
746 // Now check the parent controller using this as the child.
747 //
748 Status = PARSE_HANDLE_DATABASE_PARENTS (DeviceHandle, &ParentControllerCount, &ParentControllerBuffer);
749 if ((DeviceNameToReturn == NULL) && !EFI_ERROR (Status)) {
750 for (LoopVar = 0; LoopVar < ParentControllerCount; LoopVar++) {
751 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (ParentControllerBuffer[LoopVar], &ParentDriverCount, &ParentDriverBuffer);
752 if (!EFI_ERROR (Status)) {
753 for (HandleCount = 0; HandleCount < ParentDriverCount; HandleCount++) {
754 //
755 // try using that driver's component name with controller and our driver as the child.
756 //
757 Status = gBS->OpenProtocol (
758 ParentDriverBuffer[HandleCount],
759 &gEfiComponentName2ProtocolGuid,
760 (VOID **)&CompName2,
762 NULL,
763 EFI_OPEN_PROTOCOL_GET_PROTOCOL
764 );
765 if (EFI_ERROR (Status)) {
766 Status = gBS->OpenProtocol (
767 ParentDriverBuffer[HandleCount],
768 &gEfiComponentNameProtocolGuid,
769 (VOID **)&CompName2,
771 NULL,
772 EFI_OPEN_PROTOCOL_GET_PROTOCOL
773 );
774 }
775
776 if (EFI_ERROR (Status)) {
777 continue;
778 }
779
780 Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
781 if (Lang == NULL) {
782 continue;
783 }
784
785 Status = CompName2->GetControllerName (CompName2, ParentControllerBuffer[LoopVar], DeviceHandle, Lang, &DeviceNameToReturn);
786 FreePool (Lang);
787 Lang = NULL;
788 if (!EFI_ERROR (Status) && (DeviceNameToReturn != NULL)) {
789 break;
790 }
791 }
792
793 SHELL_FREE_NON_NULL (ParentDriverBuffer);
794 if (!EFI_ERROR (Status) && (DeviceNameToReturn != NULL)) {
795 break;
796 }
797 }
798 }
799
800 SHELL_FREE_NON_NULL (ParentControllerBuffer);
801 }
802
803 //
804 // dont return on fail since we will try device path if that bit is on
805 //
806 if (DeviceNameToReturn != NULL) {
807 ASSERT (BestDeviceName != NULL);
808 StrnCatGrow (BestDeviceName, NULL, DeviceNameToReturn, 0);
809 return (EFI_SUCCESS);
810 }
811 }
812
813 if ((Flags & EFI_DEVICE_NAME_USE_DEVICE_PATH) != 0) {
814 Status = gBS->OpenProtocol (
815 DeviceHandle,
816 &gEfiDevicePathProtocolGuid,
817 (VOID **)&DevicePath,
819 NULL,
820 EFI_OPEN_PROTOCOL_GET_PROTOCOL
821 );
822 if (!EFI_ERROR (Status)) {
823 //
824 // use device path to text on the device path
825 //
826 *BestDeviceName = ConvertDevicePathToText (DevicePath, TRUE, TRUE);
827 return (EFI_SUCCESS);
828 }
829 }
830
831 //
832 // none of the selected bits worked.
833 //
834 return (EFI_NOT_FOUND);
835}
836
854EFIAPI
856 IN EFI_HANDLE DeviceHandle,
857 OUT SHELL_FILE_HANDLE *FileHandle
858 )
859{
860 EFI_STATUS Status;
861 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
862 EFI_FILE_PROTOCOL *RealFileHandle;
864
865 //
866 // get the simple file system interface
867 //
868 Status = gBS->OpenProtocol (
869 DeviceHandle,
870 &gEfiSimpleFileSystemProtocolGuid,
871 (VOID **)&SimpleFileSystem,
873 NULL,
874 EFI_OPEN_PROTOCOL_GET_PROTOCOL
875 );
876 if (EFI_ERROR (Status)) {
877 return (EFI_NOT_FOUND);
878 }
879
880 Status = gBS->OpenProtocol (
881 DeviceHandle,
882 &gEfiDevicePathProtocolGuid,
883 (VOID **)&DevPath,
885 NULL,
886 EFI_OPEN_PROTOCOL_GET_PROTOCOL
887 );
888 if (EFI_ERROR (Status)) {
889 return (EFI_NOT_FOUND);
890 }
891
892 //
893 // Open the root volume now...
894 //
895 Status = SimpleFileSystem->OpenVolume (SimpleFileSystem, &RealFileHandle);
896 if (EFI_ERROR (Status)) {
897 return Status;
898 }
899
900 *FileHandle = ConvertEfiFileProtocolToShellHandle (RealFileHandle, EfiShellGetMapFromDevicePath (&DevPath));
901 return (EFI_SUCCESS);
902}
903
922EFIAPI
924 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
925 OUT SHELL_FILE_HANDLE *FileHandle
926 )
927{
928 EFI_STATUS Status;
929 EFI_HANDLE Handle;
930
931 if (FileHandle == NULL) {
932 return (EFI_INVALID_PARAMETER);
933 }
934
935 //
936 // find the handle of the device with that device handle and the file system
937 //
939 Status = gBS->LocateDevicePath (
940 &gEfiSimpleFileSystemProtocolGuid,
941 &DevicePath,
942 &Handle
943 );
944 if (EFI_ERROR (Status)) {
945 return (EFI_NOT_FOUND);
946 }
947
948 return (EfiShellOpenRootByHandle (Handle, FileHandle));
949}
950
958BOOLEAN
959EFIAPI
961 VOID
962 )
963{
965 return (FALSE);
966 }
967
968 return (TRUE);
969}
970
986 IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath,
987 OUT SHELL_FILE_HANDLE *FileHandle,
988 IN UINT64 OpenMode,
989 IN UINT64 Attributes OPTIONAL
990 )
991{
992 EFI_STATUS Status;
993 FILEPATH_DEVICE_PATH *FilePathNode;
994 EFI_HANDLE Handle;
995 SHELL_FILE_HANDLE ShellHandle;
996 EFI_FILE_PROTOCOL *Handle1;
997 EFI_FILE_PROTOCOL *Handle2;
998 FILEPATH_DEVICE_PATH *AlignedNode;
999
1000 if (FileHandle == NULL) {
1001 return (EFI_INVALID_PARAMETER);
1002 }
1003
1004 *FileHandle = NULL;
1005 Handle1 = NULL;
1006 Handle2 = NULL;
1007 Handle = NULL;
1008 ShellHandle = NULL;
1009 FilePathNode = NULL;
1010 AlignedNode = NULL;
1011
1012 Status = EfiShellOpenRoot (DevicePath, &ShellHandle);
1013
1014 if (!EFI_ERROR (Status)) {
1015 Handle1 = ConvertShellHandleToEfiFileProtocol (ShellHandle);
1016 if (Handle1 != NULL) {
1017 //
1018 // chop off the beginning part before the file system part...
1019 //
1021 Status = gBS->LocateDevicePath (
1022 &gEfiSimpleFileSystemProtocolGuid,
1023 &DevicePath,
1024 &Handle
1025 );
1026 if (!EFI_ERROR (Status)) {
1027 //
1028 // To access as a file system, the file path should only
1029 // contain file path components. Follow the file path nodes
1030 // and find the target file
1031 //
1032 for ( FilePathNode = (FILEPATH_DEVICE_PATH *)DevicePath
1033 ; !IsDevicePathEnd (&FilePathNode->Header)
1034 ; FilePathNode = (FILEPATH_DEVICE_PATH *)NextDevicePathNode (&FilePathNode->Header)
1035 )
1036 {
1037 SHELL_FREE_NON_NULL (AlignedNode);
1038 AlignedNode = AllocateCopyPool (DevicePathNodeLength (FilePathNode), FilePathNode);
1039 //
1040 // For file system access each node should be a file path component
1041 //
1042 if ((DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH) ||
1043 (DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP)
1044 )
1045 {
1046 Status = EFI_UNSUPPORTED;
1047 break;
1048 }
1049
1050 //
1051 // Open this file path node
1052 //
1053 Handle2 = Handle1;
1054 Handle1 = NULL;
1055
1056 //
1057 // if this is the last node in the DevicePath always create (if that was requested).
1058 //
1059 if (IsDevicePathEnd ((NextDevicePathNode (&FilePathNode->Header)))) {
1060 Status = Handle2->Open (
1061 Handle2,
1062 &Handle1,
1063 AlignedNode->PathName,
1064 OpenMode,
1065 Attributes
1066 );
1067 } else {
1068 //
1069 // This is not the last node and we dont want to 'create' existing
1070 // directory entries...
1071 //
1072
1073 //
1074 // open without letting it create
1075 // prevents error on existing files/directories
1076 //
1077 Status = Handle2->Open (
1078 Handle2,
1079 &Handle1,
1080 AlignedNode->PathName,
1081 OpenMode &~EFI_FILE_MODE_CREATE,
1082 Attributes
1083 );
1084 //
1085 // if above failed now open and create the 'item'
1086 // if OpenMode EFI_FILE_MODE_CREATE bit was on (but disabled above)
1087 //
1088 if ((EFI_ERROR (Status)) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) {
1089 Status = Handle2->Open (
1090 Handle2,
1091 &Handle1,
1092 AlignedNode->PathName,
1093 OpenMode,
1094 Attributes
1095 );
1096 }
1097 }
1098
1099 //
1100 // Close the last node
1101 //
1102 ShellInfoObject.NewEfiShellProtocol->CloseFile (Handle2);
1103
1104 //
1105 // If there's been an error, stop
1106 //
1107 if (EFI_ERROR (Status)) {
1108 break;
1109 }
1110 } // for loop
1111 }
1112 }
1113 }
1114
1115 SHELL_FREE_NON_NULL (AlignedNode);
1116 if (EFI_ERROR (Status)) {
1117 if (Handle1 != NULL) {
1118 ShellInfoObject.NewEfiShellProtocol->CloseFile (Handle1);
1119 }
1120 } else {
1121 *FileHandle = ConvertEfiFileProtocolToShellHandle (Handle1, ShellFileHandleGetPath (ShellHandle));
1122 }
1123
1124 return (Status);
1125}
1126
1164EFIAPI
1166 IN CONST CHAR16 *FileName,
1167 IN UINT64 FileAttribs,
1168 OUT SHELL_FILE_HANDLE *FileHandle
1169 )
1170{
1171 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
1172 EFI_STATUS Status;
1173 BOOLEAN Volatile;
1174
1175 //
1176 // Is this for an environment variable
1177 // do we start with >v
1178 //
1179 if (StrStr (FileName, L">v") == FileName) {
1180 Status = IsVolatileEnv (FileName + 2, &Volatile);
1181 if (EFI_ERROR (Status)) {
1182 return Status;
1183 }
1184
1185 if (!Volatile) {
1186 return (EFI_INVALID_PARAMETER);
1187 }
1188
1189 *FileHandle = CreateFileInterfaceEnv (FileName+2);
1190 return (EFI_SUCCESS);
1191 }
1192
1193 //
1194 // We are opening a regular file.
1195 //
1196 DevicePath = EfiShellGetDevicePathFromFilePath (FileName);
1197 if (DevicePath == NULL) {
1198 return (EFI_NOT_FOUND);
1199 }
1200
1201 Status = InternalOpenFileDevicePath (DevicePath, FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, FileAttribs);
1202 FreePool (DevicePath);
1203
1204 return (Status);
1205}
1206
1225EFIAPI
1227 IN CONST EFI_GUID *Guid,
1228 IN CONST CHAR16 *GuidName
1229 )
1230{
1231 return (AddNewGuidNameMapping (Guid, GuidName, NULL));
1232}
1233
1287EFIAPI
1289 IN CONST CHAR16 *FileName,
1290 OUT SHELL_FILE_HANDLE *FileHandle,
1291 IN UINT64 OpenMode
1292 )
1293{
1294 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
1295 EFI_STATUS Status;
1296 BOOLEAN Volatile;
1297
1298 *FileHandle = NULL;
1299
1300 //
1301 // Is this for StdIn
1302 //
1303 if (StrCmp (FileName, L">i") == 0) {
1304 //
1305 // make sure not writing to StdIn
1306 //
1307 if ((OpenMode & EFI_FILE_MODE_WRITE) != 0) {
1308 return (EFI_INVALID_PARAMETER);
1309 }
1310
1311 *FileHandle = ShellInfoObject.NewShellParametersProtocol->StdIn;
1312 ASSERT (*FileHandle != NULL);
1313 return (EFI_SUCCESS);
1314 }
1315
1316 //
1317 // Is this for StdOut
1318 //
1319 if (StrCmp (FileName, L">o") == 0) {
1320 //
1321 // make sure not writing to StdIn
1322 //
1323 if ((OpenMode & EFI_FILE_MODE_READ) != 0) {
1324 return (EFI_INVALID_PARAMETER);
1325 }
1326
1327 *FileHandle = &FileInterfaceStdOut;
1328 return (EFI_SUCCESS);
1329 }
1330
1331 //
1332 // Is this for NUL / NULL file
1333 //
1334 if ((gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)FileName, L"NUL") == 0) ||
1335 (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)FileName, L"NULL") == 0))
1336 {
1337 *FileHandle = &FileInterfaceNulFile;
1338 return (EFI_SUCCESS);
1339 }
1340
1341 //
1342 // Is this for StdErr
1343 //
1344 if (StrCmp (FileName, L">e") == 0) {
1345 //
1346 // make sure not writing to StdIn
1347 //
1348 if ((OpenMode & EFI_FILE_MODE_READ) != 0) {
1349 return (EFI_INVALID_PARAMETER);
1350 }
1351
1352 *FileHandle = &FileInterfaceStdErr;
1353 return (EFI_SUCCESS);
1354 }
1355
1356 //
1357 // Is this for an environment variable
1358 // do we start with >v
1359 //
1360 if (StrStr (FileName, L">v") == FileName) {
1361 Status = IsVolatileEnv (FileName + 2, &Volatile);
1362 if (EFI_ERROR (Status)) {
1363 return Status;
1364 }
1365
1366 if (!Volatile &&
1367 ((OpenMode & EFI_FILE_MODE_WRITE) != 0))
1368 {
1369 return (EFI_INVALID_PARAMETER);
1370 }
1371
1372 *FileHandle = CreateFileInterfaceEnv (FileName+2);
1373 return (EFI_SUCCESS);
1374 }
1375
1376 //
1377 // We are opening a regular file.
1378 //
1379 DevicePath = EfiShellGetDevicePathFromFilePath (FileName);
1380
1381 if (DevicePath == NULL) {
1382 return (EFI_NOT_FOUND);
1383 }
1384
1385 //
1386 // Copy the device path, open the file, then free the memory
1387 //
1388 Status = InternalOpenFileDevicePath (DevicePath, FileHandle, OpenMode, 0); // 0 = no specific file attributes
1389 FreePool (DevicePath);
1390
1391 return (Status);
1392}
1393
1406EFIAPI
1408 IN CONST CHAR16 *FileName
1409 )
1410{
1411 SHELL_FILE_HANDLE FileHandle;
1412 EFI_STATUS Status;
1413
1414 FileHandle = NULL;
1415
1416 //
1417 // get a handle to the file
1418 //
1419 Status = EfiShellCreateFile (
1420 FileName,
1421 0,
1422 &FileHandle
1423 );
1424 if (EFI_ERROR (Status)) {
1425 return (Status);
1426 }
1427
1428 //
1429 // now delete the file
1430 //
1431 ShellFileHandleRemove (FileHandle);
1432 return (ShellInfoObject.NewEfiShellProtocol->DeleteFile (FileHandle));
1433}
1434
1438VOID
1439EFIAPI
1441 VOID
1442 )
1443{
1444 ShellInfoObject.PageBreakEnabled = FALSE;
1445}
1446
1450VOID
1451EFIAPI
1453 VOID
1454 )
1455{
1456 ShellInfoObject.PageBreakEnabled = TRUE;
1457}
1458
1483 IN CONST EFI_HANDLE *ParentImageHandle,
1484 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1485 IN CONST CHAR16 *CommandLine OPTIONAL,
1486 IN CONST CHAR16 **Environment OPTIONAL,
1487 OUT EFI_STATUS *StartImageStatus OPTIONAL
1488 )
1489{
1490 EFI_STATUS Status;
1491 EFI_STATUS StartStatus;
1492 EFI_STATUS CleanupStatus;
1493 EFI_HANDLE NewHandle;
1494 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
1495 LIST_ENTRY OrigEnvs;
1496 EFI_SHELL_PARAMETERS_PROTOCOL ShellParamsProtocol;
1497 CHAR16 *ImagePath;
1498 UINTN Index;
1499 CHAR16 *Walker;
1500 CHAR16 *NewCmdLine;
1501
1502 if (ParentImageHandle == NULL) {
1503 return (EFI_INVALID_PARAMETER);
1504 }
1505
1506 InitializeListHead (&OrigEnvs);
1507 ZeroMem (&ShellParamsProtocol, sizeof (EFI_SHELL_PARAMETERS_PROTOCOL));
1508
1509 NewHandle = NULL;
1510
1511 NewCmdLine = AllocateCopyPool (StrSize (CommandLine), CommandLine);
1512 if (NewCmdLine == NULL) {
1513 return EFI_OUT_OF_RESOURCES;
1514 }
1515
1516 for (Walker = NewCmdLine; Walker != NULL && *Walker != CHAR_NULL; Walker++) {
1517 if ((*Walker == L'^') && (*(Walker+1) == L'#')) {
1518 CopyMem (Walker, Walker+1, StrSize (Walker) - sizeof (Walker[0]));
1519 }
1520 }
1521
1522 //
1523 // Load the image with:
1524 // FALSE - not from boot manager and NULL, 0 being not already in memory
1525 //
1526 Status = gBS->LoadImage (
1527 FALSE,
1528 *ParentImageHandle,
1529 (EFI_DEVICE_PATH_PROTOCOL *)DevicePath,
1530 NULL,
1531 0,
1532 &NewHandle
1533 );
1534
1535 if (EFI_ERROR (Status)) {
1536 if (NewHandle != NULL) {
1537 gBS->UnloadImage (NewHandle);
1538 }
1539
1540 FreePool (NewCmdLine);
1541 return (Status);
1542 }
1543
1544 Status = gBS->OpenProtocol (
1545 NewHandle,
1546 &gEfiLoadedImageProtocolGuid,
1547 (VOID **)&LoadedImage,
1549 NULL,
1550 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1551 );
1552
1553 if (!EFI_ERROR (Status)) {
1554 //
1555 // If the image is not an app abort it.
1556 //
1557 if (LoadedImage->ImageCodeType != EfiLoaderCode) {
1559 -1,
1560 -1,
1561 NULL,
1562 STRING_TOKEN (STR_SHELL_IMAGE_NOT_APP),
1563 ShellInfoObject.HiiHandle
1564 );
1565 goto UnloadImage;
1566 }
1567
1568 ASSERT (LoadedImage->LoadOptionsSize == 0);
1569 if (NewCmdLine != NULL) {
1570 LoadedImage->LoadOptionsSize = (UINT32)StrSize (NewCmdLine);
1571 LoadedImage->LoadOptions = (VOID *)NewCmdLine;
1572 }
1573
1574 //
1575 // Save our current environment settings for later restoration if necessary
1576 //
1577 if (Environment != NULL) {
1578 Status = GetEnvironmentVariableList (&OrigEnvs);
1579 if (!EFI_ERROR (Status)) {
1580 Status = SetEnvironmentVariables (Environment);
1581 }
1582 }
1583
1584 //
1585 // Initialize and install a shell parameters protocol on the image.
1586 //
1587 ShellParamsProtocol.StdIn = ShellInfoObject.NewShellParametersProtocol->StdIn;
1588 ShellParamsProtocol.StdOut = ShellInfoObject.NewShellParametersProtocol->StdOut;
1589 ShellParamsProtocol.StdErr = ShellInfoObject.NewShellParametersProtocol->StdErr;
1590 Status = UpdateArgcArgv (&ShellParamsProtocol, NewCmdLine, Efi_Application, NULL, NULL);
1591 if (EFI_ERROR (Status)) {
1592 goto UnloadImage;
1593 }
1594
1595 //
1596 // Replace Argv[0] with the full path of the binary we're executing:
1597 // If the command line was "foo", the binary might be called "foo.efi".
1598 // "The first entry in [Argv] is always the full file path of the
1599 // executable" - UEFI Shell Spec section 2.3
1600 //
1601 ImagePath = EfiShellGetFilePathFromDevicePath (DevicePath);
1602 // The image we're executing isn't necessarily in a filesystem - it might
1603 // be memory mapped. In this case EfiShellGetFilePathFromDevicePath will
1604 // return NULL, and we'll leave Argv[0] as UpdateArgcArgv set it.
1605 if (ImagePath != NULL) {
1606 if (ShellParamsProtocol.Argv == NULL) {
1607 // Command line was empty or null.
1608 // (UpdateArgcArgv sets Argv to NULL when CommandLine is "" or NULL)
1609 ShellParamsProtocol.Argv = AllocatePool (sizeof (CHAR16 *));
1610 if (ShellParamsProtocol.Argv == NULL) {
1611 Status = EFI_OUT_OF_RESOURCES;
1612 goto UnloadImage;
1613 }
1614
1615 ShellParamsProtocol.Argc = 1;
1616 } else {
1617 // Free the string UpdateArgcArgv put in Argv[0];
1618 FreePool (ShellParamsProtocol.Argv[0]);
1619 }
1620
1621 ShellParamsProtocol.Argv[0] = ImagePath;
1622 }
1623
1624 Status = gBS->InstallProtocolInterface (&NewHandle, &gEfiShellParametersProtocolGuid, EFI_NATIVE_INTERFACE, &ShellParamsProtocol);
1625 ASSERT_EFI_ERROR (Status);
1626
1628
1629 //
1630 // now start the image and if the caller wanted the return code pass it to them...
1631 //
1632 if (!EFI_ERROR (Status)) {
1633 StartStatus = gBS->StartImage (
1634 NewHandle,
1635 0,
1636 NULL
1637 );
1638 if (StartImageStatus != NULL) {
1639 *StartImageStatus = StartStatus;
1640 }
1641
1642 CleanupStatus = gBS->UninstallProtocolInterface (
1643 NewHandle,
1644 &gEfiShellParametersProtocolGuid,
1645 &ShellParamsProtocol
1646 );
1647 ASSERT_EFI_ERROR (CleanupStatus);
1648
1649 goto FreeAlloc;
1650 }
1651
1652UnloadImage:
1653 // Unload image - We should only get here if we didn't call StartImage
1654 gBS->UnloadImage (NewHandle);
1655
1656FreeAlloc:
1657 // Free Argv (Allocated in UpdateArgcArgv)
1658 if (ShellParamsProtocol.Argv != NULL) {
1659 for (Index = 0; Index < ShellParamsProtocol.Argc; Index++) {
1660 if (ShellParamsProtocol.Argv[Index] != NULL) {
1661 FreePool (ShellParamsProtocol.Argv[Index]);
1662 }
1663 }
1664
1665 FreePool (ShellParamsProtocol.Argv);
1666 }
1667 }
1668
1669 // Restore environment variables
1670 if (!IsListEmpty (&OrigEnvs)) {
1671 CleanupStatus = SetEnvironmentVariableList (&OrigEnvs);
1672 ASSERT_EFI_ERROR (CleanupStatus);
1673 }
1674
1675 FreePool (NewCmdLine);
1676
1677 return (Status);
1678}
1679
1701 IN CONST CHAR16 *CommandLine OPTIONAL,
1702 IN CONST CHAR16 **Environment OPTIONAL,
1703 OUT EFI_STATUS *StartImageStatus OPTIONAL
1704 )
1705{
1706 EFI_STATUS Status;
1707 EFI_STATUS CleanupStatus;
1708 LIST_ENTRY OrigEnvs;
1709
1710 InitializeListHead (&OrigEnvs);
1711
1712 //
1713 // Save our current environment settings for later restoration if necessary
1714 //
1715 if (Environment != NULL) {
1716 Status = GetEnvironmentVariableList (&OrigEnvs);
1717 if (!EFI_ERROR (Status)) {
1718 Status = SetEnvironmentVariables (Environment);
1719 } else {
1720 return Status;
1721 }
1722 }
1723
1724 Status = RunShellCommand (CommandLine, StartImageStatus);
1725
1726 // Restore environment variables
1727 if (!IsListEmpty (&OrigEnvs)) {
1728 CleanupStatus = SetEnvironmentVariableList (&OrigEnvs);
1729 ASSERT_EFI_ERROR (CleanupStatus);
1730 }
1731
1732 return (Status);
1733}
1734
1741STATIC
1742BOOLEAN
1744 VOID
1745 )
1746{
1747 EFI_STATUS Status;
1748 CHAR16 *Temp;
1749 CHAR16 *Temp2;
1750 UINTN TempSize;
1751 BOOLEAN RetVal;
1752
1753 RetVal = TRUE;
1754 Temp = NULL;
1755 Temp2 = NULL;
1756
1757 if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {
1758 TempSize = 0;
1759 Temp = NULL;
1760 Status = SHELL_GET_ENVIRONMENT_VARIABLE (mNoNestingEnvVarName, &TempSize, Temp);
1761 if (Status == EFI_BUFFER_TOO_SMALL) {
1762 Temp = AllocateZeroPool (TempSize + sizeof (CHAR16));
1763 if (Temp != NULL) {
1764 Status = SHELL_GET_ENVIRONMENT_VARIABLE (mNoNestingEnvVarName, &TempSize, Temp);
1765 }
1766 }
1767
1768 Temp2 = StrnCatGrow (&Temp2, NULL, mNoNestingTrue, 0);
1769 if ((Temp != NULL) && (Temp2 != NULL) && (StringNoCaseCompare (&Temp, &Temp2) == 0)) {
1770 //
1771 // Use the no nesting method.
1772 //
1773 RetVal = FALSE;
1774 }
1775 }
1776
1777 SHELL_FREE_NON_NULL (Temp);
1778 SHELL_FREE_NON_NULL (Temp2);
1779 return (RetVal);
1780}
1781
1817EFIAPI
1819 IN EFI_HANDLE *ParentImageHandle,
1820 IN CHAR16 *CommandLine OPTIONAL,
1821 IN CHAR16 **Environment OPTIONAL,
1822 OUT EFI_STATUS *StatusCode OPTIONAL
1823 )
1824{
1825 EFI_STATUS Status;
1826 CHAR16 *Temp;
1827 EFI_DEVICE_PATH_PROTOCOL *DevPath;
1828 UINTN Size;
1829
1830 if ((PcdGet8 (PcdShellSupportLevel) < 1)) {
1831 return (EFI_UNSUPPORTED);
1832 }
1833
1834 Temp = NULL;
1835 if (NestingEnabled ()) {
1836 DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);
1837 if (DevPath == NULL) {
1838 return EFI_OUT_OF_RESOURCES;
1839 }
1840
1842 Temp = ConvertDevicePathToText (ShellInfoObject.FileDevPath, TRUE, TRUE);
1843 if (Temp != NULL) {
1844 FreePool (Temp);
1845 }
1846
1847 Temp = ConvertDevicePathToText (ShellInfoObject.ImageDevPath, TRUE, TRUE);
1848 if (Temp != NULL) {
1849 FreePool (Temp);
1850 }
1851
1852 if (DevPath != NULL) {
1853 Temp = ConvertDevicePathToText (DevPath, TRUE, TRUE);
1854 }
1855
1856 if (Temp != NULL) {
1857 FreePool (Temp);
1858 }
1859
1860 DEBUG_CODE_END ();
1861
1862 Temp = NULL;
1863 Size = 0;
1864 ASSERT ((Temp == NULL && Size == 0) || (Temp != NULL));
1865 StrnCatGrow (&Temp, &Size, L"Shell.efi -exit ", 0);
1866 StrnCatGrow (&Temp, &Size, CommandLine, 0);
1867
1869 ParentImageHandle,
1870 DevPath,
1871 Temp,
1872 (CONST CHAR16 **)Environment,
1873 StatusCode
1874 );
1875
1876 //
1877 // de-allocate and return
1878 //
1879 FreePool (DevPath);
1880 FreePool (Temp);
1881 } else {
1882 Status = InternalShellExecute (
1883 (CONST CHAR16 *)CommandLine,
1884 (CONST CHAR16 **)Environment,
1885 StatusCode
1886 );
1887 }
1888
1889 return (Status);
1890}
1891
1900VOID
1902 IN EFI_SHELL_FILE_INFO *FileListNode
1903 )
1904{
1905 if (FileListNode->Info != NULL) {
1906 FreePool ((VOID *)FileListNode->Info);
1907 }
1908
1909 if (FileListNode->FileName != NULL) {
1910 FreePool ((VOID *)FileListNode->FileName);
1911 }
1912
1913 if (FileListNode->FullName != NULL) {
1914 FreePool ((VOID *)FileListNode->FullName);
1915 }
1916
1917 if (FileListNode->Handle != NULL) {
1918 ShellInfoObject.NewEfiShellProtocol->CloseFile (FileListNode->Handle);
1919 }
1920
1921 FreePool (FileListNode);
1922}
1923
1937EFIAPI
1939 IN EFI_SHELL_FILE_INFO **FileList
1940 )
1941{
1942 EFI_SHELL_FILE_INFO *ShellFileListItem;
1943
1944 if ((FileList == NULL) || (*FileList == NULL)) {
1945 return (EFI_INVALID_PARAMETER);
1946 }
1947
1948 for ( ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetFirstNode (&(*FileList)->Link)
1949 ; !IsListEmpty (&(*FileList)->Link)
1950 ; ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetFirstNode (&(*FileList)->Link)
1951 )
1952 {
1953 RemoveEntryList (&ShellFileListItem->Link);
1954 InternalFreeShellFileInfoNode (ShellFileListItem);
1955 }
1956
1958 *FileList = NULL;
1959 return (EFI_SUCCESS);
1960}
1961
1973EFIAPI
1975 IN EFI_SHELL_FILE_INFO **FileList
1976 )
1977{
1978 EFI_STATUS Status;
1979 EFI_SHELL_FILE_INFO *Duplicates;
1980 EFI_SHELL_FILE_INFO *ShellFileListItem;
1981 EFI_SHELL_FILE_INFO *ShellFileListItem2;
1982 EFI_SHELL_FILE_INFO *TempNode;
1983
1984 if ((FileList == NULL) || (*FileList == NULL)) {
1985 return (EFI_INVALID_PARAMETER);
1986 }
1987
1988 Status = ShellSortFileList (
1989 FileList,
1990 &Duplicates,
1991 ShellSortFileListByFullName
1992 );
1993 if (!EFI_ERROR (Status)) {
1994 EfiShellFreeFileList (&Duplicates);
1995 return EFI_SUCCESS;
1996 }
1997
1998 //
1999 // Fall back to the slow method that needs no extra memory, and so cannot
2000 // fail.
2001 //
2002 for ( ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetFirstNode (&(*FileList)->Link)
2003 ; !IsNull (&(*FileList)->Link, &ShellFileListItem->Link)
2004 ; ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetNextNode (&(*FileList)->Link, &ShellFileListItem->Link)
2005 )
2006 {
2007 for ( ShellFileListItem2 = (EFI_SHELL_FILE_INFO *)GetNextNode (&(*FileList)->Link, &ShellFileListItem->Link)
2008 ; !IsNull (&(*FileList)->Link, &ShellFileListItem2->Link)
2009 ; ShellFileListItem2 = (EFI_SHELL_FILE_INFO *)GetNextNode (&(*FileList)->Link, &ShellFileListItem2->Link)
2010 )
2011 {
2012 if (gUnicodeCollation->StriColl (
2013 gUnicodeCollation,
2014 (CHAR16 *)ShellFileListItem->FullName,
2015 (CHAR16 *)ShellFileListItem2->FullName
2016 ) == 0
2017 )
2018 {
2019 TempNode = (EFI_SHELL_FILE_INFO *)GetPreviousNode (
2020 &(*FileList)->Link,
2021 &ShellFileListItem2->Link
2022 );
2023 RemoveEntryList (&ShellFileListItem2->Link);
2024 InternalFreeShellFileInfoNode (ShellFileListItem2);
2025 // Set ShellFileListItem2 to PreviousNode so we don't access Freed
2026 // memory in GetNextNode in the loop expression above.
2027 ShellFileListItem2 = TempNode;
2028 }
2029 }
2030 }
2031
2032 return (EFI_SUCCESS);
2033}
2034
2035//
2036// This is the same structure as the external version, but it has no CONST qualifiers.
2037//
2038typedef struct {
2041 CHAR16 *FullName;
2042 CHAR16 *FileName;
2043 SHELL_FILE_HANDLE Handle;
2046
2058 IN EFI_SHELL_FILE_INFO *Node,
2059 IN BOOLEAN Save
2060 )
2061{
2063
2064 //
2065 // try to confirm that the objects are in sync
2066 //
2067 ASSERT (sizeof (EFI_SHELL_FILE_INFO_NO_CONST) == sizeof (EFI_SHELL_FILE_INFO));
2068
2069 NewNode = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
2070 if (NewNode == NULL) {
2071 return (NULL);
2072 }
2073
2074 NewNode->FullName = AllocateCopyPool (StrSize (Node->FullName), Node->FullName);
2075 NewNode->FileName = AllocateCopyPool (StrSize (Node->FileName), Node->FileName);
2076 NewNode->Info = AllocateCopyPool ((UINTN)Node->Info->Size, Node->Info);
2077 if ( (NewNode->FullName == NULL)
2078 || (NewNode->FileName == NULL)
2079 || (NewNode->Info == NULL)
2080 )
2081 {
2082 SHELL_FREE_NON_NULL (NewNode->FullName);
2083 SHELL_FREE_NON_NULL (NewNode->FileName);
2084 SHELL_FREE_NON_NULL (NewNode->Info);
2085 SHELL_FREE_NON_NULL (NewNode);
2086 return (NULL);
2087 }
2088
2089 NewNode->Status = Node->Status;
2090 NewNode->Handle = Node->Handle;
2091 if (!Save) {
2092 Node->Handle = NULL;
2093 }
2094
2095 return ((EFI_SHELL_FILE_INFO *)NewNode);
2096}
2097
2113 IN CONST CHAR16 *BasePath,
2114 IN CONST EFI_STATUS Status,
2115 IN CONST CHAR16 *FileName,
2116 IN CONST SHELL_FILE_HANDLE Handle,
2117 IN CONST EFI_FILE_INFO *Info
2118 )
2119{
2120 EFI_SHELL_FILE_INFO *ShellFileListItem;
2121 CHAR16 *TempString;
2122 UINTN Size;
2123
2124 TempString = NULL;
2125 Size = 0;
2126
2127 ShellFileListItem = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
2128 if (ShellFileListItem == NULL) {
2129 return (NULL);
2130 }
2131
2132 if ((Info != NULL) && (Info->Size != 0)) {
2133 ShellFileListItem->Info = AllocateZeroPool ((UINTN)Info->Size);
2134 if (ShellFileListItem->Info == NULL) {
2135 FreePool (ShellFileListItem);
2136 return (NULL);
2137 }
2138
2139 CopyMem (ShellFileListItem->Info, Info, (UINTN)Info->Size);
2140 } else {
2141 ShellFileListItem->Info = NULL;
2142 }
2143
2144 if (FileName != NULL) {
2145 ASSERT (TempString == NULL);
2146 ShellFileListItem->FileName = StrnCatGrow (&TempString, 0, FileName, 0);
2147 if (ShellFileListItem->FileName == NULL) {
2148 FreePool (ShellFileListItem->Info);
2149 FreePool (ShellFileListItem);
2150 return (NULL);
2151 }
2152 } else {
2153 ShellFileListItem->FileName = NULL;
2154 }
2155
2156 Size = 0;
2157 TempString = NULL;
2158 if (BasePath != NULL) {
2159 ASSERT ((TempString == NULL && Size == 0) || (TempString != NULL));
2160 TempString = StrnCatGrow (&TempString, &Size, BasePath, 0);
2161 if (TempString == NULL) {
2162 FreePool ((VOID *)ShellFileListItem->FileName);
2163 SHELL_FREE_NON_NULL (ShellFileListItem->Info);
2164 FreePool (ShellFileListItem);
2165 return (NULL);
2166 }
2167 }
2168
2169 if (ShellFileListItem->FileName != NULL) {
2170 ASSERT ((TempString == NULL && Size == 0) || (TempString != NULL));
2171 TempString = StrnCatGrow (&TempString, &Size, ShellFileListItem->FileName, 0);
2172 if (TempString == NULL) {
2173 FreePool ((VOID *)ShellFileListItem->FileName);
2174 FreePool (ShellFileListItem->Info);
2175 FreePool (ShellFileListItem);
2176 return (NULL);
2177 }
2178 }
2179
2180 TempString = PathCleanUpDirectories (TempString);
2181
2182 ShellFileListItem->FullName = TempString;
2183 ShellFileListItem->Status = Status;
2184 ShellFileListItem->Handle = Handle;
2185
2186 return (ShellFileListItem);
2187}
2188
2204EFIAPI
2206 IN SHELL_FILE_HANDLE FileDirHandle,
2207 OUT EFI_SHELL_FILE_INFO **FileList
2208 )
2209{
2210 EFI_SHELL_FILE_INFO *ShellFileList;
2211 EFI_SHELL_FILE_INFO *ShellFileListItem;
2213 EFI_STATUS Status;
2214 BOOLEAN NoFile;
2215 CHAR16 *TempString;
2216 CHAR16 *BasePath;
2217 UINTN Size;
2218 CHAR16 *TempSpot;
2219
2220 BasePath = NULL;
2221 Status = FileHandleGetFileName (FileDirHandle, &BasePath);
2222 if (EFI_ERROR (Status)) {
2223 return (Status);
2224 }
2225
2226 if (ShellFileHandleGetPath (FileDirHandle) != NULL) {
2227 TempString = NULL;
2228 Size = 0;
2229 TempString = StrnCatGrow (&TempString, &Size, ShellFileHandleGetPath (FileDirHandle), 0);
2230 if (TempString == NULL) {
2231 SHELL_FREE_NON_NULL (BasePath);
2232 return (EFI_OUT_OF_RESOURCES);
2233 }
2234
2235 TempSpot = StrStr (TempString, L";");
2236
2237 if (TempSpot != NULL) {
2238 *TempSpot = CHAR_NULL;
2239 }
2240
2241 TempString = StrnCatGrow (&TempString, &Size, BasePath, 0);
2242 if (TempString == NULL) {
2243 SHELL_FREE_NON_NULL (BasePath);
2244 return (EFI_OUT_OF_RESOURCES);
2245 }
2246
2247 SHELL_FREE_NON_NULL (BasePath);
2248 BasePath = TempString;
2249 }
2250
2251 NoFile = FALSE;
2252 ShellFileList = NULL;
2253 ShellFileListItem = NULL;
2254 FileInfo = NULL;
2255 Status = EFI_SUCCESS;
2256
2257 for ( Status = FileHandleFindFirstFile (FileDirHandle, &FileInfo)
2258 ; !EFI_ERROR (Status) && !NoFile
2259 ; Status = FileHandleFindNextFile (FileDirHandle, FileInfo, &NoFile)
2260 )
2261 {
2262 if (ShellFileList == NULL) {
2263 ShellFileList = (EFI_SHELL_FILE_INFO *)AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
2264 if (ShellFileList == NULL) {
2265 SHELL_FREE_NON_NULL (BasePath);
2266 return EFI_OUT_OF_RESOURCES;
2267 }
2268
2269 InitializeListHead (&ShellFileList->Link);
2270 }
2271
2272 //
2273 // allocate a new EFI_SHELL_FILE_INFO and populate it...
2274 //
2275 ShellFileListItem = CreateAndPopulateShellFileInfo (
2276 BasePath,
2277 EFI_SUCCESS, // success since we didn't fail to open it...
2279 NULL, // no handle since not open
2280 FileInfo
2281 );
2282 if (ShellFileListItem == NULL) {
2283 Status = EFI_OUT_OF_RESOURCES;
2284 //
2285 // Free resources outside the loop.
2286 //
2287 break;
2288 }
2289
2290 InsertTailList (&ShellFileList->Link, &ShellFileListItem->Link);
2291 }
2292
2293 if (EFI_ERROR (Status)) {
2294 EfiShellFreeFileList (&ShellFileList);
2295 *FileList = NULL;
2296 } else {
2297 *FileList = ShellFileList;
2298 }
2299
2300 SHELL_FREE_NON_NULL (BasePath);
2301 return (Status);
2302}
2303
2322EFIAPI
2324 IN CONST CHAR16 *GuidName,
2325 OUT EFI_GUID *Guid
2326 )
2327{
2328 EFI_GUID *NewGuid;
2329 EFI_STATUS Status;
2330
2331 if ((Guid == NULL) || (GuidName == NULL)) {
2332 return (EFI_INVALID_PARAMETER);
2333 }
2334
2335 Status = GetGuidFromStringName (GuidName, NULL, &NewGuid);
2336
2337 if (!EFI_ERROR (Status)) {
2338 CopyGuid (Guid, NewGuid);
2339 }
2340
2341 return (Status);
2342}
2343
2362EFIAPI
2364 IN CONST EFI_GUID *Guid,
2365 OUT CONST CHAR16 **GuidName
2366 )
2367{
2368 CHAR16 *Name;
2369
2370 if ((Guid == NULL) || (GuidName == NULL)) {
2371 return (EFI_INVALID_PARAMETER);
2372 }
2373
2374 Name = GetStringNameFromGuid (Guid, NULL);
2375 if ((Name == NULL) || (StrLen (Name) == 0)) {
2376 SHELL_FREE_NON_NULL (Name);
2377 return (EFI_NOT_FOUND);
2378 }
2379
2380 *GuidName = AddBufferToFreeList (Name);
2381
2382 return (EFI_SUCCESS);
2383}
2384
2409 IN CONST CHAR16 *FilePattern,
2410 IN EFI_UNICODE_COLLATION_PROTOCOL *UnicodeCollation,
2411 IN SHELL_FILE_HANDLE FileHandle,
2412 IN OUT EFI_SHELL_FILE_INFO **FileList,
2413 IN CONST EFI_SHELL_FILE_INFO *ParentNode OPTIONAL,
2414 IN CONST CHAR16 *MapName
2415 )
2416{
2417 EFI_STATUS Status;
2418 CONST CHAR16 *NextFilePatternStart;
2419 CHAR16 *CurrentFilePattern;
2420 EFI_SHELL_FILE_INFO *ShellInfo;
2421 EFI_SHELL_FILE_INFO *ShellInfoNode;
2422 EFI_SHELL_FILE_INFO *NewShellNode;
2424 BOOLEAN Directory;
2425 CHAR16 *NewFullName;
2426 UINTN Size;
2427
2428 NewShellNode = NULL;
2429 FileInfo = NULL;
2430 if ( (FilePattern == NULL)
2431 || (UnicodeCollation == NULL)
2432 || (FileList == NULL)
2433 )
2434 {
2435 return (EFI_INVALID_PARAMETER);
2436 }
2437
2438 ShellInfo = NULL;
2439 CurrentFilePattern = NULL;
2440
2441 if (*FilePattern == L'\\') {
2442 FilePattern++;
2443 }
2444
2445 for ( NextFilePatternStart = FilePattern
2446 ; *NextFilePatternStart != CHAR_NULL && *NextFilePatternStart != L'\\'
2447 ; NextFilePatternStart++)
2448 {
2449 }
2450
2451 CurrentFilePattern = AllocateZeroPool ((NextFilePatternStart-FilePattern+1)*sizeof (CHAR16));
2452 if (CurrentFilePattern == NULL) {
2453 return EFI_OUT_OF_RESOURCES;
2454 }
2455
2456 StrnCpyS (CurrentFilePattern, NextFilePatternStart-FilePattern+1, FilePattern, NextFilePatternStart-FilePattern);
2457
2458 if ( (CurrentFilePattern[0] == CHAR_NULL)
2459 && (NextFilePatternStart[0] == CHAR_NULL)
2460 )
2461 {
2462 //
2463 // we want the parent or root node (if no parent)
2464 //
2465 if (ParentNode == NULL) {
2466 //
2467 // We want the root node. create the node.
2468 //
2469 FileInfo = FileHandleGetInfo (FileHandle);
2470 if (FileInfo != NULL) {
2471 NewShellNode = CreateAndPopulateShellFileInfo (
2472 MapName,
2474 L"\\",
2475 FileHandle,
2476 FileInfo
2477 );
2478 }
2479
2480 SHELL_FREE_NON_NULL (FileInfo);
2481 } else {
2482 //
2483 // Add the current parameter FileHandle to the list, then end...
2484 //
2485 NewShellNode = InternalDuplicateShellFileInfo ((EFI_SHELL_FILE_INFO *)ParentNode, TRUE);
2486 }
2487
2488 if (NewShellNode == NULL) {
2489 Status = EFI_OUT_OF_RESOURCES;
2490 } else {
2491 NewShellNode->Handle = NULL;
2492 if (*FileList == NULL) {
2493 *FileList = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
2494 InitializeListHead (&((*FileList)->Link));
2495 }
2496
2497 //
2498 // Add to the returning to use list
2499 //
2500 InsertTailList (&(*FileList)->Link, &NewShellNode->Link);
2501
2502 Status = EFI_SUCCESS;
2503 }
2504 } else {
2505 Status = EfiShellFindFilesInDir (FileHandle, &ShellInfo);
2506
2507 if (!EFI_ERROR (Status)) {
2508 if (StrStr (NextFilePatternStart, L"\\") != NULL) {
2509 Directory = TRUE;
2510 } else {
2511 Directory = FALSE;
2512 }
2513
2514 for ( ShellInfoNode = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ShellInfo->Link)
2515 ; !IsNull (&ShellInfo->Link, &ShellInfoNode->Link)
2516 ; ShellInfoNode = (EFI_SHELL_FILE_INFO *)GetNextNode (&ShellInfo->Link, &ShellInfoNode->Link)
2517 )
2518 {
2519 if (UnicodeCollation->MetaiMatch (UnicodeCollation, (CHAR16 *)ShellInfoNode->FileName, CurrentFilePattern)) {
2520 if ((ShellInfoNode->FullName != NULL) && (StrStr (ShellInfoNode->FullName, L":") == NULL)) {
2521 Size = StrSize (ShellInfoNode->FullName) + StrSize (MapName);
2522 NewFullName = AllocateZeroPool (Size);
2523 if (NewFullName == NULL) {
2524 Status = EFI_OUT_OF_RESOURCES;
2525 } else {
2526 StrCpyS (NewFullName, Size / sizeof (CHAR16), MapName);
2527 StrCatS (NewFullName, Size / sizeof (CHAR16), ShellInfoNode->FullName);
2528 FreePool ((VOID *)ShellInfoNode->FullName);
2529 ShellInfoNode->FullName = NewFullName;
2530 }
2531 }
2532
2533 if (Directory && !EFI_ERROR (Status) && (ShellInfoNode->FullName != NULL) && (ShellInfoNode->FileName != NULL)) {
2534 //
2535 // should be a directory
2536 //
2537
2538 //
2539 // don't open the . and .. directories
2540 //
2541 if ( (StrCmp (ShellInfoNode->FileName, L".") != 0)
2542 && (StrCmp (ShellInfoNode->FileName, L"..") != 0)
2543 )
2544 {
2545 //
2546 //
2547 //
2548 if (EFI_ERROR (Status)) {
2549 break;
2550 }
2551
2552 //
2553 // Open the directory since we need that handle in the next recursion.
2554 //
2555 ShellInfoNode->Status = EfiShellOpenFileByName (ShellInfoNode->FullName, &ShellInfoNode->Handle, EFI_FILE_MODE_READ);
2556
2557 //
2558 // recurse with the next part of the pattern
2559 //
2560 Status = ShellSearchHandle (NextFilePatternStart, UnicodeCollation, ShellInfoNode->Handle, FileList, ShellInfoNode, MapName);
2561 EfiShellClose (ShellInfoNode->Handle);
2562 ShellInfoNode->Handle = NULL;
2563 }
2564 } else if (!EFI_ERROR (Status)) {
2565 //
2566 // should be a file
2567 //
2568
2569 //
2570 // copy the information we need into a new Node
2571 //
2572 NewShellNode = InternalDuplicateShellFileInfo (ShellInfoNode, FALSE);
2573 if (NewShellNode == NULL) {
2574 Status = EFI_OUT_OF_RESOURCES;
2575 }
2576
2577 if (*FileList == NULL) {
2578 *FileList = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
2579 InitializeListHead (&((*FileList)->Link));
2580 }
2581
2582 //
2583 // Add to the returning to use list
2584 //
2585 InsertTailList (&(*FileList)->Link, &NewShellNode->Link);
2586 }
2587 }
2588
2589 if (EFI_ERROR (Status)) {
2590 break;
2591 }
2592 }
2593
2594 if (EFI_ERROR (Status)) {
2595 EfiShellFreeFileList (&ShellInfo);
2596 } else {
2597 Status = EfiShellFreeFileList (&ShellInfo);
2598 }
2599 }
2600 }
2601
2602 if ((*FileList == NULL) || ((*FileList != NULL) && IsListEmpty (&(*FileList)->Link))) {
2603 Status = EFI_NOT_FOUND;
2604 }
2605
2606 FreePool (CurrentFilePattern);
2607 return (Status);
2608}
2609
2637EFIAPI
2639 IN CONST CHAR16 *FilePattern,
2640 OUT EFI_SHELL_FILE_INFO **FileList
2641 )
2642{
2643 EFI_STATUS Status;
2644 CHAR16 *PatternCopy;
2645 CHAR16 *PatternCurrentLocation;
2646 EFI_DEVICE_PATH_PROTOCOL *RootDevicePath;
2647 SHELL_FILE_HANDLE RootFileHandle;
2648 CHAR16 *MapName;
2649 UINTN Count;
2650
2651 if ( (FilePattern == NULL)
2652 || (FileList == NULL)
2653 || (StrStr (FilePattern, L":") == NULL)
2654 )
2655 {
2656 return (EFI_INVALID_PARAMETER);
2657 }
2658
2659 Status = EFI_SUCCESS;
2660 RootDevicePath = NULL;
2661 RootFileHandle = NULL;
2662 MapName = NULL;
2663 PatternCopy = AllocateCopyPool (StrSize (FilePattern), FilePattern);
2664 if (PatternCopy == NULL) {
2665 return (EFI_OUT_OF_RESOURCES);
2666 }
2667
2668 PatternCopy = PathCleanUpDirectories (PatternCopy);
2669 if (PatternCopy == NULL) {
2670 return (EFI_OUT_OF_RESOURCES);
2671 }
2672
2673 Count = StrStr (PatternCopy, L":") - PatternCopy + 1;
2674 ASSERT (Count <= StrLen (PatternCopy));
2675
2676 ASSERT (MapName == NULL);
2677 MapName = StrnCatGrow (&MapName, NULL, PatternCopy, Count);
2678 if (MapName == NULL) {
2679 Status = EFI_OUT_OF_RESOURCES;
2680 } else {
2681 RootDevicePath = EfiShellGetDevicePathFromFilePath (PatternCopy);
2682 if (RootDevicePath == NULL) {
2683 Status = EFI_INVALID_PARAMETER;
2684 } else {
2685 Status = EfiShellOpenRoot (RootDevicePath, &RootFileHandle);
2686 if (!EFI_ERROR (Status)) {
2687 for ( PatternCurrentLocation = PatternCopy
2688 ; *PatternCurrentLocation != ':'
2689 ; PatternCurrentLocation++)
2690 {
2691 }
2692
2693 PatternCurrentLocation++;
2694 Status = ShellSearchHandle (PatternCurrentLocation, gUnicodeCollation, RootFileHandle, FileList, NULL, MapName);
2695 EfiShellClose (RootFileHandle);
2696 }
2697
2698 FreePool (RootDevicePath);
2699 }
2700 }
2701
2702 SHELL_FREE_NON_NULL (PatternCopy);
2703 SHELL_FREE_NON_NULL (MapName);
2704
2705 return (Status);
2706}
2707
2724EFIAPI
2726 IN CHAR16 *Path,
2727 IN UINT64 OpenMode,
2728 IN OUT EFI_SHELL_FILE_INFO **FileList
2729 )
2730{
2731 EFI_STATUS Status;
2732 EFI_SHELL_FILE_INFO *ShellFileListItem;
2733 CHAR16 *Path2;
2734 UINTN Path2Size;
2735 CONST CHAR16 *CurDir;
2736 BOOLEAN Found;
2737
2739
2740 Path2Size = 0;
2741 Path2 = NULL;
2742
2743 if ((FileList == NULL) || (*FileList == NULL)) {
2744 return (EFI_INVALID_PARAMETER);
2745 }
2746
2747 if ((*Path == L'.') && (*(Path+1) == L'\\')) {
2748 Path += 2;
2749 }
2750
2751 //
2752 // convert a local path to an absolute path
2753 //
2754 if (StrStr (Path, L":") == NULL) {
2755 CurDir = EfiShellGetCurDir (NULL);
2756 if (CurDir == NULL) {
2757 return EFI_NOT_FOUND;
2758 }
2759
2760 ASSERT ((Path2 == NULL && Path2Size == 0) || (Path2 != NULL));
2761 StrnCatGrow (&Path2, &Path2Size, CurDir, 0);
2762 StrnCatGrow (&Path2, &Path2Size, L"\\", 0);
2763 if (*Path == L'\\') {
2764 Path++;
2765 while (PathRemoveLastItem (Path2)) {
2766 }
2767 }
2768
2769 ASSERT ((Path2 == NULL && Path2Size == 0) || (Path2 != NULL));
2770 StrnCatGrow (&Path2, &Path2Size, Path, 0);
2771 } else {
2772 ASSERT (Path2 == NULL);
2773 StrnCatGrow (&Path2, NULL, Path, 0);
2774 }
2775
2776 PathCleanUpDirectories (Path2);
2777
2778 //
2779 // do the search
2780 //
2781 Status = EfiShellFindFiles (Path2, FileList);
2782
2783 FreePool (Path2);
2784
2785 if (EFI_ERROR (Status)) {
2786 return (Status);
2787 }
2788
2789 Found = FALSE;
2790 //
2791 // We had no errors so open all the files (that are not already opened...)
2792 //
2793 for ( ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetFirstNode (&(*FileList)->Link)
2794 ; !IsNull (&(*FileList)->Link, &ShellFileListItem->Link)
2795 ; ShellFileListItem = (EFI_SHELL_FILE_INFO *)GetNextNode (&(*FileList)->Link, &ShellFileListItem->Link)
2796 )
2797 {
2798 if ((ShellFileListItem->Status == 0) && (ShellFileListItem->Handle == NULL)) {
2799 ShellFileListItem->Status = EfiShellOpenFileByName (ShellFileListItem->FullName, &ShellFileListItem->Handle, OpenMode);
2800 Found = TRUE;
2801 }
2802 }
2803
2804 if (!Found) {
2805 return (EFI_NOT_FOUND);
2806 }
2807
2808 return (EFI_SUCCESS);
2809}
2810
2833CONST CHAR16 *
2834EFIAPI
2836 IN CONST CHAR16 *Name,
2837 OUT UINT32 *Attributes OPTIONAL
2838 )
2839{
2840 EFI_STATUS Status;
2841 VOID *Buffer;
2842 UINTN Size;
2843 ENV_VAR_LIST *Node;
2844 CHAR16 *CurrentWriteLocation;
2845
2846 Size = 0;
2847 Buffer = NULL;
2848
2849 if (Name == NULL) {
2850 //
2851 // Build the semi-colon delimited list. (2 passes)
2852 //
2853 for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
2854 ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
2855 ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
2856 )
2857 {
2858 ASSERT (Node->Key != NULL);
2859 Size += StrSize (Node->Key);
2860 }
2861
2862 Size += 2*sizeof (CHAR16);
2863
2864 Buffer = AllocateZeroPool (Size);
2865 if (Buffer == NULL) {
2866 return (NULL);
2867 }
2868
2869 CurrentWriteLocation = (CHAR16 *)Buffer;
2870
2871 for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
2872 ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
2873 ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
2874 )
2875 {
2876 ASSERT (Node->Key != NULL);
2877 StrCpyS (
2878 CurrentWriteLocation,
2879 (Size)/sizeof (CHAR16) - (CurrentWriteLocation - ((CHAR16 *)Buffer)),
2880 Node->Key
2881 );
2882 CurrentWriteLocation += StrLen (CurrentWriteLocation) + 1;
2883 }
2884 } else {
2885 //
2886 // We are doing a specific environment variable
2887 //
2888 Status = ShellFindEnvVarInList (Name, (CHAR16 **)&Buffer, &Size, Attributes);
2889
2890 if (EFI_ERROR (Status)) {
2891 //
2892 // get the size we need for this EnvVariable
2893 //
2894 Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (Name, Attributes, &Size, Buffer);
2895 if (Status == EFI_BUFFER_TOO_SMALL) {
2896 //
2897 // Allocate the space and recall the get function
2898 //
2899 Buffer = AllocateZeroPool (Size);
2900 if (Buffer == NULL) {
2901 return NULL;
2902 }
2903
2904 Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (Name, Attributes, &Size, Buffer);
2905 }
2906
2907 //
2908 // we didn't get it (might not exist)
2909 // free the memory if we allocated any and return NULL
2910 //
2911 if (EFI_ERROR (Status)) {
2912 if (Buffer != NULL) {
2913 FreePool (Buffer);
2914 }
2915
2916 return (NULL);
2917 } else {
2918 //
2919 // If we did not find the environment variable in the gShellEnvVarList
2920 // but get it from UEFI variable storage successfully then we need update
2921 // the gShellEnvVarList.
2922 //
2924 Status = ShellInitEnvVarList ();
2925 ASSERT (Status == EFI_SUCCESS);
2926 }
2927 }
2928 }
2929
2930 //
2931 // return the buffer
2932 //
2933 return (AddBufferToFreeList (Buffer));
2934}
2935
2959CONST CHAR16 *
2960EFIAPI
2962 IN CONST CHAR16 *Name
2963 )
2964{
2965 return (EfiShellGetEnvEx (Name, NULL));
2966}
2967
2980 IN CONST CHAR16 *Name,
2981 IN CONST CHAR16 *Value,
2982 IN BOOLEAN Volatile
2983 )
2984{
2985 EFI_STATUS Status;
2986
2987 if ((Value == NULL) || (StrLen (Value) == 0)) {
2988 Status = SHELL_DELETE_ENVIRONMENT_VARIABLE (Name);
2989 if (!EFI_ERROR (Status)) {
2991 }
2992 } else {
2994 Status = ShellAddEnvVarToList (
2995 Name,
2996 Value,
2997 StrSize (Value),
2998 EFI_VARIABLE_BOOTSERVICE_ACCESS | (Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE)
2999 );
3000 if (!EFI_ERROR (Status)) {
3001 Status = Volatile
3002 ? SHELL_SET_ENVIRONMENT_VARIABLE_V (Name, StrSize (Value) - sizeof (CHAR16), Value)
3003 : SHELL_SET_ENVIRONMENT_VARIABLE_NV (Name, StrSize (Value) - sizeof (CHAR16), Value);
3004 if (EFI_ERROR (Status)) {
3006 }
3007 }
3008 }
3009
3010 return Status;
3011}
3012
3035EFIAPI
3037 IN CONST CHAR16 *Name,
3038 IN CONST CHAR16 *Value,
3039 IN BOOLEAN Volatile
3040 )
3041{
3042 if ((Name == NULL) || (*Name == CHAR_NULL)) {
3043 return (EFI_INVALID_PARAMETER);
3044 }
3045
3046 //
3047 // Make sure we dont 'set' a predefined read only variable
3048 //
3049 if ((StrCmp (Name, L"cwd") == 0) ||
3050 (StrCmp (Name, L"lasterror") == 0) ||
3051 (StrCmp (Name, L"profiles") == 0) ||
3052 (StrCmp (Name, L"uefishellsupport") == 0) ||
3053 (StrCmp (Name, L"uefishellversion") == 0) ||
3054 (StrCmp (Name, L"uefiversion") == 0) ||
3055 (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest &&
3056 (StrCmp (Name, mNoNestingEnvVarName) == 0))
3057 )
3058 {
3059 return (EFI_INVALID_PARAMETER);
3060 }
3061
3062 return (InternalEfiShellSetEnv (Name, Value, Volatile));
3063}
3064
3081CONST CHAR16 *
3082EFIAPI
3084 IN CONST CHAR16 *FileSystemMapping OPTIONAL
3085 )
3086{
3087 CHAR16 *PathToReturn;
3088 UINTN Size;
3089 SHELL_MAP_LIST *MapListItem;
3090
3091 if (!IsListEmpty (&gShellMapList.Link)) {
3092 //
3093 // if parameter is NULL, use current
3094 //
3095 if (FileSystemMapping == NULL) {
3096 return (EfiShellGetEnv (L"cwd"));
3097 } else {
3098 Size = 0;
3099 PathToReturn = NULL;
3100 MapListItem = ShellCommandFindMapItem (FileSystemMapping);
3101 if (MapListItem != NULL) {
3102 ASSERT ((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL));
3103 PathToReturn = StrnCatGrow (&PathToReturn, &Size, MapListItem->MapName, 0);
3104 PathToReturn = StrnCatGrow (&PathToReturn, &Size, MapListItem->CurrentDirectoryPath, 0);
3105 }
3106 }
3107
3108 return (AddBufferToFreeList (PathToReturn));
3109 } else {
3110 return (NULL);
3111 }
3112}
3113
3142EFIAPI
3144 IN CONST CHAR16 *FileSystem OPTIONAL,
3145 IN CONST CHAR16 *Dir
3146 )
3147{
3148 CHAR16 *MapName;
3149 SHELL_MAP_LIST *MapListItem;
3150 UINTN Size;
3151 EFI_STATUS Status;
3152 CHAR16 *TempString;
3153 CHAR16 *DirectoryName;
3154 UINTN TempLen;
3155
3156 Size = 0;
3157 MapName = NULL;
3158 MapListItem = NULL;
3159 TempString = NULL;
3160 DirectoryName = NULL;
3161
3162 if (((FileSystem == NULL) && (Dir == NULL)) || (Dir == NULL)) {
3163 return (EFI_INVALID_PARAMETER);
3164 }
3165
3166 if (IsListEmpty (&gShellMapList.Link)) {
3167 return (EFI_NOT_FOUND);
3168 }
3169
3170 DirectoryName = StrnCatGrow (&DirectoryName, NULL, Dir, 0);
3171 if (DirectoryName == NULL) {
3172 ASSERT (DirectoryName != NULL);
3173 return (EFI_OUT_OF_RESOURCES);
3174 }
3175
3176 PathCleanUpDirectories (DirectoryName);
3177
3178 if (FileSystem == NULL) {
3179 //
3180 // determine the file system mapping to use
3181 //
3182 if (StrStr (DirectoryName, L":") != NULL) {
3183 ASSERT (MapName == NULL);
3184 MapName = StrnCatGrow (&MapName, NULL, DirectoryName, (StrStr (DirectoryName, L":")-DirectoryName+1));
3185 }
3186
3187 //
3188 // find the file system mapping's entry in the list
3189 // or use current
3190 //
3191 if (MapName != NULL) {
3192 MapListItem = ShellCommandFindMapItem (MapName);
3193
3194 //
3195 // make that the current file system mapping
3196 //
3197 if (MapListItem != NULL) {
3198 gShellCurMapping = MapListItem;
3199 }
3200 } else {
3201 MapListItem = gShellCurMapping;
3202 }
3203
3204 if (MapListItem == NULL) {
3205 FreePool (DirectoryName);
3206 SHELL_FREE_NON_NULL (MapName);
3207 return (EFI_NOT_FOUND);
3208 }
3209
3210 //
3211 // now update the MapListItem's current directory
3212 //
3213 if ((MapListItem->CurrentDirectoryPath != NULL) && (DirectoryName[StrLen (DirectoryName) - 1] != L':')) {
3214 FreePool (MapListItem->CurrentDirectoryPath);
3215 MapListItem->CurrentDirectoryPath = NULL;
3216 }
3217
3218 if (MapName != NULL) {
3219 TempLen = StrLen (MapName);
3220 if (TempLen != StrLen (DirectoryName)) {
3221 ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
3222 MapListItem->CurrentDirectoryPath = StrnCatGrow (&MapListItem->CurrentDirectoryPath, &Size, DirectoryName+StrLen (MapName), 0);
3223 }
3224
3225 FreePool (MapName);
3226 } else {
3227 ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
3228 MapListItem->CurrentDirectoryPath = StrnCatGrow (&MapListItem->CurrentDirectoryPath, &Size, DirectoryName, 0);
3229 }
3230
3231 if (((MapListItem->CurrentDirectoryPath != NULL) && (MapListItem->CurrentDirectoryPath[StrLen (MapListItem->CurrentDirectoryPath)-1] == L'\\')) || (MapListItem->CurrentDirectoryPath == NULL)) {
3232 ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
3233 if (MapListItem->CurrentDirectoryPath != NULL) {
3234 MapListItem->CurrentDirectoryPath[StrLen (MapListItem->CurrentDirectoryPath)-1] = CHAR_NULL;
3235 }
3236 }
3237 } else {
3238 //
3239 // cant have a mapping in the directory...
3240 //
3241 if (StrStr (DirectoryName, L":") != NULL) {
3242 FreePool (DirectoryName);
3243 return (EFI_INVALID_PARAMETER);
3244 }
3245
3246 //
3247 // FileSystem != NULL
3248 //
3249 MapListItem = ShellCommandFindMapItem (FileSystem);
3250 if (MapListItem == NULL) {
3251 FreePool (DirectoryName);
3252 return (EFI_INVALID_PARAMETER);
3253 }
3254
3255 // gShellCurMapping = MapListItem;
3256 if (DirectoryName != NULL) {
3257 //
3258 // change current dir on that file system
3259 //
3260
3261 if (MapListItem->CurrentDirectoryPath != NULL) {
3262 FreePool (MapListItem->CurrentDirectoryPath);
3263 DEBUG_CODE (
3264 MapListItem->CurrentDirectoryPath = NULL;
3265 );
3266 }
3267
3268 // ASSERT((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
3269 // MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, FileSystem, 0);
3270 ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
3271 MapListItem->CurrentDirectoryPath = StrnCatGrow (&MapListItem->CurrentDirectoryPath, &Size, L"\\", 0);
3272 ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
3273 MapListItem->CurrentDirectoryPath = StrnCatGrow (&MapListItem->CurrentDirectoryPath, &Size, DirectoryName, 0);
3274 if ((MapListItem->CurrentDirectoryPath != NULL) && (MapListItem->CurrentDirectoryPath[StrLen (MapListItem->CurrentDirectoryPath)-1] == L'\\')) {
3275 ASSERT ((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL));
3276 MapListItem->CurrentDirectoryPath[StrLen (MapListItem->CurrentDirectoryPath)-1] = CHAR_NULL;
3277 }
3278 }
3279 }
3280
3281 FreePool (DirectoryName);
3282 //
3283 // if updated the current directory then update the environment variable
3284 //
3285 if (MapListItem == gShellCurMapping) {
3286 Size = 0;
3287 ASSERT ((TempString == NULL && Size == 0) || (TempString != NULL));
3288 StrnCatGrow (&TempString, &Size, MapListItem->MapName, 0);
3289 ASSERT ((TempString == NULL && Size == 0) || (TempString != NULL));
3290 StrnCatGrow (&TempString, &Size, MapListItem->CurrentDirectoryPath, 0);
3291 Status = InternalEfiShellSetEnv (L"cwd", TempString, TRUE);
3292 FreePool (TempString);
3293 return (Status);
3294 }
3295
3296 return (EFI_SUCCESS);
3297}
3298
3325EFIAPI
3327 IN CONST CHAR16 *Command,
3328 IN CONST CHAR16 *Sections OPTIONAL,
3329 OUT CHAR16 **HelpText
3330 )
3331{
3332 CONST CHAR16 *ManFileName;
3333 CHAR16 *FixCommand;
3334 EFI_STATUS Status;
3335
3336 ASSERT (HelpText != NULL);
3337 FixCommand = NULL;
3338
3339 ManFileName = ShellCommandGetManFileNameHandler (Command);
3340
3341 if (ManFileName != NULL) {
3342 return (ProcessManFile (ManFileName, Command, Sections, NULL, HelpText));
3343 } else {
3344 if ( (StrLen (Command) > 4)
3345 && ((Command[StrLen (Command)-1] == L'i') || (Command[StrLen (Command)-1] == L'I'))
3346 && ((Command[StrLen (Command)-2] == L'f') || (Command[StrLen (Command)-2] == L'F'))
3347 && ((Command[StrLen (Command)-3] == L'e') || (Command[StrLen (Command)-3] == L'E'))
3348 && (Command[StrLen (Command)-4] == L'.')
3349 )
3350 {
3351 FixCommand = AllocateZeroPool (StrSize (Command) - 4 * sizeof (CHAR16));
3352 if (FixCommand == NULL) {
3353 return EFI_OUT_OF_RESOURCES;
3354 }
3355
3356 StrnCpyS (
3357 FixCommand,
3358 (StrSize (Command) - 4 * sizeof (CHAR16))/sizeof (CHAR16),
3359 Command,
3360 StrLen (Command)-4
3361 );
3362 Status = ProcessManFile (FixCommand, FixCommand, Sections, NULL, HelpText);
3363 FreePool (FixCommand);
3364 return Status;
3365 } else {
3366 return (ProcessManFile (Command, Command, Sections, NULL, HelpText));
3367 }
3368 }
3369}
3370
3379BOOLEAN
3380EFIAPI
3382 VOID
3383 )
3384{
3385 return (ShellInfoObject.PageBreakEnabled);
3386}
3387
3396BOOLEAN
3397EFIAPI
3399 VOID
3400 )
3401{
3402 return (ShellInfoObject.RootShellInstance);
3403}
3404
3414CHAR16 *
3416 VOID
3417 )
3418{
3419 EFI_STATUS Status;
3420 EFI_GUID Guid;
3421 CHAR16 *VariableName;
3422 UINTN NameSize;
3423 UINTN NameBufferSize;
3424 CHAR16 *RetVal;
3425 UINTN RetSize;
3426
3427 NameBufferSize = INIT_NAME_BUFFER_SIZE;
3428 VariableName = AllocateZeroPool (NameBufferSize);
3429 RetSize = 0;
3430 RetVal = NULL;
3431
3432 if (VariableName == NULL) {
3433 return (NULL);
3434 }
3435
3436 VariableName[0] = CHAR_NULL;
3437
3438 while (TRUE) {
3439 NameSize = NameBufferSize;
3440 Status = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);
3441 if (Status == EFI_NOT_FOUND) {
3442 break;
3443 } else if (Status == EFI_BUFFER_TOO_SMALL) {
3444 NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;
3445 SHELL_FREE_NON_NULL (VariableName);
3446 VariableName = AllocateZeroPool (NameBufferSize);
3447 if (VariableName == NULL) {
3448 Status = EFI_OUT_OF_RESOURCES;
3449 SHELL_FREE_NON_NULL (RetVal);
3450 RetVal = NULL;
3451 break;
3452 }
3453
3454 NameSize = NameBufferSize;
3455 Status = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);
3456 }
3457
3458 if (EFI_ERROR (Status)) {
3459 SHELL_FREE_NON_NULL (RetVal);
3460 RetVal = NULL;
3461 break;
3462 }
3463
3464 if (CompareGuid (&Guid, &gShellAliasGuid)) {
3465 ASSERT ((RetVal == NULL && RetSize == 0) || (RetVal != NULL));
3466 RetVal = StrnCatGrow (&RetVal, &RetSize, VariableName, 0);
3467 RetVal = StrnCatGrow (&RetVal, &RetSize, L";", 0);
3468 } // compare guid
3469 } // while
3470
3471 SHELL_FREE_NON_NULL (VariableName);
3472
3473 return (RetVal);
3474}
3475
3484CHAR16 *
3486 CHAR16 *Str
3487 )
3488{
3489 UINTN Index;
3490
3491 for (Index = 0; Str[Index] != L'\0'; Index++) {
3492 if ((Str[Index] >= L'A') && (Str[Index] <= L'Z')) {
3493 Str[Index] -= (CHAR16)(L'A' - L'a');
3494 }
3495 }
3496
3497 return Str;
3498}
3499
3518CONST CHAR16 *
3519EFIAPI
3521 IN CONST CHAR16 *Alias,
3522 OUT BOOLEAN *Volatile OPTIONAL
3523 )
3524{
3525 CHAR16 *RetVal;
3526 UINTN RetSize;
3527 UINT32 Attribs;
3528 EFI_STATUS Status;
3529 CHAR16 *AliasLower;
3530 CHAR16 *AliasVal;
3531
3532 // Convert to lowercase to make aliases case-insensitive
3533 if (Alias != NULL) {
3534 AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
3535 if (AliasLower == NULL) {
3536 return NULL;
3537 }
3538
3539 ToLower (AliasLower);
3540
3541 if (Volatile == NULL) {
3542 GetVariable2 (AliasLower, &gShellAliasGuid, (VOID **)&AliasVal, NULL);
3543 FreePool (AliasLower);
3544 return (AddBufferToFreeList (AliasVal));
3545 }
3546
3547 RetSize = 0;
3548 RetVal = NULL;
3549 Status = gRT->GetVariable (AliasLower, &gShellAliasGuid, &Attribs, &RetSize, RetVal);
3550 if (Status == EFI_BUFFER_TOO_SMALL) {
3551 RetVal = AllocateZeroPool (RetSize);
3552 if (RetVal == NULL) {
3553 FreePool (AliasLower);
3554 return NULL;
3555 }
3556
3557 Status = gRT->GetVariable (AliasLower, &gShellAliasGuid, &Attribs, &RetSize, RetVal);
3558 }
3559
3560 if (EFI_ERROR (Status)) {
3561 if (RetVal != NULL) {
3562 FreePool (RetVal);
3563 }
3564
3565 FreePool (AliasLower);
3566 return (NULL);
3567 }
3568
3570 *Volatile = FALSE;
3571 } else {
3572 *Volatile = TRUE;
3573 }
3574
3575 FreePool (AliasLower);
3576 return (AddBufferToFreeList (RetVal));
3577 }
3578
3580}
3581
3600 IN CONST CHAR16 *Command,
3601 IN CONST CHAR16 *Alias,
3602 IN BOOLEAN Volatile
3603 )
3604{
3605 EFI_STATUS Status;
3606 CHAR16 *AliasLower;
3607 BOOLEAN DeleteAlias;
3608
3609 DeleteAlias = FALSE;
3610 if (Alias == NULL) {
3611 //
3612 // We must be trying to remove one if Alias is NULL
3613 // remove an alias (but passed in COMMAND parameter)
3614 //
3615 Alias = Command;
3616 DeleteAlias = TRUE;
3617 }
3618
3619 ASSERT (Alias != NULL);
3620
3621 //
3622 // Convert to lowercase to make aliases case-insensitive
3623 //
3624 AliasLower = AllocateCopyPool (StrSize (Alias), Alias);
3625 if (AliasLower == NULL) {
3626 return EFI_OUT_OF_RESOURCES;
3627 }
3628
3629 ToLower (AliasLower);
3630
3631 if (DeleteAlias) {
3632 Status = gRT->SetVariable (AliasLower, &gShellAliasGuid, 0, 0, NULL);
3633 } else {
3634 Status = gRT->SetVariable (
3635 AliasLower,
3636 &gShellAliasGuid,
3637 EFI_VARIABLE_BOOTSERVICE_ACCESS | (Volatile ? 0 : EFI_VARIABLE_NON_VOLATILE),
3638 StrSize (Command),
3639 (VOID *)Command
3640 );
3641 }
3642
3643 FreePool (AliasLower);
3644
3645 return Status;
3646}
3647
3670EFIAPI
3672 IN CONST CHAR16 *Command,
3673 IN CONST CHAR16 *Alias,
3674 IN BOOLEAN Replace,
3675 IN BOOLEAN Volatile
3676 )
3677{
3678 if (ShellCommandIsOnAliasList ((Alias == NULL) ? Command : Alias)) {
3679 //
3680 // cant set over a built in alias
3681 //
3682 return (EFI_ACCESS_DENIED);
3683 } else if ((Command == NULL) || (*Command == CHAR_NULL) || (StrLen (Command) == 0)) {
3684 //
3685 // Command is null or empty
3686 //
3687 return (EFI_INVALID_PARAMETER);
3688 } else if ((EfiShellGetAlias (Command, NULL) != NULL) && !Replace) {
3689 //
3690 // Alias already exists, Replace not set
3691 //
3692 return (EFI_ACCESS_DENIED);
3693 } else {
3694 return (InternalSetAlias (Command, Alias, Volatile));
3695 }
3696}
3697
3698// Pure FILE_HANDLE operations are passed to FileHandleLib
3699// these functions are indicated by the *
3700EFI_SHELL_PROTOCOL mShellProtocol = {
3740 NULL,
3741 SHELL_MAJOR_VERSION,
3742 SHELL_MINOR_VERSION,
3743
3744 // New for UEFI Shell 2.1
3749};
3750
3767 IN OUT EFI_SHELL_PROTOCOL **NewShell
3768 )
3769{
3770 EFI_STATUS Status;
3771 UINTN BufferSize;
3772 EFI_HANDLE *Buffer;
3773 UINTN HandleCounter;
3774 SHELL_PROTOCOL_HANDLE_LIST *OldProtocolNode;
3775 EFI_SHELL_PROTOCOL *OldShell;
3776
3777 if (NewShell == NULL) {
3778 return (EFI_INVALID_PARAMETER);
3779 }
3780
3781 BufferSize = 0;
3782 Buffer = NULL;
3783 OldProtocolNode = NULL;
3784 InitializeListHead (&ShellInfoObject.OldShellList.Link);
3785
3786 //
3787 // Initialize EfiShellProtocol object...
3788 //
3789 Status = gBS->CreateEvent (
3790 0,
3791 0,
3792 NULL,
3793 NULL,
3794 &mShellProtocol.ExecutionBreak
3795 );
3796 if (EFI_ERROR (Status)) {
3797 return (Status);
3798 }
3799
3800 //
3801 // Get the size of the buffer we need.
3802 //
3803 Status = gBS->LocateHandle (
3804 ByProtocol,
3805 &gEfiShellProtocolGuid,
3806 NULL,
3807 &BufferSize,
3808 Buffer
3809 );
3810 if (Status == EFI_BUFFER_TOO_SMALL) {
3811 //
3812 // Allocate and recall with buffer of correct size
3813 //
3814 Buffer = AllocateZeroPool (BufferSize);
3815 if (Buffer == NULL) {
3816 return (EFI_OUT_OF_RESOURCES);
3817 }
3818
3819 Status = gBS->LocateHandle (
3820 ByProtocol,
3821 &gEfiShellProtocolGuid,
3822 NULL,
3823 &BufferSize,
3824 Buffer
3825 );
3826 if (EFI_ERROR (Status)) {
3827 FreePool (Buffer);
3828 return (Status);
3829 }
3830
3831 //
3832 // now overwrite each of them, but save the info to restore when we end.
3833 //
3834 for (HandleCounter = 0; HandleCounter < (BufferSize/sizeof (EFI_HANDLE)); HandleCounter++) {
3835 Status = gBS->OpenProtocol (
3836 Buffer[HandleCounter],
3837 &gEfiShellProtocolGuid,
3838 (VOID **)&OldShell,
3840 NULL,
3841 EFI_OPEN_PROTOCOL_GET_PROTOCOL
3842 );
3843 if (!EFI_ERROR (Status)) {
3844 OldProtocolNode = AllocateZeroPool (sizeof (SHELL_PROTOCOL_HANDLE_LIST));
3845 if (OldProtocolNode == NULL) {
3846 if (!IsListEmpty (&ShellInfoObject.OldShellList.Link)) {
3847 CleanUpShellProtocol (&mShellProtocol);
3848 }
3849
3850 Status = EFI_OUT_OF_RESOURCES;
3851 break;
3852 }
3853
3854 //
3855 // reinstall over the old one...
3856 //
3857 OldProtocolNode->Handle = Buffer[HandleCounter];
3858 OldProtocolNode->Interface = OldShell;
3859 Status = gBS->ReinstallProtocolInterface (
3860 OldProtocolNode->Handle,
3861 &gEfiShellProtocolGuid,
3862 OldProtocolNode->Interface,
3863 (VOID *)(&mShellProtocol)
3864 );
3865 if (!EFI_ERROR (Status)) {
3866 //
3867 // we reinstalled successfully. log this so we can reverse it later.
3868 //
3869
3870 //
3871 // add to the list for subsequent...
3872 //
3873 InsertTailList (&ShellInfoObject.OldShellList.Link, &OldProtocolNode->Link);
3874 }
3875 }
3876 }
3877
3878 FreePool (Buffer);
3879 } else if (Status == EFI_NOT_FOUND) {
3880 ASSERT (IsListEmpty (&ShellInfoObject.OldShellList.Link));
3881 //
3882 // no one else published yet. just publish it ourselves.
3883 //
3884 Status = gBS->InstallProtocolInterface (
3885 &gImageHandle,
3886 &gEfiShellProtocolGuid,
3888 (VOID *)(&mShellProtocol)
3889 );
3890 }
3891
3892 if (PcdGetBool (PcdShellSupportOldProtocols)) {
3895 }
3896
3897 if (!EFI_ERROR (Status)) {
3898 *NewShell = &mShellProtocol;
3899 }
3900
3901 return (Status);
3902}
3903
3916 IN OUT EFI_SHELL_PROTOCOL *NewShell
3917 )
3918{
3920
3921 //
3922 // if we need to restore old protocols...
3923 //
3924 if (!IsListEmpty (&ShellInfoObject.OldShellList.Link)) {
3925 for (Node2 = (SHELL_PROTOCOL_HANDLE_LIST *)GetFirstNode (&ShellInfoObject.OldShellList.Link)
3926 ; !IsListEmpty (&ShellInfoObject.OldShellList.Link)
3927 ; Node2 = (SHELL_PROTOCOL_HANDLE_LIST *)GetFirstNode (&ShellInfoObject.OldShellList.Link)
3928 )
3929 {
3930 RemoveEntryList (&Node2->Link);
3931 gBS->ReinstallProtocolInterface (Node2->Handle, &gEfiShellProtocolGuid, NewShell, Node2->Interface);
3932 FreePool (Node2);
3933 }
3934 } else {
3935 //
3936 // no need to restore
3937 //
3938 gBS->UninstallProtocolInterface (gImageHandle, &gEfiShellProtocolGuid, NewShell);
3939 }
3940
3941 return EFI_SUCCESS;
3942}
3943
3953 IN OUT EFI_SHELL_PROTOCOL *NewShell
3954 )
3955{
3956 EFI_STATUS Status;
3958
3959 CleanUpShellProtocol (NewShell);
3960
3961 Status = gBS->CloseEvent (NewShell->ExecutionBreak);
3962 NewShell->ExecutionBreak = NULL;
3963
3964 Status = gBS->OpenProtocol (
3966 &gEfiSimpleTextInputExProtocolGuid,
3967 (VOID **)&SimpleEx,
3969 NULL,
3970 EFI_OPEN_PROTOCOL_GET_PROTOCOL
3971 );
3972
3973 if (!EFI_ERROR (Status)) {
3974 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlCNotifyHandle1);
3975 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlCNotifyHandle2);
3976 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlCNotifyHandle3);
3977 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlCNotifyHandle4);
3978 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlSNotifyHandle1);
3979 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlSNotifyHandle2);
3980 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlSNotifyHandle3);
3981 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, ShellInfoObject.CtrlSNotifyHandle4);
3982 }
3983
3984 return (Status);
3985}
3986
3995EFIAPI
3997 IN EFI_KEY_DATA *KeyData
3998 )
3999{
4000 if (((KeyData->Key.UnicodeChar == L'c') &&
4001 ((KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED)) || (KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED)))) ||
4002 (KeyData->Key.UnicodeChar == 3)
4003 )
4004 {
4005 if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {
4006 return (EFI_UNSUPPORTED);
4007 }
4008
4009 return (gBS->SignalEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak));
4010 } else if ((KeyData->Key.UnicodeChar == L's') &&
4011 ((KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED)) || (KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED)))
4012 )
4013 {
4014 ShellInfoObject.HaltOutput = TRUE;
4015 }
4016
4017 return (EFI_SUCCESS);
4018}
4019
4029 VOID
4030 )
4031{
4033 EFI_KEY_DATA KeyData;
4034 EFI_STATUS Status;
4035
4036 Status = gBS->OpenProtocol (
4038 &gEfiSimpleTextInputExProtocolGuid,
4039 (VOID **)&SimpleEx,
4041 NULL,
4042 EFI_OPEN_PROTOCOL_GET_PROTOCOL
4043 );
4044 if (EFI_ERROR (Status)) {
4046 -1,
4047 -1,
4048 NULL,
4049 STRING_TOKEN (STR_SHELL_NO_IN_EX),
4050 ShellInfoObject.HiiHandle
4051 );
4052 return (EFI_SUCCESS);
4053 }
4054
4055 if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) {
4056 return (EFI_UNSUPPORTED);
4057 }
4058
4059 KeyData.KeyState.KeyToggleState = 0;
4060 KeyData.Key.ScanCode = 0;
4061 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
4062 KeyData.Key.UnicodeChar = L'c';
4063
4064 Status = SimpleEx->RegisterKeyNotify (
4065 SimpleEx,
4066 &KeyData,
4068 &ShellInfoObject.CtrlCNotifyHandle1
4069 );
4070
4071 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
4072 if (!EFI_ERROR (Status)) {
4073 Status = SimpleEx->RegisterKeyNotify (
4074 SimpleEx,
4075 &KeyData,
4077 &ShellInfoObject.CtrlCNotifyHandle2
4078 );
4079 }
4080
4081 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
4082 KeyData.Key.UnicodeChar = 3;
4083 if (!EFI_ERROR (Status)) {
4084 Status = SimpleEx->RegisterKeyNotify (
4085 SimpleEx,
4086 &KeyData,
4088 &ShellInfoObject.CtrlCNotifyHandle3
4089 );
4090 }
4091
4092 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
4093 if (!EFI_ERROR (Status)) {
4094 Status = SimpleEx->RegisterKeyNotify (
4095 SimpleEx,
4096 &KeyData,
4098 &ShellInfoObject.CtrlCNotifyHandle4
4099 );
4100 }
4101
4102 return (Status);
4103}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
LIST_ENTRY *EFIAPI GetPreviousNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:369
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
RETURN_STATUS EFIAPI StrCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:405
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
CHAR16 *EFIAPI PathCleanUpDirectories(IN CHAR16 *Path)
Definition: FilePaths.c:68
BOOLEAN EFIAPI PathRemoveLastItem(IN OUT CHAR16 *Path)
Definition: FilePaths.c:22
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
RETURN_STATUS EFIAPI StrnCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:310
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR16 *EFIAPI StrStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
Definition: String.c:224
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MEDIA_FILEPATH_DP
Definition: DevicePath.h:1098
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI FileDevicePath(IN EFI_HANDLE Device OPTIONAL, IN CONST CHAR16 *FileName)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL)
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
BOOLEAN EFIAPI IsDevicePathEndType(IN CONST VOID *Node)
VOID EFIAPI SetDevicePathEndNode(OUT VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS EFIAPI FileHandleFlush(IN EFI_FILE_HANDLE FileHandle)
EFI_STATUS EFIAPI FileHandleGetFileName(IN CONST EFI_FILE_HANDLE Handle, OUT CHAR16 **FullFileName)
EFI_STATUS EFIAPI FileHandleSetInfo(IN EFI_FILE_HANDLE FileHandle, IN CONST EFI_FILE_INFO *FileInfo)
EFI_STATUS EFIAPI FileHandleGetPosition(IN EFI_FILE_HANDLE FileHandle, OUT UINT64 *Position)
EFI_STATUS EFIAPI FileHandleSetPosition(IN EFI_FILE_HANDLE FileHandle, IN UINT64 Position)
EFI_FILE_INFO *EFIAPI FileHandleGetInfo(IN EFI_FILE_HANDLE FileHandle)
EFI_STATUS EFIAPI FileHandleFindNextFile(IN EFI_FILE_HANDLE DirHandle, OUT EFI_FILE_INFO *Buffer, OUT BOOLEAN *NoFile)
EFI_STATUS EFIAPI FileHandleClose(IN EFI_FILE_HANDLE FileHandle)
EFI_STATUS EFIAPI FileHandleGetSize(IN EFI_FILE_HANDLE FileHandle, OUT UINT64 *Size)
EFI_STATUS EFIAPI FileHandleDelete(IN EFI_FILE_HANDLE FileHandle)
EFI_STATUS EFIAPI FileHandleFindFirstFile(IN EFI_FILE_HANDLE DirHandle, OUT EFI_FILE_INFO **Buffer)
EFI_STATUS EFIAPI FileHandleWrite(IN EFI_FILE_HANDLE FileHandle, IN OUT UINTN *BufferSize, IN VOID *Buffer)
EFI_STATUS EFIAPI FileHandleRead(IN EFI_FILE_HANDLE FileHandle, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
EFI_FILE_PROTOCOL FileInterfaceNulFile
EFI_FILE_PROTOCOL * CreateFileInterfaceEnv(IN CONST CHAR16 *EnvName)
EFI_FILE_PROTOCOL FileInterfaceStdErr
EFI_FILE_PROTOCOL FileInterfaceStdOut
CHAR16 *EFIAPI GetStringNameFromGuid(IN CONST EFI_GUID *Guid, IN CONST CHAR8 *Lang OPTIONAL)
CHAR8 *EFIAPI GetBestLanguageForDriver(IN CONST CHAR8 *SupportedLanguages, IN CONST CHAR8 *InputLanguage, IN BOOLEAN Iso639Language)
EFI_STATUS EFIAPI GetGuidFromStringName(IN CONST CHAR16 *Name, IN CONST CHAR8 *Lang OPTIONAL, OUT EFI_GUID **Guid)
#define PARSE_HANDLE_DATABASE_PARENTS(ControllerHandle, Count, Buffer)
EFI_STATUS EFIAPI AddNewGuidNameMapping(IN CONST EFI_GUID *Guid, IN CONST CHAR16 *TheName, IN CONST CHAR8 *Lang OPTIONAL)
EFI_STATUS EFIAPI ParseHandleDatabaseByRelationship(IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL, IN CONST EFI_HANDLE ControllerHandle OPTIONAL, IN CONST UINTN Mask, IN UINTN *MatchingHandleCount, OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL)
#define PARSE_HANDLE_DATABASE_UEFI_DRIVERS(ControllerHandle, Count, Buffer)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
EFI_FILE_INFO *(EFIAPI * EFI_SHELL_GET_FILE_INFO)(IN SHELL_FILE_HANDLE FileHandle)
Definition: Shell.h:584
EFI_STATUS(EFIAPI * EFI_SHELL_SET_FILE_INFO)(IN SHELL_FILE_HANDLE FileHandle, IN CONST EFI_FILE_INFO *FileInfo)
Definition: Shell.h:1102
EFI_STATUS(EFIAPI * EFI_SHELL_WRITE_FILE)(IN SHELL_FILE_HANDLE FileHandle, IN OUT UINTN *BufferSize, IN VOID *Buffer)
Definition: Shell.h:1174
EFI_STATUS(EFIAPI * EFI_SHELL_GET_FILE_POSITION)(IN SHELL_FILE_HANDLE FileHandle, OUT UINT64 *Position)
Definition: Shell.h:621
EFI_STATUS(EFIAPI * EFI_SHELL_DELETE_FILE)(IN SHELL_FILE_HANDLE FileHandle)
Definition: Shell.h:249
EFI_STATUS(EFIAPI * EFI_SHELL_READ_FILE)(IN SHELL_FILE_HANDLE FileHandle, IN OUT UINTN *ReadSize, IN OUT VOID *Buffer)
Definition: Shell.h:928
EFI_STATUS(EFIAPI * EFI_SHELL_SET_FILE_POSITION)(IN SHELL_FILE_HANDLE FileHandle, IN UINT64 Position)
Definition: Shell.h:1124
EFI_STATUS(EFIAPI * EFI_SHELL_GET_FILE_SIZE)(IN SHELL_FILE_HANDLE FileHandle, OUT UINT64 *Size)
Definition: Shell.h:639
EFI_STATUS(EFIAPI * EFI_SHELL_FLUSH_FILE)(IN SHELL_FILE_HANDLE FileHandle)
Definition: Shell.h:391
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
EFI_STATUS RunShellCommand(IN CONST CHAR16 *CmdLine, OUT EFI_STATUS *CommandStatus)
Definition: Shell.c:2780
VOID * AddBufferToFreeList(VOID *Buffer)
Definition: Shell.c:1480
BOOLEAN EFIAPI ShellFileHandleRemove(IN CONST SHELL_FILE_HANDLE Handle)
SHELL_FILE_HANDLE EFIAPI ConvertEfiFileProtocolToShellHandle(IN CONST EFI_FILE_PROTOCOL *Handle, IN CONST CHAR16 *Path)
EFI_STATUS EFIAPI ShellCommandAddMapItemAndUpdatePath(IN CONST CHAR16 *Name, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST UINT64 Flags, IN CONST BOOLEAN Path)
CONST CHAR16 *EFIAPI ShellCommandGetManFileNameHandler(IN CONST CHAR16 *CommandString)
SHELL_MAP_LIST gShellMapList
List of Mappings - DeviceName and Drive Letter(ism).
CONST CHAR16 *EFIAPI ShellFileHandleGetPath(IN CONST SHELL_FILE_HANDLE Handle)
SHELL_MAP_LIST * gShellCurMapping
Pointer to node of current directory in the mMapList.
EFI_FILE_PROTOCOL *EFIAPI ConvertShellHandleToEfiFileProtocol(IN CONST SHELL_FILE_HANDLE Handle)
SHELL_MAP_LIST *EFIAPI ShellCommandFindMapItem(IN CONST CHAR16 *MapKey)
EFI_STATUS EFIAPI ShellSortFileList(IN OUT EFI_SHELL_FILE_INFO **FileList, OUT EFI_SHELL_FILE_INFO **Duplicates OPTIONAL, IN SHELL_SORT_FILE_LIST Order)
SCRIPT_FILE *EFIAPI ShellCommandGetCurrentScriptFile(VOID)
BOOLEAN EFIAPI ShellCommandIsOnAliasList(IN CONST CHAR16 *Alias)
EFI_STATUS ShellFindEnvVarInList(IN CONST CHAR16 *Key, OUT CHAR16 **Value, OUT UINTN *ValueSize, OUT UINT32 *Atts OPTIONAL)
Definition: ShellEnvVar.c:426
EFI_STATUS ShellInitEnvVarList(VOID)
Definition: ShellEnvVar.c:576
EFI_STATUS IsVolatileEnv(IN CONST CHAR16 *EnvVarName, OUT BOOLEAN *Volatile)
Definition: ShellEnvVar.c:29
EFI_STATUS GetEnvironmentVariableList(IN OUT LIST_ENTRY *ListHead)
Definition: ShellEnvVar.c:134
EFI_STATUS ShellAddEnvVarToList(IN CONST CHAR16 *Key, IN CONST CHAR16 *Value, IN UINTN ValueSize, IN UINT32 Atts)
Definition: ShellEnvVar.c:472
EFI_STATUS ShellRemvoeEnvVarFromList(IN CONST CHAR16 *Key)
Definition: ShellEnvVar.c:543
EFI_STATUS SetEnvironmentVariableList(IN LIST_ENTRY *ListHead)
Definition: ShellEnvVar.c:254
VOID ShellFreeEnvVarList(VOID)
Definition: ShellEnvVar.c:593
EFI_STATUS SetEnvironmentVariables(IN CONST CHAR16 **Environment)
Definition: ShellEnvVar.c:322
#define SHELL_SET_ENVIRONMENT_VARIABLE_NV(EnvVarName, BufferSize, Buffer)
Definition: ShellEnvVar.h:75
#define SHELL_DELETE_ENVIRONMENT_VARIABLE(EnvVarName)
Definition: ShellEnvVar.h:55
#define SHELL_SET_ENVIRONMENT_VARIABLE_V(EnvVarName, BufferSize, Buffer)
Definition: ShellEnvVar.h:136
#define SHELL_GET_ENVIRONMENT_VARIABLE(EnvVarName, BufferSize, Buffer)
Definition: ShellEnvVar.h:95
#define SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES(EnvVarName, Atts, BufferSize, Buffer)
Definition: ShellEnvVar.h:116
EFI_STATUS EFIAPI ShellPrintHiiEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR8 *Language OPTIONAL, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle,...)
CHAR16 *EFIAPI StrnCatGrow(IN OUT CHAR16 **Destination, IN OUT UINTN *CurrentSize, IN CONST CHAR16 *Source, IN UINTN Count)
EFI_STATUS ProcessManFile(IN CONST CHAR16 *ManFileName, IN CONST CHAR16 *Command, IN CONST CHAR16 *Sections OPTIONAL, OUT CHAR16 **BriefDesc OPTIONAL, OUT CHAR16 **HelpText)
EFI_STATUS UpdateArgcArgv(IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, IN CONST CHAR16 *NewCommandLine, IN SHELL_OPERATION_TYPES Type, OUT CHAR16 ***OldArgv OPTIONAL, OUT UINTN *OldArgc OPTIONAL)
EFI_STATUS CleanUpShellProtocol(IN OUT EFI_SHELL_PROTOCOL *NewShell)
CONST CHAR16 *EFIAPI EfiShellGetEnvEx(IN CONST CHAR16 *Name, OUT UINT32 *Attributes OPTIONAL)
EFI_STATUS InternalOpenFileDevicePath(IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT SHELL_FILE_HANDLE *FileHandle, IN UINT64 OpenMode, IN UINT64 Attributes OPTIONAL)
CONST CHAR16 *EFIAPI EfiShellGetMapFromDevicePath(IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath)
EFI_STATUS EFIAPI EfiShellGetGuidName(IN CONST EFI_GUID *Guid, OUT CONST CHAR16 **GuidName)
BOOLEAN EFIAPI EfiShellBatchIsActive(VOID)
BOOLEAN EFIAPI EfiShellGetPageBreak(VOID)
EFI_STATUS EFIAPI EfiShellOpenFileList(IN CHAR16 *Path, IN UINT64 OpenMode, IN OUT EFI_SHELL_FILE_INFO **FileList)
EFI_STATUS InternalShellExecute(IN CONST CHAR16 *CommandLine OPTIONAL, IN CONST CHAR16 **Environment OPTIONAL, OUT EFI_STATUS *StartImageStatus OPTIONAL)
VOID InternalFreeShellFileInfoNode(IN EFI_SHELL_FILE_INFO *FileListNode)
BOOLEAN InternalShellProtocolIsSimpleFileSystemPresent(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition: ShellProtocol.c:77
EFI_STATUS EFIAPI NotificationFunction(IN EFI_KEY_DATA *KeyData)
CONST CHAR16 *EFIAPI EfiShellGetEnv(IN CONST CHAR16 *Name)
EFI_SHELL_FILE_INFO * InternalDuplicateShellFileInfo(IN EFI_SHELL_FILE_INFO *Node, IN BOOLEAN Save)
EFI_STATUS EFIAPI EfiShellRemoveDupInFileList(IN EFI_SHELL_FILE_INFO **FileList)
VOID EFIAPI EfiShellEnablePageBreak(VOID)
STATIC BOOLEAN NestingEnabled(VOID)
EFI_STATUS EFIAPI EfiShellGetGuidFromName(IN CONST CHAR16 *GuidName, OUT EFI_GUID *Guid)
EFI_STATUS EFIAPI EfiShellCreateFile(IN CONST CHAR16 *FileName, IN UINT64 FileAttribs, OUT SHELL_FILE_HANDLE *FileHandle)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI EfiShellGetDevicePathFromFilePath(IN CONST CHAR16 *Path)
EFI_STATUS EFIAPI EfiShellDeleteFileByName(IN CONST CHAR16 *FileName)
CONST EFI_DEVICE_PATH_PROTOCOL *EFIAPI EfiShellGetDevicePathFromMap(IN CONST CHAR16 *Mapping)
CHAR16 *EFIAPI EfiShellGetFilePathFromDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *Path)
VOID EFIAPI EfiShellDisablePageBreak(VOID)
EFI_SHELL_FILE_INFO * CreateAndPopulateShellFileInfo(IN CONST CHAR16 *BasePath, IN CONST EFI_STATUS Status, IN CONST CHAR16 *FileName, IN CONST SHELL_FILE_HANDLE Handle, IN CONST EFI_FILE_INFO *Info)
EFI_STATUS EFIAPI EfiShellSetCurDir(IN CONST CHAR16 *FileSystem OPTIONAL, IN CONST CHAR16 *Dir)
EFI_STATUS EFIAPI EfiShellOpenFileByName(IN CONST CHAR16 *FileName, OUT SHELL_FILE_HANDLE *FileHandle, IN UINT64 OpenMode)
EFI_STATUS EFIAPI EfiShellSetEnv(IN CONST CHAR16 *Name, IN CONST CHAR16 *Value, IN BOOLEAN Volatile)
CONST CHAR16 *EFIAPI EfiShellGetAlias(IN CONST CHAR16 *Alias, OUT BOOLEAN *Volatile OPTIONAL)
EFI_STATUS EFIAPI EfiShellOpenRootByHandle(IN EFI_HANDLE DeviceHandle, OUT SHELL_FILE_HANDLE *FileHandle)
BOOLEAN EFIAPI EfiShellIsRootShell(VOID)
EFI_STATUS EFIAPI EfiShellExecute(IN EFI_HANDLE *ParentImageHandle, IN CHAR16 *CommandLine OPTIONAL, IN CHAR16 **Environment OPTIONAL, OUT EFI_STATUS *StatusCode OPTIONAL)
EFI_STATUS EFIAPI EfiShellFreeFileList(IN EFI_SHELL_FILE_INFO **FileList)
EFI_STATUS EFIAPI EfiShellFindFilesInDir(IN SHELL_FILE_HANDLE FileDirHandle, OUT EFI_SHELL_FILE_INFO **FileList)
CONST CHAR16 *EFIAPI EfiShellGetCurDir(IN CONST CHAR16 *FileSystemMapping OPTIONAL)
EFI_STATUS InternalShellExecuteDevicePath(IN CONST EFI_HANDLE *ParentImageHandle, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *CommandLine OPTIONAL, IN CONST CHAR16 **Environment OPTIONAL, OUT EFI_STATUS *StartImageStatus OPTIONAL)
EFI_STATUS InternalEfiShellSetEnv(IN CONST CHAR16 *Name, IN CONST CHAR16 *Value, IN BOOLEAN Volatile)
EFI_STATUS EFIAPI EfiShellGetDeviceName(IN EFI_HANDLE DeviceHandle, IN EFI_SHELL_DEVICE_NAME_FLAGS Flags, IN CHAR8 *Language, OUT CHAR16 **BestDeviceName)
EFI_STATUS EFIAPI EfiShellRegisterGuidName(IN CONST EFI_GUID *Guid, IN CONST CHAR16 *GuidName)
EFI_STATUS EFIAPI EfiShellSetAlias(IN CONST CHAR16 *Command, IN CONST CHAR16 *Alias, IN BOOLEAN Replace, IN BOOLEAN Volatile)
EFI_STATUS InternalSetAlias(IN CONST CHAR16 *Command, IN CONST CHAR16 *Alias, IN BOOLEAN Volatile)
BOOLEAN InternalShellProtocolIsBlockIoPresent(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition: ShellProtocol.c:47
EFI_STATUS EFIAPI EfiShellGetHelpText(IN CONST CHAR16 *Command, IN CONST CHAR16 *Sections OPTIONAL, OUT CHAR16 **HelpText)
CHAR16 * InternalEfiShellGetListAlias(VOID)
EFI_STATUS EFIAPI EfiShellFindFiles(IN CONST CHAR16 *FilePattern, OUT EFI_SHELL_FILE_INFO **FileList)
EFI_STATUS CreatePopulateInstallShellProtocol(IN OUT EFI_SHELL_PROTOCOL **NewShell)
EFI_STATUS InernalEfiShellStartMonitor(VOID)
EFI_STATUS EFIAPI EfiShellSetMap(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST CHAR16 *Mapping)
EFI_STATUS ShellSearchHandle(IN CONST CHAR16 *FilePattern, IN EFI_UNICODE_COLLATION_PROTOCOL *UnicodeCollation, IN SHELL_FILE_HANDLE FileHandle, IN OUT EFI_SHELL_FILE_INFO **FileList, IN CONST EFI_SHELL_FILE_INFO *ParentNode OPTIONAL, IN CONST CHAR16 *MapName)
CHAR16 * ToLower(CHAR16 *Str)
EFI_STATUS EFIAPI EfiShellOpenRoot(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT SHELL_FILE_HANDLE *FileHandle)
EFI_STATUS EFIAPI EfiShellClose(IN SHELL_FILE_HANDLE FileHandle)
Definition: ShellProtocol.c:29
EFI_STATUS CleanUpShellEnvironment(IN OUT EFI_SHELL_PROTOCOL *NewShell)
INTN EFIAPI StringNoCaseCompare(IN CONST VOID *Buffer1, IN CONST VOID *Buffer2)
Definition: BaseSortLib.c:92
INTN EFIAPI DevicePathCompare(IN CONST VOID *Buffer1, IN CONST VOID *Buffer2)
Definition: BaseSortLib.c:73
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
#define STRING_TOKEN(t)
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1317
@ EfiLoaderCode
#define EFI_VARIABLE_NON_VOLATILE
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_KEY_TOGGLE_STATE KeyToggleState
UINT32 KeyShiftState
UINT64 Size
Definition: FileInfo.h:23
CHAR16 FileName[1]
Definition: FileInfo.h:52
EFI_INPUT_KEY Key
EFI_KEY_STATE KeyState
VOID * LoadOptions
A pointer to the image's binary load options.
Definition: LoadedImage.h:62
UINT32 LoadOptionsSize
The size in bytes of LoadOptions.
Definition: LoadedImage.h:61
EFI_MEMORY_TYPE ImageCodeType
The memory type that the code sections were loaded as.
Definition: LoadedImage.h:69
EFI_STATUS Status
Status of opening the file. Valid only if Handle != NULL.
CHAR16 * FileName
name of this file.
EFI_FILE_INFO * Info
Pointer to the FileInfo struct for this file or NULL.
SHELL_FILE_HANDLE Handle
Handle for interacting with the opened file or NULL if closed.
CHAR16 * FullName
Fully qualified filename.
LIST_ENTRY Link
Linked list members.
LIST_ENTRY Link
Linked list members.
Definition: Shell.h:153
SHELL_FILE_HANDLE Handle
Handle for interacting with the opened file or NULL if closed.
Definition: Shell.h:157
EFI_FILE_INFO * Info
Pointer to the FileInfo struct for this file or NULL.
Definition: Shell.h:158
EFI_STATUS Status
Status of opening the file. Valid only if Handle != NULL.
Definition: Shell.h:154
CONST CHAR16 * FullName
Fully qualified filename.
Definition: Shell.h:155
CONST CHAR16 * FileName
name of this file.
Definition: Shell.h:156
EFI_HANDLE ConsoleInHandle
Definition: UefiSpec.h:2048
Definition: Base.h:213
UINT32 NoNest
Was "-nonest" found on command line.
Definition: Shell.h:74
VOID * CtrlCNotifyHandle3
The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
Definition: Shell.h:116
EFI_DEVICE_PATH_PROTOCOL * FileDevPath
DevicePath for ourselves.
Definition: Shell.h:109
VOID * CtrlCNotifyHandle4
The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
Definition: Shell.h:117
BOOLEAN HaltOutput
TRUE to start a CTRL-S halt.
Definition: Shell.h:122
EFI_DEVICE_PATH_PROTOCOL * ImageDevPath
DevicePath for ourselves.
Definition: Shell.h:108
VOID * CtrlCNotifyHandle1
The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
Definition: Shell.h:114
EFI_HII_HANDLE HiiHandle
Handle from HiiLib.
Definition: Shell.h:105
VOID * CtrlSNotifyHandle4
The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
Definition: Shell.h:121
VOID * CtrlCNotifyHandle2
The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
Definition: Shell.h:115
VOID * CtrlSNotifyHandle2
The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
Definition: Shell.h:119
SHELL_PROTOCOL_HANDLE_LIST OldShellList
List of other instances to reinstall when closing.
Definition: Shell.h:112
VOID * CtrlSNotifyHandle3
The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
Definition: Shell.h:120
VOID * CtrlSNotifyHandle1
The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
Definition: Shell.h:118