2 Main file for map shell level 2 command.
4 Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
6 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "UefiShellLevel2CommandsLib.h"
19 #include <Protocol/SimpleFileSystem.h>
20 #include <Protocol/BlockIo.h>
21 #include <Library/DevicePathLib.h>
22 #include <Library/HandleParsingLib.h>
23 #include <Library/SortLib.h>
26 Determine if a string has only numbers and letters.
28 This is useful for such things as Map names which can only be letters and numbers.
30 @param[in] String pointer to the string to analyze,
31 @param[in] Len Number of characters to analyze.
33 @retval TRUE String has only numbers and letters
34 @retval FALSE String has at least one other character.
39 IN CONST CHAR16
*String
,
44 for (Count
= 0 ; Count
< Len
&& String
!= NULL
&& *String
!= CHAR_NULL
; String
++,Count
++) {
45 if (! ((*String
>= L
'a' && *String
<= L
'z') ||
46 (*String
>= L
'A' && *String
<= L
'Z') ||
47 (*String
>= L
'0' && *String
<= L
'9'))
56 Do a search in the Target delimited list.
58 @param[in] List The list to seatch in.
59 @param[in] MetaTarget The item to search for. MetaMatching supported.
60 @param[out] FullName Optional pointer to an allocated buffer containing
62 @param[in] Meta TRUE to use MetaMatching.
63 @param[in] SkipTrailingNumbers TRUE to allow for numbers after the MetaTarget.
64 @param[in] Target The single character that delimits list
70 IN CONST CHAR16
*List
,
71 IN CONST CHAR16
*MetaTarget
,
72 OUT CHAR16
**FullName OPTIONAL
,
73 IN CONST BOOLEAN Meta
,
74 IN CONST BOOLEAN SkipTrailingNumbers
,
75 IN CONST CHAR16
*Target
80 CONST CHAR16
*ListWalker
;
84 for (ListWalker
= List
, TempList
= NULL
85 ; ListWalker
!= NULL
&& *ListWalker
!= CHAR_NULL
88 TempList
= StrnCatGrow(&TempList
, NULL
, ListWalker
, 0);
89 ASSERT(TempList
!= NULL
);
90 TempSpot
= StrStr(TempList
, Target
);
91 if (TempSpot
!= NULL
) {
92 *TempSpot
= CHAR_NULL
;
95 while (SkipTrailingNumbers
&& (ShellIsDecimalDigitCharacter(TempList
[StrLen(TempList
)-1]) || TempList
[StrLen(TempList
)-1] == L
':')) {
96 TempList
[StrLen(TempList
)-1] = CHAR_NULL
;
99 ListWalker
= StrStr(ListWalker
, Target
);
100 while(ListWalker
!= NULL
&& *ListWalker
== *Target
) {
104 Result
= gUnicodeCollation
->MetaiMatch(gUnicodeCollation
, (CHAR16
*)TempList
, (CHAR16
*)MetaTarget
);
106 Result
= (BOOLEAN
)(StrCmp(TempList
, MetaTarget
)==0);
109 if (FullName
!= NULL
) {
110 *FullName
= TempList
;
124 Determine what type of device is represented and return it's string. The
125 string is in allocated memory and must be callee freed. The HII is is listed below.
126 The actual string cannot be determined.
128 @param[in] DevicePath The device to analyze.
130 @retval STR_MAP_MEDIA_UNKNOWN The media type is unknown.
131 @retval STR_MAP_MEDIA_HARDDISK The media is a hard drive.
132 @retval STR_MAP_MEDIA_CDROM The media is a CD ROM.
133 @retval STR_MAP_MEDIA_FLOPPY The media is a floppy drive.
138 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
141 ACPI_HID_DEVICE_PATH
*Acpi
;
144 // Parse the device path:
145 // Devicepath sub type mediatype
146 // MEDIA_HANRDDRIVE_DP -> Hard Disk
147 // MEDIA_CDROM_DP -> CD Rom
148 // Acpi.HID = 0X0604 -> Floppy
150 if (NULL
== DevicePath
) {
151 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_UNKNOWN
), NULL
);
154 for (;!IsDevicePathEndType (DevicePath
) ;DevicePath
= NextDevicePathNode (DevicePath
)) {
155 if (DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) {
156 switch (DevicePathSubType (DevicePath
)) {
157 case MEDIA_HARDDRIVE_DP
:
158 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_HARDDISK
), NULL
);
160 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_CDROM
), NULL
);
162 } else if (DevicePathType (DevicePath
) == ACPI_DEVICE_PATH
) {
163 Acpi
= (ACPI_HID_DEVICE_PATH
*) DevicePath
;
164 if (EISA_ID_TO_NUM (Acpi
->HID
) == 0x0604) {
165 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_FLOPPY
), NULL
);
170 return HiiGetString(gShellLevel2HiiHandle
, STRING_TOKEN(STR_MAP_MEDIA_UNKNOWN
), NULL
);
174 Function to detemine if a handle has removable storage.
176 @param[in] DevicePath DevicePath to test.
178 @retval TRUE The handle has removable storage.
179 @retval FALSE The handle does not have removable storage.
184 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
187 if (NULL
== DevicePath
) {
191 while (!IsDevicePathEndType (DevicePath
)) {
192 if (DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) {
193 switch (DevicePathSubType (DevicePath
)) {
201 DevicePath
= NextDevicePathNode (DevicePath
);
207 Function to detemine if a something on the map list matches.
209 @param[in] MapList The pointer to the list to test.
210 @param[in] Specific The pointer to a specific name to test for.
211 @param[in] TypeString The pointer to the list of types.
212 @param[in] Normal Always show normal mappings.
213 @param[in] Consist Always show consistent mappings.
215 @retval TRUE The map should be displayed.
216 @retval FALSE The map should not be displayed.
221 IN CONST CHAR16
*MapList
,
222 IN CONST CHAR16
*Specific
,
223 IN CONST CHAR16
*TypeString
,
224 IN CONST BOOLEAN Normal
,
225 IN CONST BOOLEAN Consist
229 RETURN_STATUS Status
;
232 // specific has priority
234 if (Specific
!= NULL
) {
235 NewSpecific
= AllocateCopyPool(StrSize(Specific
) + sizeof(CHAR16
), Specific
);
236 if (NewSpecific
== NULL
){
239 if (NewSpecific
[StrLen(NewSpecific
)-1] != L
':') {
240 Status
= StrnCatS(NewSpecific
, (StrSize(Specific
) + sizeof(CHAR16
))/sizeof(CHAR16
), L
":", StrLen(L
":"));
241 if (EFI_ERROR (Status
)) {
242 FreePool(NewSpecific
);
247 if (SearchList(MapList
, NewSpecific
, NULL
, TRUE
, FALSE
, L
";")) {
248 FreePool(NewSpecific
);
251 FreePool(NewSpecific
);
255 && (SearchList(MapList
, L
"HD*", NULL
, TRUE
, TRUE
, L
";")
256 ||SearchList(MapList
, L
"CD*", NULL
, TRUE
, TRUE
, L
";")
257 ||SearchList(MapList
, L
"F*", NULL
, TRUE
, TRUE
, L
";")
258 ||SearchList(MapList
, L
"FP*", NULL
, TRUE
, TRUE
, L
";"))){
264 && (SearchList(MapList
, L
"FS", NULL
, FALSE
, TRUE
, L
";")
265 ||SearchList(MapList
, L
"BLK", NULL
, FALSE
, TRUE
, L
";"))){
269 if (TypeString
!= NULL
&& SearchList(MapList
, TypeString
, NULL
, TRUE
, TRUE
, L
";")) {
277 Display a single map line for device Handle if conditions are met.
279 @param[in] Verbose TRUE to display (extra) verbose information.
280 @param[in] Consist TRUE to display consistent mappings.
281 @param[in] Normal TRUE to display normal (not consist) mappings.
282 @param[in] TypeString pointer to string of filter types.
283 @param[in] SFO TRUE to display output in Standard Output Format.
284 @param[in] Specific pointer to string for specific map to display.
285 @param[in] Handle The handle to display from.
287 @retval EFI_SUCCESS The mapping was displayed.
291 PerformSingleMappingDisplay(
292 IN CONST BOOLEAN Verbose
,
293 IN CONST BOOLEAN Consist
,
294 IN CONST BOOLEAN Normal
,
295 IN CONST CHAR16
*TypeString
,
296 IN CONST BOOLEAN SFO
,
297 IN CONST CHAR16
*Specific OPTIONAL
,
298 IN CONST EFI_HANDLE Handle
301 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
302 EFI_DEVICE_PATH_PROTOCOL
*DevPathCopy
;
303 CONST CHAR16
*MapList
;
306 CHAR16
*DevPathString
;
311 CONST CHAR16
*TempSpot2
;
316 DevPath
= DevicePathFromHandle(Handle
);
317 DevPathCopy
= DevPath
;
318 MapList
= gEfiShellProtocol
->GetMapFromDevicePath(&DevPathCopy
);
319 if (MapList
== NULL
) {
320 return EFI_NOT_FOUND
;
323 if (!MappingListHasType(MapList
, Specific
, TypeString
, Normal
, Consist
)){
324 return EFI_NOT_FOUND
;
327 if (Normal
|| !Consist
) {
329 // need the Normal here since people can use both on command line. otherwise unused.
336 CurrentName
= StrnCatGrow(&CurrentName
, 0, MapList
, 0);
337 if (CurrentName
== NULL
) {
338 return (EFI_OUT_OF_RESOURCES
);
342 // Chop off the other names that become "Alias(s)"
343 // leaving just the normal name
345 TempSpot
= StrStr(CurrentName
, L
";");
346 if (TempSpot
!= NULL
) {
347 *TempSpot
= CHAR_NULL
;
353 // Skip the first name. This is the standard name.
355 TempSpot
= StrStr(MapList
, L
";");
356 if (TempSpot
!= NULL
) {
359 SearchList(TempSpot
, L
"HD*", &CurrentName
, TRUE
, FALSE
, L
";");
360 if (CurrentName
== NULL
) {
361 SearchList(TempSpot
, L
"CD*", &CurrentName
, TRUE
, FALSE
, L
";");
363 if (CurrentName
== NULL
) {
364 SearchList(TempSpot
, L
"FP*", &CurrentName
, TRUE
, FALSE
, L
";");
366 if (CurrentName
== NULL
) {
367 SearchList(TempSpot
, L
"F*", &CurrentName
, TRUE
, FALSE
, L
";");
369 if (CurrentName
== NULL
) {
371 // We didnt find anything, so just the first one in the list...
373 CurrentName
= StrnCatGrow(&CurrentName
, 0, MapList
, 0);
374 if (CurrentName
== NULL
) {
375 return (EFI_OUT_OF_RESOURCES
);
377 TempSpot
= StrStr(CurrentName
, L
";");
378 if (TempSpot
!= NULL
) {
379 *TempSpot
= CHAR_NULL
;
382 Alias
= StrnCatGrow(&Alias
, 0, MapList
, 0);
384 return EFI_OUT_OF_RESOURCES
;
386 TempSpot
= StrStr(Alias
, CurrentName
);
387 if (TempSpot
!= NULL
) {
388 TempSpot2
= StrStr(TempSpot
, L
";");
389 if (TempSpot2
!= NULL
) {
390 TempSpot2
++; // Move past ";" from CurrentName
391 CopyMem(TempSpot
, TempSpot2
, StrSize(TempSpot2
));
393 *TempSpot
= CHAR_NULL
;
396 if (Alias
[StrLen(Alias
)-1] == L
';') {
397 Alias
[StrLen(Alias
)-1] = CHAR_NULL
;
401 DevPathString
= ConvertDevicePathToText(DevPath
, TRUE
, FALSE
);
402 TempLen
= StrLen(CurrentName
);
408 STRING_TOKEN (STR_MAP_ENTRY
),
409 gShellLevel2HiiHandle
,
411 Alias
!=NULL
?Alias
:(TempLen
< StrLen(MapList
)?MapList
+ TempLen
+1:L
""),
416 // also print handle, media type, removable (y/n), and current directory
418 MediaType
= GetDeviceMediaType(DevPath
);
419 if ((TypeString
!= NULL
&&MediaType
!= NULL
&& StrStr(TypeString
, MediaType
) != NULL
) || TypeString
== NULL
) {
420 Removable
= IsRemoveableDevice(DevPath
);
421 TempSpot2
= ShellGetCurrentDir(CurrentName
);
426 STRING_TOKEN (STR_MAP_ENTRY_VERBOSE
),
427 gShellLevel2HiiHandle
,
428 ConvertHandleToHandleIndex(Handle
),
430 Removable
?L
"Yes":L
"No",
434 SHELL_FREE_NON_NULL(MediaType
);
441 STRING_TOKEN (STR_MAP_SFO_MAPPINGS
),
442 gShellLevel2HiiHandle
,
445 Consist
?L
"":(TempLen
< StrLen(MapList
)?MapList
+ TempLen
+1:L
"")
448 SHELL_FREE_NON_NULL(DevPathString
);
449 SHELL_FREE_NON_NULL(CurrentName
);
450 SHELL_FREE_NON_NULL(Alias
);
455 Delete Specific from the list of maps for device Handle.
457 @param[in] Specific The name to delete.
458 @param[in] Handle The device to look on.
460 @retval EFI_SUCCESS The delete was successful.
461 @retval EFI_NOT_FOUND Name was not a map on Handle.
465 PerformSingleMappingDelete(
466 IN CONST CHAR16
*Specific
,
467 IN CONST EFI_HANDLE Handle
470 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
471 EFI_DEVICE_PATH_PROTOCOL
*DevPathCopy
;
472 CONST CHAR16
*MapList
;
475 DevPath
= DevicePathFromHandle(Handle
);
476 DevPathCopy
= DevPath
;
477 MapList
= gEfiShellProtocol
->GetMapFromDevicePath(&DevPathCopy
);
480 if (MapList
== NULL
) {
481 return (EFI_NOT_FOUND
);
484 // if there is a specific and its not on the list...
486 if (!SearchList(MapList
, Specific
, &CurrentName
, TRUE
, FALSE
, L
";")) {
487 return (EFI_NOT_FOUND
);
489 return (gEfiShellProtocol
->SetMap(NULL
, CurrentName
));
492 CONST CHAR16 Cd
[] = L
"cd*";
493 CONST CHAR16 Hd
[] = L
"hd*";
494 CONST CHAR16 Fp
[] = L
"fp*";
495 CONST CHAR16 AnyF
[] = L
"F*";
497 Function to display mapping information to the user.
499 If Specific is specified then Consist and Normal will be ignored since information will
500 be printed for the specific item only.
502 @param[in] Verbose TRUE to display (extra) verbose information.
503 @param[in] Consist TRUE to display consistent mappings.
504 @param[in] Normal TRUE to display normal (not consist) mappings.
505 @param[in] TypeString Pointer to string of filter types.
506 @param[in] SFO TRUE to display output in Standard Output Format.
507 @param[in] Specific Pointer to string for specific map to display.
508 @param[in] Header TRUE to print the header block.
510 @retval SHELL_SUCCESS The display was printed.
511 @retval SHELL_INVALID_PARAMETER One of Consist or Normal must be TRUE if no Specific.
516 PerformMappingDisplay(
517 IN CONST BOOLEAN Verbose
,
518 IN CONST BOOLEAN Consist
,
519 IN CONST BOOLEAN Normal
,
520 IN CONST CHAR16
*TypeString
,
521 IN CONST BOOLEAN SFO
,
522 IN CONST CHAR16
*Specific OPTIONAL
,
523 IN CONST BOOLEAN Header
527 EFI_HANDLE
*HandleBuffer
;
533 if (!Consist
&& !Normal
&& Specific
== NULL
&& TypeString
== NULL
) {
534 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
, L
"map");
535 return (SHELL_INVALID_PARAMETER
);
538 if (TypeString
!= NULL
) {
540 if (StrnCmp(TypeString
, Test
, StrLen(Test
)-1) != 0) {
542 if (StrnCmp(TypeString
, Test
, StrLen(Test
)-1) != 0) {
544 if (StrnCmp(TypeString
, Test
, StrLen(Test
)-1) != 0) {
545 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellLevel2HiiHandle
, L
"map", TypeString
);
546 return (SHELL_INVALID_PARAMETER
);
548 } else if (Test
== NULL
) {
549 Test
= (CHAR16
*)AnyF
;
561 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MAP_HEADER
), gShellLevel2HiiHandle
);
563 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_SFO_HEADER
), gShellLevel2HiiHandle
, L
"map");
571 // Look up all SimpleFileSystems in the platform
573 Status
= gBS
->LocateHandle(
575 &gEfiSimpleFileSystemProtocolGuid
,
579 if (Status
== EFI_BUFFER_TOO_SMALL
) {
580 HandleBuffer
= AllocateZeroPool(BufferSize
);
581 if (HandleBuffer
== NULL
) {
582 return (SHELL_OUT_OF_RESOURCES
);
584 Status
= gBS
->LocateHandle(
586 &gEfiSimpleFileSystemProtocolGuid
,
593 // Get the map name(s) for each one.
595 for ( LoopVar
= 0, Found
= FALSE
596 ; LoopVar
< (BufferSize
/ sizeof(EFI_HANDLE
)) && HandleBuffer
!= NULL
599 Status
= PerformSingleMappingDisplay(
606 HandleBuffer
[LoopVar
]);
607 if (!EFI_ERROR(Status
)) {
613 // Look up all BlockIo in the platform
615 Status
= gBS
->LocateHandle(
617 &gEfiBlockIoProtocolGuid
,
621 if (Status
== EFI_BUFFER_TOO_SMALL
) {
622 SHELL_FREE_NON_NULL(HandleBuffer
);
623 HandleBuffer
= AllocateZeroPool(BufferSize
);
624 if (HandleBuffer
== NULL
) {
625 return (SHELL_OUT_OF_RESOURCES
);
627 Status
= gBS
->LocateHandle(
629 &gEfiBlockIoProtocolGuid
,
634 if (!EFI_ERROR(Status
) && HandleBuffer
!= NULL
) {
636 // Get the map name(s) for each one.
639 ; LoopVar
< BufferSize
/ sizeof(EFI_HANDLE
)
643 // Skip any that were already done...
645 if (gBS
->OpenProtocol(
646 HandleBuffer
[LoopVar
],
647 &gEfiSimpleFileSystemProtocolGuid
,
651 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) == EFI_SUCCESS
) {
654 Status
= PerformSingleMappingDisplay(
661 HandleBuffer
[LoopVar
]);
662 if (!EFI_ERROR(Status
)) {
666 FreePool(HandleBuffer
);
669 if (Specific
!= NULL
) {
670 ShellPrintHiiEx(gST
->ConOut
->Mode
->CursorColumn
, gST
->ConOut
->Mode
->CursorRow
-1, NULL
, STRING_TOKEN (STR_MAP_NF
), gShellLevel2HiiHandle
, L
"map", Specific
);
672 ShellPrintHiiEx(gST
->ConOut
->Mode
->CursorColumn
, gST
->ConOut
->Mode
->CursorRow
-1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"map");
675 return (SHELL_SUCCESS
);
679 Perform a mapping display and parse for multiple types in the TypeString.
681 @param[in] Verbose TRUE to use verbose output.
682 @param[in] Consist TRUE to display consistent names.
683 @param[in] Normal TRUE to display normal names.
684 @param[in] TypeString An optional comma-delimited list of types.
685 @param[in] SFO TRUE to display in SFO format. See Spec.
686 @param[in] Specific An optional specific map name to display alone.
688 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
689 @retval SHELL_SUCCESS The display was successful.
690 @sa PerformMappingDisplay
694 PerformMappingDisplay2(
695 IN CONST BOOLEAN Verbose
,
696 IN CONST BOOLEAN Consist
,
697 IN CONST BOOLEAN Normal
,
698 IN CONST CHAR16
*TypeString
,
699 IN CONST BOOLEAN SFO
,
700 IN CONST CHAR16
*Specific OPTIONAL
703 CONST CHAR16
*TypeWalker
;
704 SHELL_STATUS ShellStatus
;
708 if (TypeString
== NULL
) {
709 return (PerformMappingDisplay(Verbose
, Consist
, Normal
, NULL
, SFO
, Specific
, TRUE
));
711 ShellStatus
= SHELL_SUCCESS
;
712 for (TypeWalker
= TypeString
; TypeWalker
!= NULL
&& *TypeWalker
!= CHAR_NULL
;) {
713 Comma
= StrStr(TypeWalker
, L
",");
715 if (ShellStatus
== SHELL_SUCCESS
) {
716 ShellStatus
= PerformMappingDisplay(Verbose
, Consist
, Normal
, TypeWalker
, SFO
, Specific
, (BOOLEAN
)(TypeWalker
== TypeString
));
718 PerformMappingDisplay(Verbose
, Consist
, Normal
, TypeWalker
, SFO
, Specific
, (BOOLEAN
)(TypeWalker
== TypeString
));
723 if (ShellStatus
== SHELL_SUCCESS
) {
724 ShellStatus
= PerformMappingDisplay(Verbose
, Consist
, Normal
, TypeWalker
, SFO
, Specific
, (BOOLEAN
)(TypeWalker
== TypeString
));
726 PerformMappingDisplay(Verbose
, Consist
, Normal
, TypeWalker
, SFO
, Specific
, (BOOLEAN
)(TypeWalker
== TypeString
));
729 TypeWalker
= Comma
+ 1;
733 return (ShellStatus
);
737 Delete a specific map.
739 @param[in] Specific The pointer to the name of the map to delete.
741 @retval EFI_INVALID_PARAMETER Specific was NULL.
742 @retval EFI_SUCCESS The operation was successful.
743 @retval EFI_NOT_FOUND Specific could not be found.
747 PerformMappingDelete(
748 IN CONST CHAR16
*Specific
752 EFI_HANDLE
*HandleBuffer
;
757 if (Specific
== NULL
) {
758 return (EFI_INVALID_PARAMETER
);
766 // Look up all SimpleFileSystems in the platform
768 Status
= gBS
->LocateHandle(
770 &gEfiDevicePathProtocolGuid
,
774 if (Status
== EFI_BUFFER_TOO_SMALL
) {
775 HandleBuffer
= AllocateZeroPool(BufferSize
);
776 if (HandleBuffer
== NULL
) {
777 return (EFI_OUT_OF_RESOURCES
);
779 Status
= gBS
->LocateHandle(
781 &gEfiDevicePathProtocolGuid
,
786 if (EFI_ERROR(Status
)) {
787 SHELL_FREE_NON_NULL(HandleBuffer
);
791 if (HandleBuffer
!= NULL
) {
793 // Get the map name(s) for each one.
796 ; LoopVar
< BufferSize
/ sizeof(EFI_HANDLE
)
799 if (PerformSingleMappingDelete(Specific
,HandleBuffer
[LoopVar
]) == SHELL_SUCCESS
) {
805 // Look up all BlockIo in the platform
807 Status
= gBS
->LocateHandle(
809 &gEfiBlockIoProtocolGuid
,
813 if (Status
== EFI_BUFFER_TOO_SMALL
) {
814 FreePool(HandleBuffer
);
815 HandleBuffer
= AllocateZeroPool(BufferSize
);
816 if (HandleBuffer
== NULL
) {
817 return (EFI_OUT_OF_RESOURCES
);
819 Status
= gBS
->LocateHandle(
821 &gEfiBlockIoProtocolGuid
,
826 if (EFI_ERROR(Status
)) {
827 SHELL_FREE_NON_NULL(HandleBuffer
);
831 if (HandleBuffer
!= NULL
) {
833 // Get the map name(s) for each one.
836 ; LoopVar
< BufferSize
/ sizeof(EFI_HANDLE
)
840 // Skip any that were already done...
842 if (gBS
->OpenProtocol(
843 HandleBuffer
[LoopVar
],
844 &gEfiDevicePathProtocolGuid
,
848 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) == EFI_SUCCESS
) {
851 if (PerformSingleMappingDelete(Specific
,HandleBuffer
[LoopVar
]) == SHELL_SUCCESS
) {
856 SHELL_FREE_NON_NULL(HandleBuffer
);
858 return (EFI_NOT_FOUND
);
860 return (EFI_SUCCESS
);
864 function to add a mapping from mapping.
866 This function will get the device path associated with the mapping and call SetMap.
868 @param[in] Map The Map to add a mapping for
869 @param[in] SName The name of the new mapping
871 @retval SHELL_SUCCESS the mapping was added
872 @retval SHELL_INVALID_PARAMETER the device path for Map could not be retrieved.
873 @return Shell version of a return value from EfiShellProtocol->SetMap
878 AddMappingFromMapping(
879 IN CONST CHAR16
*Map
,
880 IN CONST CHAR16
*SName
883 CONST EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
886 RETURN_STATUS StrRetStatus
;
888 NewSName
= AllocateCopyPool(StrSize(SName
) + sizeof(CHAR16
), SName
);
889 if (NewSName
== NULL
) {
890 return (SHELL_OUT_OF_RESOURCES
);
892 if (NewSName
[StrLen(NewSName
)-1] != L
':') {
893 StrRetStatus
= StrnCatS(NewSName
, (StrSize(SName
) + sizeof(CHAR16
))/sizeof(CHAR16
), L
":", StrLen(L
":"));
894 if (EFI_ERROR(StrRetStatus
)) {
896 return ((SHELL_STATUS
) (StrRetStatus
& (~MAX_BIT
)));
900 if (!IsNumberLetterOnly(NewSName
, StrLen(NewSName
)-1)) {
902 return (SHELL_INVALID_PARAMETER
);
905 DevPath
= gEfiShellProtocol
->GetDevicePathFromMap(Map
);
906 if (DevPath
== NULL
) {
908 return (SHELL_INVALID_PARAMETER
);
911 Status
= gEfiShellProtocol
->SetMap(DevPath
, NewSName
);
913 if (EFI_ERROR(Status
)) {
914 return (SHELL_DEVICE_ERROR
);
916 return (SHELL_SUCCESS
);
920 function to add a mapping from an EFI_HANDLE.
922 This function will get the device path associated with the Handle and call SetMap.
924 @param[in] Handle The handle to add a mapping for
925 @param[in] SName The name of the new mapping
927 @retval SHELL_SUCCESS the mapping was added
928 @retval SHELL_INVALID_PARAMETER SName was not valid for a map name.
929 @return Shell version of a return value from either
930 gBS->OpenProtocol or EfiShellProtocol->SetMap
935 AddMappingFromHandle(
936 IN CONST EFI_HANDLE Handle
,
937 IN CONST CHAR16
*SName
940 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
943 RETURN_STATUS StrRetStatus
;
945 NewSName
= AllocateCopyPool(StrSize(SName
) + sizeof(CHAR16
), SName
);
946 if (NewSName
== NULL
) {
947 return (SHELL_OUT_OF_RESOURCES
);
949 if (NewSName
[StrLen(NewSName
)-1] != L
':') {
950 StrRetStatus
= StrnCatS(NewSName
, (StrSize(SName
) + sizeof(CHAR16
))/sizeof(CHAR16
), L
":", StrLen(L
":"));
951 if (EFI_ERROR(StrRetStatus
)) {
953 return ((SHELL_STATUS
) (StrRetStatus
& (~MAX_BIT
)));
957 if (!IsNumberLetterOnly(NewSName
, StrLen(NewSName
)-1)) {
959 return (SHELL_INVALID_PARAMETER
);
962 Status
= gBS
->OpenProtocol(
964 &gEfiDevicePathProtocolGuid
,
968 EFI_OPEN_PROTOCOL_GET_PROTOCOL
970 if (EFI_ERROR(Status
)) {
972 return (SHELL_DEVICE_ERROR
);
974 Status
= gEfiShellProtocol
->SetMap(DevPath
, NewSName
);
976 if (EFI_ERROR(Status
)) {
977 return (SHELL_DEVICE_ERROR
);
979 return (SHELL_SUCCESS
);
982 STATIC CONST SHELL_PARAM_ITEM MapParamList
[] = {
990 {L
"-sfo", TypeValue
},
995 Function for 'map' command.
997 @param[in] ImageHandle Handle to the Image (NULL if Internal).
998 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1002 ShellCommandRunMap (
1003 IN EFI_HANDLE ImageHandle
,
1004 IN EFI_SYSTEM_TABLE
*SystemTable
1008 LIST_ENTRY
*Package
;
1009 CHAR16
*ProblemParam
;
1010 CONST CHAR16
*SName
;
1011 CONST CHAR16
*Mapping
;
1012 EFI_HANDLE MapAsHandle
;
1013 SHELL_STATUS ShellStatus
;
1017 CONST CHAR16
*Param1
;
1018 CONST CHAR16
*TypeString
;
1019 UINTN TempStringLength
;
1021 ProblemParam
= NULL
;
1024 ShellStatus
= SHELL_SUCCESS
;
1028 // initialize the shell lib (we must be in non-auto-init...)
1030 Status
= ShellInitialize();
1031 ASSERT_EFI_ERROR(Status
);
1033 Status
= CommandInit();
1034 ASSERT_EFI_ERROR(Status
);
1037 // parse the command line
1039 Status
= ShellCommandLineParse (MapParamList
, &Package
, &ProblemParam
, TRUE
);
1040 if (EFI_ERROR(Status
)) {
1041 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1042 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"map", ProblemParam
);
1043 FreePool(ProblemParam
);
1044 ShellStatus
= SHELL_INVALID_PARAMETER
;
1052 SfoMode
= ShellCommandLineGetFlag(Package
, L
"-sfo");
1053 ConstMode
= ShellCommandLineGetFlag(Package
, L
"-c");
1054 NormlMode
= ShellCommandLineGetFlag(Package
, L
"-f");
1055 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
1057 } else if (ShellCommandLineGetRawValue(Package
, 3) != NULL
) {
1058 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"map");
1059 ShellStatus
= SHELL_INVALID_PARAMETER
;
1062 // Deleting a map name...
1064 if (ShellCommandLineGetFlag(Package
, L
"-d")) {
1065 if ( ShellCommandLineGetFlag(Package
, L
"-r")
1066 || ShellCommandLineGetFlag(Package
, L
"-v")
1069 || ShellCommandLineGetFlag(Package
, L
"-u")
1070 || ShellCommandLineGetFlag(Package
, L
"-t")
1072 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_CON
), gShellLevel2HiiHandle
, L
"map");
1073 ShellStatus
= SHELL_INVALID_PARAMETER
;
1075 SName
= ShellCommandLineGetValue(Package
, L
"-d");
1076 if (SName
!= NULL
) {
1077 Status
= PerformMappingDelete(SName
);
1078 if (EFI_ERROR(Status
)) {
1079 if (Status
== EFI_ACCESS_DENIED
) {
1080 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_AD
), gShellLevel2HiiHandle
, L
"map");
1081 ShellStatus
= SHELL_ACCESS_DENIED
;
1082 } else if (Status
== EFI_NOT_FOUND
) {
1083 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MAP_NF
), gShellLevel2HiiHandle
, L
"map", SName
);
1084 ShellStatus
= SHELL_INVALID_PARAMETER
;
1086 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_UK
), gShellLevel2HiiHandle
, L
"map", Status
);
1087 ShellStatus
= SHELL_UNSUPPORTED
;
1091 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
, L
"map");
1092 ShellStatus
= SHELL_INVALID_PARAMETER
;
1095 } else if ( ShellCommandLineGetFlag(Package
, L
"-r")
1096 // || ShellCommandLineGetFlag(Package, L"-v")
1099 || ShellCommandLineGetFlag(Package
, L
"-u")
1100 || ShellCommandLineGetFlag(Package
, L
"-t")
1102 if ( ShellCommandLineGetFlag(Package
, L
"-r")) {
1106 Status
= ShellCommandCreateInitialMappingsAndPaths();
1107 if (EFI_ERROR(Status
)) {
1108 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_UK
), gShellLevel2HiiHandle
, L
"map", Status
);
1109 ShellStatus
= SHELL_UNSUPPORTED
;
1112 if ( ShellStatus
== SHELL_SUCCESS
&& ShellCommandLineGetFlag(Package
, L
"-u")) {
1116 Status
= ShellCommandUpdateMapping ();
1117 if (EFI_ERROR(Status
)) {
1118 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_UK
), gShellLevel2HiiHandle
, L
"map", Status
);
1119 ShellStatus
= SHELL_UNSUPPORTED
;
1122 if (ShellStatus
== SHELL_SUCCESS
) {
1123 Param1
= ShellCommandLineGetRawValue(Package
, 1);
1124 TypeString
= ShellCommandLineGetValue(Package
, L
"-t");
1127 &&TypeString
== NULL
1130 // now do the display...
1132 ShellStatus
= PerformMappingDisplay(
1133 ShellCommandLineGetFlag(Package
, L
"-v"),
1143 // now do the display...
1145 ShellStatus
= PerformMappingDisplay2(
1146 ShellCommandLineGetFlag(Package
, L
"-v"),
1157 // adding or displaying (there were no flags)
1159 SName
= ShellCommandLineGetRawValue(Package
, 1);
1160 Mapping
= ShellCommandLineGetRawValue(Package
, 2);
1165 // display only since no flags
1167 ShellStatus
= PerformMappingDisplay(
1168 ShellCommandLineGetFlag(Package
, L
"-v"),
1176 } else if ( SName
== NULL
1180 // Display only the one specified
1182 ShellStatus
= PerformMappingDisplay(
1188 SName
, // note the variable here...
1192 if (ShellIsHexOrDecimalNumber(Mapping
, TRUE
, FALSE
)) {
1193 MapAsHandle
= ConvertHandleIndexToHandle(ShellStrToUintn(Mapping
));
1197 if (MapAsHandle
== NULL
&& Mapping
[StrLen(Mapping
)-1] != L
':') {
1198 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellLevel2HiiHandle
, L
"map", Mapping
);
1199 ShellStatus
= SHELL_INVALID_PARAMETER
;
1201 TempStringLength
= StrLen(SName
);
1202 if (!IsNumberLetterOnly(SName
, TempStringLength
-(SName
[TempStringLength
-1]==L
':'?1:0))) {
1203 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellLevel2HiiHandle
, L
"map", SName
);
1204 ShellStatus
= SHELL_INVALID_PARAMETER
;
1207 if (ShellStatus
== SHELL_SUCCESS
) {
1208 if (MapAsHandle
!= NULL
) {
1209 ShellStatus
= AddMappingFromHandle(MapAsHandle
, SName
);
1211 ShellStatus
= AddMappingFromMapping(Mapping
, SName
);
1214 if (ShellStatus
!= SHELL_SUCCESS
) {
1215 switch (ShellStatus
) {
1216 case SHELL_ACCESS_DENIED
:
1217 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_AD
), gShellLevel2HiiHandle
, L
"map");
1219 case SHELL_INVALID_PARAMETER
:
1220 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellLevel2HiiHandle
, L
"map", Mapping
);
1222 case SHELL_DEVICE_ERROR
:
1223 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_MAP_NOF
), gShellLevel2HiiHandle
, L
"map", Mapping
);
1226 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_UK
), gShellLevel2HiiHandle
, L
"map", ShellStatus
|MAX_BIT
);
1230 // now do the display...
1232 ShellStatus
= PerformMappingDisplay(
1241 } // we were sucessful so do an output
1243 } // got a valid map target
1244 } // got 2 variables
1245 } // we are adding a mapping
1246 } // got valid parameters
1250 // free the command line package
1252 ShellCommandLineFreeVarList (Package
);
1254 return (ShellStatus
);