2 Main file for map shell level 2 command.
4 (C) Copyright 2013-2014, Hewlett-Packard Development Company, L.P.
5 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UefiShellLevel2CommandsLib.h"
17 #include <Protocol/SimpleFileSystem.h>
18 #include <Protocol/BlockIo.h>
19 #include <Library/DevicePathLib.h>
20 #include <Library/HandleParsingLib.h>
21 #include <Library/SortLib.h>
24 Determine if a string has only numbers and letters.
26 This is useful for such things as Map names which can only be letters and numbers.
28 @param[in] String pointer to the string to analyze,
29 @param[in] Len Number of characters to analyze.
31 @retval TRUE String has only numbers and letters
32 @retval FALSE String has at least one other character.
37 IN CONST CHAR16
*String
,
42 for (Count
= 0 ; Count
< Len
&& String
!= NULL
&& *String
!= CHAR_NULL
; String
++,Count
++) {
43 if (! ((*String
>= L
'a' && *String
<= L
'z') ||
44 (*String
>= L
'A' && *String
<= L
'Z') ||
45 (*String
>= L
'0' && *String
<= L
'9'))
54 Do a search in the Target delimited list.
56 @param[in] List The list to seatch in.
57 @param[in] MetaTarget The item to search for. MetaMatching supported.
58 @param[out] FullName Optional pointer to an allocated buffer containing
60 @param[in] Meta TRUE to use MetaMatching.
61 @param[in] SkipTrailingNumbers TRUE to allow for numbers after the MetaTarget.
62 @param[in] Target The single character that delimits list
68 IN CONST CHAR16
*List
,
69 IN CONST CHAR16
*MetaTarget
,
70 OUT CHAR16
**FullName OPTIONAL
,
71 IN CONST BOOLEAN Meta
,
72 IN CONST BOOLEAN SkipTrailingNumbers
,
73 IN CONST CHAR16
*Target
78 CONST CHAR16
*ListWalker
;
82 for (ListWalker
= List
, TempList
= NULL
83 ; ListWalker
!= NULL
&& *ListWalker
!= CHAR_NULL
86 TempList
= StrnCatGrow(&TempList
, NULL
, ListWalker
, 0);
87 ASSERT(TempList
!= NULL
);
88 TempSpot
= StrStr(TempList
, Target
);
89 if (TempSpot
!= NULL
) {
90 *TempSpot
= CHAR_NULL
;
93 while (SkipTrailingNumbers
&& (ShellIsDecimalDigitCharacter(TempList
[StrLen(TempList
)-1]) || TempList
[StrLen(TempList
)-1] == L
':')) {
94 TempList
[StrLen(TempList
)-1] = CHAR_NULL
;
97 ListWalker
= StrStr(ListWalker
, Target
);
98 while(ListWalker
!= NULL
&& *ListWalker
== *Target
) {
102 Result
= gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, (CHAR16
*)TempList
, (CHAR16
*)MetaTarget
);
104 Result
= (BOOLEAN
)(StrCmp(TempList
, MetaTarget
)==0);
107 if (FullName
!= NULL
) {
108 *FullName
= TempList
;
122 Determine what type of device is represented and return it's string. The
123 string is in allocated memory and must be callee freed. The HII is is listed below.
124 The actual string cannot be determined.
126 @param[in] DevicePath The device to analyze.
128 @retval STR_MAP_MEDIA_UNKNOWN The media type is unknown.
129 @retval STR_MAP_MEDIA_HARDDISK The media is a hard drive.
130 @retval STR_MAP_MEDIA_CDROM The media is a CD ROM.
131 @retval STR_MAP_MEDIA_FLOPPY The media is a floppy drive.
136 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
139 ACPI_HID_DEVICE_PATH
*Acpi
;
142 // Parse the device path:
143 // Devicepath sub type mediatype
144 // MEDIA_HANRDDRIVE_DP -> Hard Disk
145 // MEDIA_CDROM_DP -> CD Rom
146 // Acpi.HID = 0X0604 -> Floppy
148 if (NULL
== DevicePath
) {
149 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_UNKNOWN
), NULL
);
152 for (;!IsDevicePathEndType (DevicePath
) ;DevicePath
= NextDevicePathNode (DevicePath
)) {
153 if (DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) {
154 switch (DevicePathSubType (DevicePath
)) {
155 case MEDIA_HARDDRIVE_DP
:
156 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_HARDDISK
), NULL
);
158 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_CDROM
), NULL
);
160 } else if (DevicePathType (DevicePath
) == ACPI_DEVICE_PATH
) {
161 Acpi
= (ACPI_HID_DEVICE_PATH
*) DevicePath
;
162 if (EISA_ID_TO_NUM (Acpi
->HID
) == 0x0604) {
163 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_FLOPPY
), NULL
);
168 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_UNKNOWN
), NULL
);
172 Function to detemine if a handle has removable storage.
174 @param[in] DevicePath DevicePath to test.
176 @retval TRUE The handle has removable storage.
177 @retval FALSE The handle does not have removable storage.
182 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
185 if (NULL
== DevicePath
) {
189 while (!IsDevicePathEndType (DevicePath
)) {
190 if (DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) {
191 switch (DevicePathSubType (DevicePath
)) {
199 DevicePath
= NextDevicePathNode (DevicePath
);
205 Function to detemine if a something on the map list matches.
207 @param[in] MapList The pointer to the list to test.
208 @param[in] Specific The pointer to a specific name to test for.
209 @param[in] TypeString The pointer to the list of types.
210 @param[in] Normal Always show normal mappings.
211 @param[in] Consist Always show consistent mappings.
213 @retval TRUE The map should be displayed.
214 @retval FALSE The map should not be displayed.
219 IN CONST CHAR16
*MapList
,
220 IN CONST CHAR16
*Specific
,
221 IN CONST CHAR16
*TypeString
,
222 IN CONST BOOLEAN Normal
,
223 IN CONST BOOLEAN Consist
228 // specific has priority
230 if (Specific
!= NULL
) {
231 NewSpecific
= AllocateZeroPool(StrSize(Specific
) + sizeof(CHAR16
));
232 if (NewSpecific
== NULL
){
235 StrCpy(NewSpecific
, Specific
);
236 if (NewSpecific
[StrLen(NewSpecific
)-1] != L
':') {
237 StrCat(NewSpecific
, L
":");
240 if (SearchList(MapList
, NewSpecific
, NULL
, TRUE
, FALSE
, L
";")) {
241 FreePool(NewSpecific
);
244 FreePool(NewSpecific
);
248 && (SearchList(MapList
, L
"HD*", NULL
, TRUE
, TRUE
, L
";")
249 ||SearchList(MapList
, L
"CD*", NULL
, TRUE
, TRUE
, L
";")
250 ||SearchList(MapList
, L
"F*", NULL
, TRUE
, TRUE
, L
";")
251 ||SearchList(MapList
, L
"FP*", NULL
, TRUE
, TRUE
, L
";"))){
257 && (SearchList(MapList
, L
"FS", NULL
, FALSE
, TRUE
, L
";")
258 ||SearchList(MapList
, L
"BLK", NULL
, FALSE
, TRUE
, L
";"))){
262 if (TypeString
!= NULL
&& SearchList(MapList
, TypeString
, NULL
, TRUE
, TRUE
, L
";")) {
270 Display a single map line for device Handle if conditions are met.
272 @param[in] Verbose TRUE to display (extra) verbose information.
273 @param[in] Consist TRUE to display consistent mappings.
274 @param[in] Normal TRUE to display normal (not consist) mappings.
275 @param[in] TypeString pointer to string of filter types.
276 @param[in] SFO TRUE to display output in Standard Output Format.
277 @param[in] Specific pointer to string for specific map to display.
278 @param[in] Handle The handle to display from.
280 @retval EFI_SUCCESS The mapping was displayed.
284 PerformSingleMappingDisplay(
285 IN CONST BOOLEAN Verbose
,
286 IN CONST BOOLEAN Consist
,
287 IN CONST BOOLEAN Normal
,
288 IN CONST CHAR16
*TypeString
,
289 IN CONST BOOLEAN SFO
,
290 IN CONST CHAR16
*Specific OPTIONAL
,
291 IN CONST EFI_HANDLE Handle
294 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
295 EFI_DEVICE_PATH_PROTOCOL
*DevPathCopy
;
296 CONST CHAR16
*MapList
;
299 CHAR16
*DevPathString
;
304 CONST CHAR16
*TempSpot2
;
309 DevPath
= DevicePathFromHandle(Handle
);
310 DevPathCopy
= DevPath
;
311 MapList
= gEfiShellProtocol
->GetMapFromDevicePath(&DevPathCopy
);
312 if (MapList
== NULL
) {
313 return EFI_NOT_FOUND
;
316 if (!MappingListHasType(MapList
, Specific
, TypeString
, Normal
, Consist
)){
317 return EFI_NOT_FOUND
;
320 if (Normal
|| !Consist
) {
322 // need the Normal here since people can use both on command line. otherwise unused.
329 CurrentName
= StrnCatGrow(&CurrentName
, 0, MapList
, 0);
330 if (CurrentName
== NULL
) {
331 return (EFI_OUT_OF_RESOURCES
);
335 // Chop off the other names that become "Alias(s)"
336 // leaving just the normal name
338 TempSpot
= StrStr(CurrentName
, L
";");
339 if (TempSpot
!= NULL
) {
340 *TempSpot
= CHAR_NULL
;
346 // Skip the first name. This is the standard name.
348 TempSpot
= StrStr(MapList
, L
";");
349 if (TempSpot
!= NULL
) {
352 SearchList(TempSpot
, L
"HD*", &CurrentName
, TRUE
, FALSE
, L
";");
353 if (CurrentName
== NULL
) {
354 SearchList(TempSpot
, L
"CD*", &CurrentName
, TRUE
, FALSE
, L
";");
356 if (CurrentName
== NULL
) {
357 SearchList(TempSpot
, L
"FP*", &CurrentName
, TRUE
, FALSE
, L
";");
359 if (CurrentName
== NULL
) {
360 SearchList(TempSpot
, L
"F*", &CurrentName
, TRUE
, FALSE
, L
";");
362 if (CurrentName
== NULL
) {
364 // We didnt find anything, so just the first one in the list...
366 CurrentName
= StrnCatGrow(&CurrentName
, 0, MapList
, 0);
367 if (CurrentName
== NULL
) {
368 return (EFI_OUT_OF_RESOURCES
);
370 TempSpot
= StrStr(CurrentName
, L
";");
371 if (TempSpot
!= NULL
) {
372 *TempSpot
= CHAR_NULL
;
375 Alias
= StrnCatGrow(&Alias
, 0, MapList
, 0);
377 return EFI_OUT_OF_RESOURCES
;
379 TempSpot
= StrStr(Alias
, CurrentName
);
380 if (TempSpot
!= NULL
) {
381 TempSpot2
= StrStr(TempSpot
, L
";");
382 if (TempSpot2
!= NULL
) {
383 TempSpot2
++; // Move past ";" from CurrentName
384 CopyMem(TempSpot
, TempSpot2
, StrSize(TempSpot2
));
386 *TempSpot
= CHAR_NULL
;
389 if (Alias
[StrLen(Alias
)-1] == L
';') {
390 Alias
[StrLen(Alias
)-1] = CHAR_NULL
;
394 DevPathString
= ConvertDevicePathToText(DevPath
, TRUE
, FALSE
);
395 TempLen
= StrLen(CurrentName
);
401 STRING_TOKEN (STR_MAP_ENTRY
),
402 gShellLevel2HiiHandle
,
404 Alias
!=NULL
?Alias
:(TempLen
< StrLen(MapList
)?MapList
+ TempLen
+1:L
""),
409 // also print handle, media type, removable (y/n), and current directory
411 MediaType
= GetDeviceMediaType(DevPath
);
412 if ((TypeString
!= NULL
&&MediaType
!= NULL
&& StrStr(TypeString
, MediaType
) != NULL
) || TypeString
== NULL
) {
413 Removable
= IsRemoveableDevice(DevPath
);
414 TempSpot2
= ShellGetCurrentDir(CurrentName
);
419 STRING_TOKEN (STR_MAP_ENTRY_VERBOSE
),
420 gShellLevel2HiiHandle
,
421 ConvertHandleToHandleIndex(Handle
),
423 Removable
?L
"Yes":L
"No",
427 SHELL_FREE_NON_NULL(MediaType
);
434 STRING_TOKEN (STR_MAP_SFO_MAPPINGS
),
435 gShellLevel2HiiHandle
,
438 Consist
?L
"":(TempLen
< StrLen(MapList
)?MapList
+ TempLen
+1:L
"")
441 SHELL_FREE_NON_NULL(DevPathString
);
442 SHELL_FREE_NON_NULL(CurrentName
);
443 SHELL_FREE_NON_NULL(Alias
);
448 Delete Specific from the list of maps for device Handle.
450 @param[in] Specific The name to delete.
451 @param[in] Handle The device to look on.
453 @retval EFI_SUCCESS The delete was successful.
454 @retval EFI_NOT_FOUND Name was not a map on Handle.
458 PerformSingleMappingDelete(
459 IN CONST CHAR16
*Specific
,
460 IN CONST EFI_HANDLE Handle
463 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
464 EFI_DEVICE_PATH_PROTOCOL
*DevPathCopy
;
465 CONST CHAR16
*MapList
;
468 DevPath
= DevicePathFromHandle(Handle
);
469 DevPathCopy
= DevPath
;
470 MapList
= gEfiShellProtocol
->GetMapFromDevicePath(&DevPathCopy
);
473 if (MapList
== NULL
) {
474 return (EFI_NOT_FOUND
);
477 // if there is a specific and its not on the list...
479 if (!SearchList(MapList
, Specific
, &CurrentName
, TRUE
, FALSE
, L
";")) {
480 return (EFI_NOT_FOUND
);
482 return (gEfiShellProtocol
->SetMap(NULL
, CurrentName
));
485 CONST CHAR16 Cd
[] = L
"cd*";
486 CONST CHAR16 Hd
[] = L
"hd*";
487 CONST CHAR16 Fp
[] = L
"fp*";
488 CONST CHAR16 AnyF
[] = L
"F*";
490 Function to display mapping information to the user.
492 If Specific is specified then Consist and Normal will be ignored since information will
493 be printed for the specific item only.
495 @param[in] Verbose TRUE to display (extra) verbose information.
496 @param[in] Consist TRUE to display consistent mappings.
497 @param[in] Normal TRUE to display normal (not consist) mappings.
498 @param[in] TypeString Pointer to string of filter types.
499 @param[in] SFO TRUE to display output in Standard Output Format.
500 @param[in] Specific Pointer to string for specific map to display.
501 @param[in] Header TRUE to print the header block.
503 @retval SHELL_SUCCESS The display was printed.
504 @retval SHELL_INVALID_PARAMETER One of Consist or Normal must be TRUE if no Specific.
509 PerformMappingDisplay(
510 IN CONST BOOLEAN Verbose
,
511 IN CONST BOOLEAN Consist
,
512 IN CONST BOOLEAN Normal
,
513 IN CONST CHAR16
*TypeString
,
514 IN CONST BOOLEAN SFO
,
515 IN CONST CHAR16
*Specific OPTIONAL
,
516 IN CONST BOOLEAN Header
520 EFI_HANDLE
*HandleBuffer
;
526 if (!Consist
&& !Normal
&& Specific
== NULL
&& TypeString
== NULL
) {
527 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
);
528 return (SHELL_INVALID_PARAMETER
);
531 if (TypeString
!= NULL
) {
533 if (StrnCmp(TypeString
, Test
, StrLen(Test
)-1) != 0) {
535 if (StrnCmp(TypeString
, Test
, StrLen(Test
)-1) != 0) {
537 if (StrnCmp(TypeString
, Test
, StrLen(Test
)-1) != 0) {
538 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, TypeString
);
539 return (SHELL_INVALID_PARAMETER
);
541 } else if (Test
== NULL
) {
542 Test
= (CHAR16
*)AnyF
;
554 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MAP_HEADER
), gShellLevel2HiiHandle
);
556 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_SFO_HEADER
), gShellLevel2HiiHandle
, L
"map");
564 // Look up all SimpleFileSystems in the platform
566 Status
= gBS
->LocateHandle(
568 &gEfiSimpleFileSystemProtocolGuid
,
572 if (Status
== EFI_BUFFER_TOO_SMALL
) {
573 HandleBuffer
= AllocateZeroPool(BufferSize
);
574 if (HandleBuffer
== NULL
) {
575 return (SHELL_OUT_OF_RESOURCES
);
577 Status
= gBS
->LocateHandle(
579 &gEfiSimpleFileSystemProtocolGuid
,
586 // Get the map name(s) for each one.
588 for ( LoopVar
= 0, Found
= FALSE
589 ; LoopVar
< (BufferSize
/ sizeof(EFI_HANDLE
)) && HandleBuffer
!= NULL
592 Status
= PerformSingleMappingDisplay(
599 HandleBuffer
[LoopVar
]);
600 if (!EFI_ERROR(Status
)) {
606 // Look up all BlockIo in the platform
608 Status
= gBS
->LocateHandle(
610 &gEfiBlockIoProtocolGuid
,
614 if (Status
== EFI_BUFFER_TOO_SMALL
) {
615 SHELL_FREE_NON_NULL(HandleBuffer
);
616 HandleBuffer
= AllocateZeroPool(BufferSize
);
617 if (HandleBuffer
== NULL
) {
618 return (SHELL_OUT_OF_RESOURCES
);
620 Status
= gBS
->LocateHandle(
622 &gEfiBlockIoProtocolGuid
,
627 if (!EFI_ERROR(Status
) && HandleBuffer
!= NULL
) {
629 // Get the map name(s) for each one.
632 ; LoopVar
< BufferSize
/ sizeof(EFI_HANDLE
)
636 // Skip any that were already done...
638 if (gBS
->OpenProtocol(
639 HandleBuffer
[LoopVar
],
640 &gEfiSimpleFileSystemProtocolGuid
,
644 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) == EFI_SUCCESS
) {
647 Status
= PerformSingleMappingDisplay(
654 HandleBuffer
[LoopVar
]);
655 if (!EFI_ERROR(Status
)) {
659 FreePool(HandleBuffer
);
662 if (Specific
!= NULL
) {
663 ShellPrintHiiEx(gST
->ConOut
->Mode
->CursorColumn
, gST
->ConOut
->Mode
->CursorRow
-1, NULL
, STRING_TOKEN (STR_MAP_NF
), gShellLevel2HiiHandle
, Specific
);
665 ShellPrintHiiEx(gST
->ConOut
->Mode
->CursorColumn
, gST
->ConOut
->Mode
->CursorRow
-1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
);
668 return (SHELL_SUCCESS
);
672 Perform a mapping display and parse for multiple types in the TypeString.
674 @param[in] Verbose TRUE to use verbose output.
675 @param[in] Consist TRUE to display consistent names.
676 @param[in] Normal TRUE to display normal names.
677 @param[in] TypeString An optional comma-delimited list of types.
678 @param[in] SFO TRUE to display in SFO format. See Spec.
679 @param[in] Specific An optional specific map name to display alone.
681 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
682 @retval SHELL_SUCCESS The display was successful.
683 @sa PerformMappingDisplay
687 PerformMappingDisplay2(
688 IN CONST BOOLEAN Verbose
,
689 IN CONST BOOLEAN Consist
,
690 IN CONST BOOLEAN Normal
,
691 IN CONST CHAR16
*TypeString
,
692 IN CONST BOOLEAN SFO
,
693 IN CONST CHAR16
*Specific OPTIONAL
696 CONST CHAR16
*TypeWalker
;
697 SHELL_STATUS ShellStatus
;
701 if (TypeString
== NULL
) {
702 return (PerformMappingDisplay(Verbose
, Consist
, Normal
, NULL
, SFO
, Specific
, TRUE
));
704 ShellStatus
= SHELL_SUCCESS
;
705 for (TypeWalker
= TypeString
; TypeWalker
!= NULL
&& *TypeWalker
!= CHAR_NULL
;) {
706 Comma
= StrStr(TypeWalker
, L
",");
708 if (ShellStatus
== SHELL_SUCCESS
) {
709 ShellStatus
= PerformMappingDisplay(Verbose
, Consist
, Normal
, TypeWalker
, SFO
, Specific
, (BOOLEAN
)(TypeWalker
== TypeString
));
711 PerformMappingDisplay(Verbose
, Consist
, Normal
, TypeWalker
, SFO
, Specific
, (BOOLEAN
)(TypeWalker
== TypeString
));
716 if (ShellStatus
== SHELL_SUCCESS
) {
717 ShellStatus
= PerformMappingDisplay(Verbose
, Consist
, Normal
, TypeWalker
, SFO
, Specific
, (BOOLEAN
)(TypeWalker
== TypeString
));
719 PerformMappingDisplay(Verbose
, Consist
, Normal
, TypeWalker
, SFO
, Specific
, (BOOLEAN
)(TypeWalker
== TypeString
));
722 TypeWalker
= Comma
+ 1;
726 return (ShellStatus
);
730 Delete a specific map.
732 @param[in] Specific The pointer to the name of the map to delete.
734 @retval EFI_INVALID_PARAMETER Specific was NULL.
735 @retval EFI_SUCCESS The operation was successful.
736 @retval EFI_NOT_FOUND Specific could not be found.
740 PerformMappingDelete(
741 IN CONST CHAR16
*Specific
745 EFI_HANDLE
*HandleBuffer
;
750 if (Specific
== NULL
) {
751 return (EFI_INVALID_PARAMETER
);
759 // Look up all SimpleFileSystems in the platform
761 Status
= gBS
->LocateHandle(
763 &gEfiDevicePathProtocolGuid
,
767 if (Status
== EFI_BUFFER_TOO_SMALL
) {
768 HandleBuffer
= AllocateZeroPool(BufferSize
);
769 if (HandleBuffer
== NULL
) {
770 return (EFI_OUT_OF_RESOURCES
);
772 Status
= gBS
->LocateHandle(
774 &gEfiDevicePathProtocolGuid
,
779 if (EFI_ERROR(Status
)) {
780 SHELL_FREE_NON_NULL(HandleBuffer
);
784 if (HandleBuffer
!= NULL
) {
786 // Get the map name(s) for each one.
789 ; LoopVar
< BufferSize
/ sizeof(EFI_HANDLE
)
792 if (PerformSingleMappingDelete(Specific
,HandleBuffer
[LoopVar
]) == SHELL_SUCCESS
) {
798 // Look up all BlockIo in the platform
800 Status
= gBS
->LocateHandle(
802 &gEfiBlockIoProtocolGuid
,
806 if (Status
== EFI_BUFFER_TOO_SMALL
) {
807 FreePool(HandleBuffer
);
808 HandleBuffer
= AllocateZeroPool(BufferSize
);
809 if (HandleBuffer
== NULL
) {
810 return (EFI_OUT_OF_RESOURCES
);
812 Status
= gBS
->LocateHandle(
814 &gEfiBlockIoProtocolGuid
,
819 if (EFI_ERROR(Status
)) {
820 SHELL_FREE_NON_NULL(HandleBuffer
);
824 if (HandleBuffer
!= NULL
) {
826 // Get the map name(s) for each one.
829 ; LoopVar
< BufferSize
/ sizeof(EFI_HANDLE
)
833 // Skip any that were already done...
835 if (gBS
->OpenProtocol(
836 HandleBuffer
[LoopVar
],
837 &gEfiDevicePathProtocolGuid
,
841 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) == EFI_SUCCESS
) {
844 if (PerformSingleMappingDelete(Specific
,HandleBuffer
[LoopVar
]) == SHELL_SUCCESS
) {
849 SHELL_FREE_NON_NULL(HandleBuffer
);
851 return (EFI_NOT_FOUND
);
853 return (EFI_SUCCESS
);
857 function to add a mapping from mapping.
859 This function will get the device path associated with the mapping and call SetMap.
861 @param[in] Map The Map to add a mapping for
862 @param[in] SName The name of the new mapping
864 @retval SHELL_SUCCESS the mapping was added
865 @retval SHELL_INVALID_PARAMETER the device path for Map could not be retrieved.
866 @return Shell version of a return value from EfiShellProtocol->SetMap
871 AddMappingFromMapping(
872 IN CONST CHAR16
*Map
,
873 IN CONST CHAR16
*SName
876 CONST EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
880 NewSName
= AllocateZeroPool(StrSize(SName
) + sizeof(CHAR16
));
881 if (NewSName
== NULL
) {
882 return (SHELL_OUT_OF_RESOURCES
);
884 StrCpy(NewSName
, SName
);
885 if (NewSName
[StrLen(NewSName
)-1] != L
':') {
886 StrCat(NewSName
, L
":");
889 if (!IsNumberLetterOnly(NewSName
, StrLen(NewSName
)-1)) {
891 return (SHELL_INVALID_PARAMETER
);
894 DevPath
= gEfiShellProtocol
->GetDevicePathFromMap(Map
);
895 if (DevPath
== NULL
) {
897 return (SHELL_INVALID_PARAMETER
);
900 Status
= gEfiShellProtocol
->SetMap(DevPath
, NewSName
);
902 if (EFI_ERROR(Status
)) {
903 return (SHELL_DEVICE_ERROR
);
905 return (SHELL_SUCCESS
);
909 function to add a mapping from an EFI_HANDLE.
911 This function will get the device path associated with the Handle and call SetMap.
913 @param[in] Handle The handle to add a mapping for
914 @param[in] SName The name of the new mapping
916 @retval SHELL_SUCCESS the mapping was added
917 @retval SHELL_INVALID_PARAMETER SName was not valid for a map name.
918 @return Shell version of a return value from either
919 gBS->OpenProtocol or EfiShellProtocol->SetMap
924 AddMappingFromHandle(
925 IN CONST EFI_HANDLE Handle
,
926 IN CONST CHAR16
*SName
929 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
933 NewSName
= AllocateZeroPool(StrSize(SName
) + sizeof(CHAR16
));
934 if (NewSName
== NULL
) {
935 return (SHELL_OUT_OF_RESOURCES
);
937 StrCpy(NewSName
, SName
);
938 if (NewSName
[StrLen(NewSName
)-1] != L
':') {
939 StrCat(NewSName
, L
":");
942 if (!IsNumberLetterOnly(NewSName
, StrLen(NewSName
)-1)) {
944 return (SHELL_INVALID_PARAMETER
);
947 Status
= gBS
->OpenProtocol(
949 &gEfiDevicePathProtocolGuid
,
953 EFI_OPEN_PROTOCOL_GET_PROTOCOL
955 if (EFI_ERROR(Status
)) {
957 return (SHELL_DEVICE_ERROR
);
959 Status
= gEfiShellProtocol
->SetMap(DevPath
, NewSName
);
961 if (EFI_ERROR(Status
)) {
962 return (SHELL_DEVICE_ERROR
);
964 return (SHELL_SUCCESS
);
967 STATIC CONST SHELL_PARAM_ITEM MapParamList
[] = {
975 {L
"-sfo", TypeValue
},
980 Function for 'map' command.
982 @param[in] ImageHandle Handle to the Image (NULL if Internal).
983 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
988 IN EFI_HANDLE ImageHandle
,
989 IN EFI_SYSTEM_TABLE
*SystemTable
994 CHAR16
*ProblemParam
;
996 CONST CHAR16
*Mapping
;
997 EFI_HANDLE MapAsHandle
;
998 SHELL_STATUS ShellStatus
;
1002 CONST CHAR16
*Param1
;
1003 CONST CHAR16
*TypeString
;
1004 UINTN TempStringLength
;
1006 ProblemParam
= NULL
;
1009 ShellStatus
= SHELL_SUCCESS
;
1013 // initialize the shell lib (we must be in non-auto-init...)
1015 Status
= ShellInitialize();
1016 ASSERT_EFI_ERROR(Status
);
1018 Status
= CommandInit();
1019 ASSERT_EFI_ERROR(Status
);
1022 // parse the command line
1024 Status
= ShellCommandLineParse (MapParamList
, &Package
, &ProblemParam
, TRUE
);
1025 if (EFI_ERROR(Status
)) {
1026 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1027 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, ProblemParam
);
1028 FreePool(ProblemParam
);
1029 ShellStatus
= SHELL_INVALID_PARAMETER
;
1037 SfoMode
= ShellCommandLineGetFlag(Package
, L
"-sfo");
1038 ConstMode
= ShellCommandLineGetFlag(Package
, L
"-c");
1039 NormlMode
= ShellCommandLineGetFlag(Package
, L
"-f");
1040 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
1042 } else if (ShellCommandLineGetRawValue(Package
, 3) != NULL
) {
1043 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
);
1044 ShellStatus
= SHELL_INVALID_PARAMETER
;
1047 // Deleting a map name...
1049 if (ShellCommandLineGetFlag(Package
, L
"-d")) {
1050 if ( ShellCommandLineGetFlag(Package
, L
"-r")
1051 || ShellCommandLineGetFlag(Package
, L
"-v")
1054 || ShellCommandLineGetFlag(Package
, L
"-u")
1055 || ShellCommandLineGetFlag(Package
, L
"-t")
1057 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CON
), gShellLevel2HiiHandle
);
1058 ShellStatus
= SHELL_INVALID_PARAMETER
;
1060 SName
= ShellCommandLineGetValue(Package
, L
"-d");
1061 if (SName
!= NULL
) {
1062 Status
= PerformMappingDelete(SName
);
1063 if (EFI_ERROR(Status
)) {
1064 if (Status
== EFI_ACCESS_DENIED
) {
1065 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_AD
), gShellLevel2HiiHandle
);
1066 ShellStatus
= SHELL_ACCESS_DENIED
;
1067 } else if (Status
== EFI_NOT_FOUND
) {
1068 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MAP_NF
), gShellLevel2HiiHandle
, SName
);
1069 ShellStatus
= SHELL_INVALID_PARAMETER
;
1071 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_UK
), gShellLevel2HiiHandle
, Status
);
1072 ShellStatus
= SHELL_UNSUPPORTED
;
1076 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
);
1077 ShellStatus
= SHELL_INVALID_PARAMETER
;
1080 } else if ( ShellCommandLineGetFlag(Package
, L
"-r")
1081 // || ShellCommandLineGetFlag(Package, L"-v")
1084 || ShellCommandLineGetFlag(Package
, L
"-u")
1085 || ShellCommandLineGetFlag(Package
, L
"-t")
1087 if ( ShellCommandLineGetFlag(Package
, L
"-r")) {
1091 Status
= ShellCommandCreateInitialMappingsAndPaths();
1092 if (EFI_ERROR(Status
)) {
1093 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_UK
), gShellLevel2HiiHandle
, Status
);
1094 ShellStatus
= SHELL_UNSUPPORTED
;
1097 if ( ShellStatus
== SHELL_SUCCESS
&& ShellCommandLineGetFlag(Package
, L
"-u")) {
1101 Status
= ShellCommandUpdateMapping ();
1102 if (EFI_ERROR(Status
)) {
1103 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_UK
), gShellLevel2HiiHandle
, Status
);
1104 ShellStatus
= SHELL_UNSUPPORTED
;
1107 if (ShellStatus
== SHELL_SUCCESS
) {
1108 Param1
= ShellCommandLineGetRawValue(Package
, 1);
1109 TypeString
= ShellCommandLineGetValue(Package
, L
"-t");
1112 &&TypeString
== NULL
1115 // now do the display...
1117 ShellStatus
= PerformMappingDisplay(
1118 ShellCommandLineGetFlag(Package
, L
"-v"),
1128 // now do the display...
1130 ShellStatus
= PerformMappingDisplay2(
1131 ShellCommandLineGetFlag(Package
, L
"-v"),
1142 // adding or displaying (there were no flags)
1144 SName
= ShellCommandLineGetRawValue(Package
, 1);
1145 Mapping
= ShellCommandLineGetRawValue(Package
, 2);
1150 // display only since no flags
1152 ShellStatus
= PerformMappingDisplay(
1153 ShellCommandLineGetFlag(Package
, L
"-v"),
1161 } else if ( SName
== NULL
1165 // Display only the one specified
1167 ShellStatus
= PerformMappingDisplay(
1173 SName
, // note the variable here...
1177 if (ShellIsHexOrDecimalNumber(Mapping
, TRUE
, FALSE
)) {
1178 MapAsHandle
= ConvertHandleIndexToHandle(ShellStrToUintn(Mapping
));
1182 if (MapAsHandle
== NULL
&& Mapping
[StrLen(Mapping
)-1] != L
':') {
1183 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, Mapping
);
1184 ShellStatus
= SHELL_INVALID_PARAMETER
;
1186 if (MapAsHandle
!= NULL
) {
1187 TempStringLength
= StrLen(SName
);
1188 if (!IsNumberLetterOnly(SName
, TempStringLength
-(SName
[TempStringLength
-1]==L
':'?1:0))) {
1189 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, SName
);
1190 ShellStatus
= SHELL_INVALID_PARAMETER
;
1192 ShellStatus
= AddMappingFromHandle(MapAsHandle
, SName
);
1195 TempStringLength
= StrLen(SName
);
1196 if (!IsNumberLetterOnly(SName
, TempStringLength
-(SName
[TempStringLength
-1]==L
':'?1:0))) {
1197 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, SName
);
1198 ShellStatus
= SHELL_INVALID_PARAMETER
;
1200 ShellStatus
= AddMappingFromMapping(Mapping
, SName
);
1203 if (ShellStatus
!= SHELL_SUCCESS
) {
1204 switch (ShellStatus
) {
1205 case SHELL_ACCESS_DENIED
:
1206 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_AD
), gShellLevel2HiiHandle
);
1208 case SHELL_INVALID_PARAMETER
:
1209 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellLevel2HiiHandle
);
1211 case SHELL_DEVICE_ERROR
:
1212 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MAP_NOF
), gShellLevel2HiiHandle
, Mapping
);
1215 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_UK
), gShellLevel2HiiHandle
, ShellStatus
|MAX_BIT
);
1219 // now do the display...
1221 ShellStatus
= PerformMappingDisplay(
1230 } // we were sucessful so do an output
1231 } // got a valid map target
1232 } // got 2 variables
1233 } // we are adding a mapping
1234 } // got valid parameters
1238 // free the command line package
1240 ShellCommandLineFreeVarList (Package
);
1242 return (ShellStatus
);