| /** @file | |
| Main file for map shell level 2 command. | |
| Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> | |
| (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> | |
| (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include "UefiShellLevel2CommandsLib.h" | |
| #include <Protocol/SimpleFileSystem.h> | |
| #include <Protocol/BlockIo.h> | |
| #include <Library/DevicePathLib.h> | |
| #include <Library/HandleParsingLib.h> | |
| #include <Library/SortLib.h> | |
| /** | |
| Determine if a string has only numbers and letters. | |
| This is useful for such things as Map names which can only be letters and numbers. | |
| @param[in] String pointer to the string to analyze, | |
| @param[in] Len Number of characters to analyze. | |
| @retval TRUE String has only numbers and letters | |
| @retval FALSE String has at least one other character. | |
| **/ | |
| BOOLEAN | |
| IsNumberLetterOnly ( | |
| IN CONST CHAR16 *String, | |
| IN CONST UINTN Len | |
| ) | |
| { | |
| UINTN Count; | |
| for (Count = 0; Count < Len && String != NULL && *String != CHAR_NULL; String++, Count++) { | |
| if (!(((*String >= L'a') && (*String <= L'z')) || | |
| ((*String >= L'A') && (*String <= L'Z')) || | |
| ((*String >= L'0') && (*String <= L'9'))) | |
| ) | |
| { | |
| return (FALSE); | |
| } | |
| } | |
| return (TRUE); | |
| } | |
| /** | |
| Do a search in the Target delimited list. | |
| @param[in] List The list to seatch in. | |
| @param[in] MetaTarget The item to search for. MetaMatching supported. | |
| @param[out] FullName Optional pointer to an allocated buffer containing | |
| the match. | |
| @param[in] Meta TRUE to use MetaMatching. | |
| @param[in] SkipTrailingNumbers TRUE to allow for numbers after the MetaTarget. | |
| @param[in] Target The single character that delimits list | |
| items (";" normally). | |
| **/ | |
| BOOLEAN | |
| SearchList ( | |
| IN CONST CHAR16 *List, | |
| IN CONST CHAR16 *MetaTarget, | |
| OUT CHAR16 **FullName OPTIONAL, | |
| IN CONST BOOLEAN Meta, | |
| IN CONST BOOLEAN SkipTrailingNumbers, | |
| IN CONST CHAR16 *Target | |
| ) | |
| { | |
| CHAR16 *TempList; | |
| CONST CHAR16 *ListWalker; | |
| BOOLEAN Result; | |
| CHAR16 *TempSpot; | |
| for (ListWalker = List, TempList = NULL | |
| ; ListWalker != NULL && *ListWalker != CHAR_NULL | |
| ; | |
| ) | |
| { | |
| TempList = StrnCatGrow (&TempList, NULL, ListWalker, 0); | |
| ASSERT (TempList != NULL); | |
| TempSpot = StrStr (TempList, Target); | |
| if (TempSpot != NULL) { | |
| *TempSpot = CHAR_NULL; | |
| } | |
| while (SkipTrailingNumbers && (ShellIsDecimalDigitCharacter (TempList[StrLen (TempList)-1]) || TempList[StrLen (TempList)-1] == L':')) { | |
| TempList[StrLen (TempList)-1] = CHAR_NULL; | |
| } | |
| ListWalker = StrStr (ListWalker, Target); | |
| while (ListWalker != NULL && *ListWalker == *Target) { | |
| ListWalker++; | |
| } | |
| if (Meta) { | |
| Result = gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)TempList, (CHAR16 *)MetaTarget); | |
| } else { | |
| Result = (BOOLEAN)(StrCmp (TempList, MetaTarget) == 0); | |
| } | |
| if (Result) { | |
| if (FullName != NULL) { | |
| *FullName = TempList; | |
| } else { | |
| FreePool (TempList); | |
| } | |
| return (TRUE); | |
| } | |
| FreePool (TempList); | |
| TempList = NULL; | |
| } | |
| return (FALSE); | |
| } | |
| /** | |
| Determine what type of device is represented and return it's string. The | |
| string is in allocated memory and must be callee freed. The HII is is listed below. | |
| The actual string cannot be determined. | |
| @param[in] DevicePath The device to analyze. | |
| @retval STR_MAP_MEDIA_UNKNOWN The media type is unknown. | |
| @retval STR_MAP_MEDIA_HARDDISK The media is a hard drive. | |
| @retval STR_MAP_MEDIA_CDROM The media is a CD ROM. | |
| @retval STR_MAP_MEDIA_FLOPPY The media is a floppy drive. | |
| **/ | |
| CHAR16 * | |
| GetDeviceMediaType ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *DevicePath | |
| ) | |
| { | |
| ACPI_HID_DEVICE_PATH *Acpi; | |
| // | |
| // Parse the device path: | |
| // Devicepath sub type mediatype | |
| // MEDIA_HANRDDRIVE_DP -> Hard Disk | |
| // MEDIA_CDROM_DP -> CD Rom | |
| // Acpi.HID = 0X0604 -> Floppy | |
| // | |
| if (NULL == DevicePath) { | |
| return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL); | |
| } | |
| for ( ; !IsDevicePathEndType (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) { | |
| if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) { | |
| switch (DevicePathSubType (DevicePath)) { | |
| case MEDIA_HARDDRIVE_DP: | |
| return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_HARDDISK), NULL); | |
| case MEDIA_CDROM_DP: | |
| return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_CDROM), NULL); | |
| } | |
| } else if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH) { | |
| Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath; | |
| if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) { | |
| return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_FLOPPY), NULL); | |
| } | |
| } | |
| } | |
| return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL); | |
| } | |
| /** | |
| Function to detemine if a handle has removable storage. | |
| @param[in] DevicePath DevicePath to test. | |
| @retval TRUE The handle has removable storage. | |
| @retval FALSE The handle does not have removable storage. | |
| **/ | |
| BOOLEAN | |
| IsRemoveableDevice ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *DevicePath | |
| ) | |
| { | |
| if (NULL == DevicePath) { | |
| return FALSE; | |
| } | |
| while (!IsDevicePathEndType (DevicePath)) { | |
| if (DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) { | |
| switch (DevicePathSubType (DevicePath)) { | |
| case MSG_USB_DP: | |
| case MSG_SCSI_DP: | |
| return TRUE; | |
| default: | |
| return FALSE; | |
| } | |
| } | |
| DevicePath = NextDevicePathNode (DevicePath); | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| Function to detemine if a something on the map list matches. | |
| @param[in] MapList The pointer to the list to test. | |
| @param[in] Specific The pointer to a specific name to test for. | |
| @param[in] TypeString The pointer to the list of types. | |
| @param[in] Normal Always show normal mappings. | |
| @param[in] Consist Always show consistent mappings. | |
| @retval TRUE The map should be displayed. | |
| @retval FALSE The map should not be displayed. | |
| **/ | |
| BOOLEAN | |
| MappingListHasType ( | |
| IN CONST CHAR16 *MapList, | |
| IN CONST CHAR16 *Specific, | |
| IN CONST CHAR16 *TypeString, | |
| IN CONST BOOLEAN Normal, | |
| IN CONST BOOLEAN Consist | |
| ) | |
| { | |
| CHAR16 *NewSpecific; | |
| RETURN_STATUS Status; | |
| UINTN Length; | |
| // | |
| // specific has priority | |
| // | |
| if (Specific != NULL) { | |
| Length = StrLen (Specific); | |
| // | |
| // Allocate enough buffer for Specific and potential ":" | |
| // | |
| NewSpecific = AllocatePool ((Length + 2) * sizeof (CHAR16)); | |
| if (NewSpecific == NULL) { | |
| return FALSE; | |
| } | |
| StrCpyS (NewSpecific, Length + 2, Specific); | |
| if (Specific[Length - 1] != L':') { | |
| Status = StrnCatS (NewSpecific, Length + 2, L":", StrLen (L":")); | |
| if (EFI_ERROR (Status)) { | |
| FreePool (NewSpecific); | |
| return FALSE; | |
| } | |
| } | |
| if (SearchList (MapList, NewSpecific, NULL, TRUE, FALSE, L";")) { | |
| FreePool (NewSpecific); | |
| return (TRUE); | |
| } | |
| FreePool (NewSpecific); | |
| } | |
| if ( Consist | |
| && (Specific == NULL) | |
| && ( SearchList (MapList, L"HD*", NULL, TRUE, TRUE, L";") | |
| || SearchList (MapList, L"CD*", NULL, TRUE, TRUE, L";") | |
| || SearchList (MapList, L"F*", NULL, TRUE, TRUE, L";") | |
| || SearchList (MapList, L"FP*", NULL, TRUE, TRUE, L";"))) | |
| { | |
| return (TRUE); | |
| } | |
| if ( Normal | |
| && (Specific == NULL) | |
| && ( SearchList (MapList, L"FS", NULL, FALSE, TRUE, L";") | |
| || SearchList (MapList, L"BLK", NULL, FALSE, TRUE, L";"))) | |
| { | |
| return (TRUE); | |
| } | |
| if ((TypeString != NULL) && SearchList (MapList, TypeString, NULL, TRUE, TRUE, L";")) { | |
| return (TRUE); | |
| } | |
| return (FALSE); | |
| } | |
| /** | |
| Display a single map line for device Handle if conditions are met. | |
| @param[in] Verbose TRUE to display (extra) verbose information. | |
| @param[in] Consist TRUE to display consistent mappings. | |
| @param[in] Normal TRUE to display normal (not consist) mappings. | |
| @param[in] TypeString pointer to string of filter types. | |
| @param[in] SFO TRUE to display output in Standard Output Format. | |
| @param[in] Specific pointer to string for specific map to display. | |
| @param[in] Handle The handle to display from. | |
| @retval EFI_SUCCESS The mapping was displayed. | |
| **/ | |
| EFI_STATUS | |
| PerformSingleMappingDisplay ( | |
| IN CONST BOOLEAN Verbose, | |
| IN CONST BOOLEAN Consist, | |
| IN CONST BOOLEAN Normal, | |
| IN CONST CHAR16 *TypeString, | |
| IN CONST BOOLEAN SFO, | |
| IN CONST CHAR16 *Specific OPTIONAL, | |
| IN CONST EFI_HANDLE Handle | |
| ) | |
| { | |
| EFI_DEVICE_PATH_PROTOCOL *DevPath; | |
| EFI_DEVICE_PATH_PROTOCOL *DevPathCopy; | |
| CONST CHAR16 *MapList; | |
| CHAR16 *CurrentName; | |
| CHAR16 *MediaType; | |
| CHAR16 *DevPathString; | |
| CHAR16 *TempSpot; | |
| CHAR16 *Alias; | |
| UINTN TempLen; | |
| BOOLEAN Removable; | |
| CONST CHAR16 *TempSpot2; | |
| Alias = NULL; | |
| TempSpot2 = NULL; | |
| CurrentName = NULL; | |
| DevPath = DevicePathFromHandle (Handle); | |
| DevPathCopy = DevPath; | |
| MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy); | |
| if (MapList == NULL) { | |
| return EFI_NOT_FOUND; | |
| } | |
| if (!MappingListHasType (MapList, Specific, TypeString, Normal, Consist)) { | |
| return EFI_NOT_FOUND; | |
| } | |
| if (Normal || !Consist) { | |
| // | |
| // need the Normal here since people can use both on command line. otherwise unused. | |
| // | |
| // | |
| // Allocate a name | |
| // | |
| CurrentName = NULL; | |
| CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0); | |
| if (CurrentName == NULL) { | |
| return (EFI_OUT_OF_RESOURCES); | |
| } | |
| // | |
| // Chop off the other names that become "Alias(s)" | |
| // leaving just the normal name | |
| // | |
| TempSpot = StrStr (CurrentName, L";"); | |
| if (TempSpot != NULL) { | |
| *TempSpot = CHAR_NULL; | |
| } | |
| } else { | |
| CurrentName = NULL; | |
| // | |
| // Skip the first name. This is the standard name. | |
| // | |
| TempSpot = StrStr (MapList, L";"); | |
| if (TempSpot != NULL) { | |
| TempSpot++; | |
| } | |
| SearchList (TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";"); | |
| if (CurrentName == NULL) { | |
| SearchList (TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";"); | |
| } | |
| if (CurrentName == NULL) { | |
| SearchList (TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";"); | |
| } | |
| if (CurrentName == NULL) { | |
| SearchList (TempSpot, L"F*", &CurrentName, TRUE, FALSE, L";"); | |
| } | |
| if (CurrentName == NULL) { | |
| // | |
| // We didnt find anything, so just the first one in the list... | |
| // | |
| CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0); | |
| if (CurrentName == NULL) { | |
| return (EFI_OUT_OF_RESOURCES); | |
| } | |
| TempSpot = StrStr (CurrentName, L";"); | |
| if (TempSpot != NULL) { | |
| *TempSpot = CHAR_NULL; | |
| } | |
| } else { | |
| Alias = StrnCatGrow (&Alias, 0, MapList, 0); | |
| if (Alias == NULL) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| TempSpot = StrStr (Alias, CurrentName); | |
| if (TempSpot != NULL) { | |
| TempSpot2 = StrStr (TempSpot, L";"); | |
| if (TempSpot2 != NULL) { | |
| TempSpot2++; // Move past ";" from CurrentName | |
| CopyMem (TempSpot, TempSpot2, StrSize (TempSpot2)); | |
| } else { | |
| *TempSpot = CHAR_NULL; | |
| } | |
| } | |
| if (Alias[StrLen (Alias)-1] == L';') { | |
| Alias[StrLen (Alias)-1] = CHAR_NULL; | |
| } | |
| } | |
| } | |
| DevPathString = ConvertDevicePathToText (DevPath, TRUE, FALSE); | |
| TempLen = StrLen (CurrentName); | |
| if (!SFO) { | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_MAP_ENTRY), | |
| gShellLevel2HiiHandle, | |
| CurrentName, | |
| Alias != NULL ? Alias : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L""), | |
| DevPathString | |
| ); | |
| if (Verbose) { | |
| // | |
| // also print handle, media type, removable (y/n), and current directory | |
| // | |
| MediaType = GetDeviceMediaType (DevPath); | |
| if (((TypeString != NULL) && (MediaType != NULL) && (StrStr (TypeString, MediaType) != NULL)) || (TypeString == NULL)) { | |
| Removable = IsRemoveableDevice (DevPath); | |
| TempSpot2 = ShellGetCurrentDir (CurrentName); | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_MAP_ENTRY_VERBOSE), | |
| gShellLevel2HiiHandle, | |
| ConvertHandleToHandleIndex (Handle), | |
| MediaType, | |
| Removable ? L"Yes" : L"No", | |
| TempSpot2 | |
| ); | |
| } | |
| SHELL_FREE_NON_NULL (MediaType); | |
| } | |
| } else { | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_MAP_SFO_MAPPINGS), | |
| gShellLevel2HiiHandle, | |
| CurrentName, | |
| DevPathString, | |
| Consist ? L"" : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L"") | |
| ); | |
| } | |
| SHELL_FREE_NON_NULL (DevPathString); | |
| SHELL_FREE_NON_NULL (CurrentName); | |
| SHELL_FREE_NON_NULL (Alias); | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| Delete Specific from the list of maps for device Handle. | |
| @param[in] Specific The name to delete. | |
| @param[in] Handle The device to look on. | |
| @retval EFI_SUCCESS The delete was successful. | |
| @retval EFI_NOT_FOUND Name was not a map on Handle. | |
| **/ | |
| EFI_STATUS | |
| PerformSingleMappingDelete ( | |
| IN CONST CHAR16 *Specific, | |
| IN CONST EFI_HANDLE Handle | |
| ) | |
| { | |
| EFI_DEVICE_PATH_PROTOCOL *DevPath; | |
| EFI_DEVICE_PATH_PROTOCOL *DevPathCopy; | |
| CONST CHAR16 *MapList; | |
| CHAR16 *CurrentName; | |
| DevPath = DevicePathFromHandle (Handle); | |
| DevPathCopy = DevPath; | |
| MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy); | |
| CurrentName = NULL; | |
| if (MapList == NULL) { | |
| return (EFI_NOT_FOUND); | |
| } | |
| // | |
| // if there is a specific and its not on the list... | |
| // | |
| if (!SearchList (MapList, Specific, &CurrentName, TRUE, FALSE, L";")) { | |
| return (EFI_NOT_FOUND); | |
| } | |
| return (gEfiShellProtocol->SetMap (NULL, CurrentName)); | |
| } | |
| CONST CHAR16 Cd[] = L"cd*"; | |
| CONST CHAR16 Hd[] = L"hd*"; | |
| CONST CHAR16 Fp[] = L"fp*"; | |
| CONST CHAR16 AnyF[] = L"F*"; | |
| /** | |
| Function to display mapping information to the user. | |
| If Specific is specified then Consist and Normal will be ignored since information will | |
| be printed for the specific item only. | |
| @param[in] Verbose TRUE to display (extra) verbose information. | |
| @param[in] Consist TRUE to display consistent mappings. | |
| @param[in] Normal TRUE to display normal (not consist) mappings. | |
| @param[in] TypeString Pointer to string of filter types. | |
| @param[in] SFO TRUE to display output in Standard Output Format. | |
| @param[in] Specific Pointer to string for specific map to display. | |
| @param[in] Header TRUE to print the header block. | |
| @retval SHELL_SUCCESS The display was printed. | |
| @retval SHELL_INVALID_PARAMETER One of Consist or Normal must be TRUE if no Specific. | |
| **/ | |
| SHELL_STATUS | |
| PerformMappingDisplay ( | |
| IN CONST BOOLEAN Verbose, | |
| IN CONST BOOLEAN Consist, | |
| IN CONST BOOLEAN Normal, | |
| IN CONST CHAR16 *TypeString, | |
| IN CONST BOOLEAN SFO, | |
| IN CONST CHAR16 *Specific OPTIONAL, | |
| IN CONST BOOLEAN Header | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_HANDLE *HandleBuffer; | |
| UINTN BufferSize; | |
| UINTN LoopVar; | |
| CHAR16 *Test; | |
| BOOLEAN Found; | |
| if (!Consist && !Normal && (Specific == NULL) && (TypeString == NULL)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map"); | |
| return (SHELL_INVALID_PARAMETER); | |
| } | |
| if (TypeString != NULL) { | |
| Test = (CHAR16 *)Cd; | |
| if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) { | |
| Test = (CHAR16 *)Hd; | |
| if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) { | |
| Test = (CHAR16 *)Fp; | |
| if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", TypeString); | |
| return (SHELL_INVALID_PARAMETER); | |
| } | |
| } else if (Test == NULL) { | |
| Test = (CHAR16 *)AnyF; | |
| } | |
| } | |
| } else { | |
| Test = NULL; | |
| } | |
| if (Header) { | |
| // | |
| // Print the header | |
| // | |
| if (!SFO) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle); | |
| } else { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"map"); | |
| } | |
| } | |
| BufferSize = 0; | |
| HandleBuffer = NULL; | |
| // | |
| // Look up all SimpleFileSystems in the platform | |
| // | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| NULL, | |
| &BufferSize, | |
| HandleBuffer | |
| ); | |
| if (Status == EFI_BUFFER_TOO_SMALL) { | |
| HandleBuffer = AllocateZeroPool (BufferSize); | |
| if (HandleBuffer == NULL) { | |
| return (SHELL_OUT_OF_RESOURCES); | |
| } | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| NULL, | |
| &BufferSize, | |
| HandleBuffer | |
| ); | |
| } | |
| // | |
| // Get the map name(s) for each one. | |
| // | |
| for ( LoopVar = 0, Found = FALSE | |
| ; LoopVar < (BufferSize / sizeof (EFI_HANDLE)) && HandleBuffer != NULL | |
| ; LoopVar++ | |
| ) | |
| { | |
| Status = PerformSingleMappingDisplay ( | |
| Verbose, | |
| Consist, | |
| Normal, | |
| Test, | |
| SFO, | |
| Specific, | |
| HandleBuffer[LoopVar] | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| Found = TRUE; | |
| } | |
| } | |
| // | |
| // Look up all BlockIo in the platform | |
| // | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiBlockIoProtocolGuid, | |
| NULL, | |
| &BufferSize, | |
| HandleBuffer | |
| ); | |
| if (Status == EFI_BUFFER_TOO_SMALL) { | |
| SHELL_FREE_NON_NULL (HandleBuffer); | |
| HandleBuffer = AllocateZeroPool (BufferSize); | |
| if (HandleBuffer == NULL) { | |
| return (SHELL_OUT_OF_RESOURCES); | |
| } | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiBlockIoProtocolGuid, | |
| NULL, | |
| &BufferSize, | |
| HandleBuffer | |
| ); | |
| } | |
| if (!EFI_ERROR (Status) && (HandleBuffer != NULL)) { | |
| // | |
| // Get the map name(s) for each one. | |
| // | |
| for ( LoopVar = 0 | |
| ; LoopVar < BufferSize / sizeof (EFI_HANDLE) | |
| ; LoopVar++ | |
| ) | |
| { | |
| // | |
| // Skip any that were already done... | |
| // | |
| if (gBS->OpenProtocol ( | |
| HandleBuffer[LoopVar], | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| NULL, | |
| gImageHandle, | |
| NULL, | |
| EFI_OPEN_PROTOCOL_TEST_PROTOCOL | |
| ) == EFI_SUCCESS) | |
| { | |
| continue; | |
| } | |
| Status = PerformSingleMappingDisplay ( | |
| Verbose, | |
| Consist, | |
| Normal, | |
| Test, | |
| SFO, | |
| Specific, | |
| HandleBuffer[LoopVar] | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| Found = TRUE; | |
| } | |
| } | |
| FreePool (HandleBuffer); | |
| } | |
| if (!Found) { | |
| if (Specific != NULL) { | |
| ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", Specific); | |
| } else { | |
| ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"map"); | |
| } | |
| } | |
| return (SHELL_SUCCESS); | |
| } | |
| /** | |
| Perform a mapping display and parse for multiple types in the TypeString. | |
| @param[in] Verbose TRUE to use verbose output. | |
| @param[in] Consist TRUE to display consistent names. | |
| @param[in] Normal TRUE to display normal names. | |
| @param[in] TypeString An optional comma-delimited list of types. | |
| @param[in] SFO TRUE to display in SFO format. See Spec. | |
| @param[in] Specific An optional specific map name to display alone. | |
| @retval SHELL_INVALID_PARAMETER A parameter was invalid. | |
| @retval SHELL_SUCCESS The display was successful. | |
| @sa PerformMappingDisplay | |
| **/ | |
| SHELL_STATUS | |
| PerformMappingDisplay2 ( | |
| IN CONST BOOLEAN Verbose, | |
| IN CONST BOOLEAN Consist, | |
| IN CONST BOOLEAN Normal, | |
| IN CONST CHAR16 *TypeString, | |
| IN CONST BOOLEAN SFO, | |
| IN CONST CHAR16 *Specific OPTIONAL | |
| ) | |
| { | |
| CONST CHAR16 *TypeWalker; | |
| SHELL_STATUS ShellStatus; | |
| CHAR16 *Comma; | |
| if (TypeString == NULL) { | |
| return (PerformMappingDisplay (Verbose, Consist, Normal, NULL, SFO, Specific, TRUE)); | |
| } | |
| ShellStatus = SHELL_SUCCESS; | |
| for (TypeWalker = TypeString; TypeWalker != NULL && *TypeWalker != CHAR_NULL;) { | |
| Comma = StrStr (TypeWalker, L","); | |
| if (Comma == NULL) { | |
| if (ShellStatus == SHELL_SUCCESS) { | |
| ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString)); | |
| } else { | |
| PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString)); | |
| } | |
| break; | |
| } else { | |
| *Comma = CHAR_NULL; | |
| if (ShellStatus == SHELL_SUCCESS) { | |
| ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString)); | |
| } else { | |
| PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString)); | |
| } | |
| *Comma = L','; | |
| TypeWalker = Comma + 1; | |
| } | |
| } | |
| return (ShellStatus); | |
| } | |
| /** | |
| Delete a specific map. | |
| @param[in] Specific The pointer to the name of the map to delete. | |
| @retval EFI_INVALID_PARAMETER Specific was NULL. | |
| @retval EFI_SUCCESS The operation was successful. | |
| @retval EFI_NOT_FOUND Specific could not be found. | |
| **/ | |
| EFI_STATUS | |
| PerformMappingDelete ( | |
| IN CONST CHAR16 *Specific | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_HANDLE *HandleBuffer; | |
| UINTN BufferSize; | |
| UINTN LoopVar; | |
| BOOLEAN Deleted; | |
| if (Specific == NULL) { | |
| return (EFI_INVALID_PARAMETER); | |
| } | |
| BufferSize = 0; | |
| HandleBuffer = NULL; | |
| Deleted = FALSE; | |
| // | |
| // Look up all SimpleFileSystems in the platform | |
| // | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiDevicePathProtocolGuid, | |
| NULL, | |
| &BufferSize, | |
| HandleBuffer | |
| ); | |
| if (Status == EFI_BUFFER_TOO_SMALL) { | |
| HandleBuffer = AllocateZeroPool (BufferSize); | |
| if (HandleBuffer == NULL) { | |
| return (EFI_OUT_OF_RESOURCES); | |
| } | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiDevicePathProtocolGuid, | |
| NULL, | |
| &BufferSize, | |
| HandleBuffer | |
| ); | |
| } | |
| if (EFI_ERROR (Status)) { | |
| SHELL_FREE_NON_NULL (HandleBuffer); | |
| return (Status); | |
| } | |
| if (HandleBuffer != NULL) { | |
| // | |
| // Get the map name(s) for each one. | |
| // | |
| for ( LoopVar = 0 | |
| ; LoopVar < BufferSize / sizeof (EFI_HANDLE) | |
| ; LoopVar++ | |
| ) | |
| { | |
| if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) { | |
| Deleted = TRUE; | |
| } | |
| } | |
| } | |
| // | |
| // Look up all BlockIo in the platform | |
| // | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiBlockIoProtocolGuid, | |
| NULL, | |
| &BufferSize, | |
| HandleBuffer | |
| ); | |
| if (Status == EFI_BUFFER_TOO_SMALL) { | |
| FreePool (HandleBuffer); | |
| HandleBuffer = AllocateZeroPool (BufferSize); | |
| if (HandleBuffer == NULL) { | |
| return (EFI_OUT_OF_RESOURCES); | |
| } | |
| Status = gBS->LocateHandle ( | |
| ByProtocol, | |
| &gEfiBlockIoProtocolGuid, | |
| NULL, | |
| &BufferSize, | |
| HandleBuffer | |
| ); | |
| } | |
| if (EFI_ERROR (Status)) { | |
| SHELL_FREE_NON_NULL (HandleBuffer); | |
| return (Status); | |
| } | |
| if (HandleBuffer != NULL) { | |
| // | |
| // Get the map name(s) for each one. | |
| // | |
| for ( LoopVar = 0 | |
| ; LoopVar < BufferSize / sizeof (EFI_HANDLE) | |
| ; LoopVar++ | |
| ) | |
| { | |
| // | |
| // Skip any that were already done... | |
| // | |
| if (gBS->OpenProtocol ( | |
| HandleBuffer[LoopVar], | |
| &gEfiDevicePathProtocolGuid, | |
| NULL, | |
| gImageHandle, | |
| NULL, | |
| EFI_OPEN_PROTOCOL_TEST_PROTOCOL | |
| ) == EFI_SUCCESS) | |
| { | |
| continue; | |
| } | |
| if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) { | |
| Deleted = TRUE; | |
| } | |
| } | |
| } | |
| SHELL_FREE_NON_NULL (HandleBuffer); | |
| if (!Deleted) { | |
| return (EFI_NOT_FOUND); | |
| } | |
| return (EFI_SUCCESS); | |
| } | |
| /** | |
| function to add a mapping from mapping. | |
| This function will get the device path associated with the mapping and call SetMap. | |
| @param[in] Map The Map to add a mapping for | |
| @param[in] SName The name of the new mapping | |
| @retval SHELL_SUCCESS the mapping was added | |
| @retval SHELL_INVALID_PARAMETER the device path for Map could not be retrieved. | |
| @return Shell version of a return value from EfiShellProtocol->SetMap | |
| **/ | |
| SHELL_STATUS | |
| AddMappingFromMapping ( | |
| IN CONST CHAR16 *Map, | |
| IN CONST CHAR16 *SName | |
| ) | |
| { | |
| CONST EFI_DEVICE_PATH_PROTOCOL *DevPath; | |
| EFI_STATUS Status; | |
| CHAR16 *NewSName; | |
| RETURN_STATUS StrRetStatus; | |
| NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName); | |
| if (NewSName == NULL) { | |
| return (SHELL_OUT_OF_RESOURCES); | |
| } | |
| if (NewSName[StrLen (NewSName)-1] != L':') { | |
| StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":")); | |
| if (EFI_ERROR (StrRetStatus)) { | |
| FreePool (NewSName); | |
| return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT))); | |
| } | |
| } | |
| if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) { | |
| FreePool (NewSName); | |
| return (SHELL_INVALID_PARAMETER); | |
| } | |
| DevPath = gEfiShellProtocol->GetDevicePathFromMap (Map); | |
| if (DevPath == NULL) { | |
| FreePool (NewSName); | |
| return (SHELL_INVALID_PARAMETER); | |
| } | |
| Status = gEfiShellProtocol->SetMap (DevPath, NewSName); | |
| FreePool (NewSName); | |
| if (EFI_ERROR (Status)) { | |
| return (SHELL_DEVICE_ERROR); | |
| } | |
| return (SHELL_SUCCESS); | |
| } | |
| /** | |
| function to add a mapping from an EFI_HANDLE. | |
| This function will get the device path associated with the Handle and call SetMap. | |
| @param[in] Handle The handle to add a mapping for | |
| @param[in] SName The name of the new mapping | |
| @retval SHELL_SUCCESS the mapping was added | |
| @retval SHELL_INVALID_PARAMETER SName was not valid for a map name. | |
| @return Shell version of a return value from either | |
| gBS->OpenProtocol or EfiShellProtocol->SetMap | |
| **/ | |
| SHELL_STATUS | |
| AddMappingFromHandle ( | |
| IN CONST EFI_HANDLE Handle, | |
| IN CONST CHAR16 *SName | |
| ) | |
| { | |
| EFI_DEVICE_PATH_PROTOCOL *DevPath; | |
| EFI_STATUS Status; | |
| CHAR16 *NewSName; | |
| RETURN_STATUS StrRetStatus; | |
| NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName); | |
| if (NewSName == NULL) { | |
| return (SHELL_OUT_OF_RESOURCES); | |
| } | |
| if (NewSName[StrLen (NewSName)-1] != L':') { | |
| StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":")); | |
| if (EFI_ERROR (StrRetStatus)) { | |
| FreePool (NewSName); | |
| return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT))); | |
| } | |
| } | |
| if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) { | |
| FreePool (NewSName); | |
| return (SHELL_INVALID_PARAMETER); | |
| } | |
| Status = gBS->OpenProtocol ( | |
| Handle, | |
| &gEfiDevicePathProtocolGuid, | |
| (VOID **)&DevPath, | |
| gImageHandle, | |
| NULL, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| FreePool (NewSName); | |
| return (SHELL_DEVICE_ERROR); | |
| } | |
| Status = gEfiShellProtocol->SetMap (DevPath, NewSName); | |
| FreePool (NewSName); | |
| if (EFI_ERROR (Status)) { | |
| return (SHELL_DEVICE_ERROR); | |
| } | |
| return (SHELL_SUCCESS); | |
| } | |
| STATIC CONST SHELL_PARAM_ITEM MapParamList[] = { | |
| { L"-d", TypeValue }, | |
| { L"-r", TypeFlag }, | |
| { L"-v", TypeFlag }, | |
| { L"-c", TypeFlag }, | |
| { L"-f", TypeFlag }, | |
| { L"-u", TypeFlag }, | |
| { L"-t", TypeValue }, | |
| { L"-sfo", TypeValue }, | |
| { NULL, TypeMax } | |
| }; | |
| /** | |
| The routine issues dummy read for every physical block device to cause | |
| the BlockIo re-installed if media change happened. | |
| **/ | |
| VOID | |
| ProbeForMediaChange ( | |
| VOID | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN HandleCount; | |
| EFI_HANDLE *Handles; | |
| EFI_BLOCK_IO_PROTOCOL *BlockIo; | |
| UINTN Index; | |
| gBS->LocateHandleBuffer ( | |
| ByProtocol, | |
| &gEfiBlockIoProtocolGuid, | |
| NULL, | |
| &HandleCount, | |
| &Handles | |
| ); | |
| // | |
| // Probe for media change for every physical block io | |
| // | |
| for (Index = 0; Index < HandleCount; Index++) { | |
| Status = gBS->HandleProtocol ( | |
| Handles[Index], | |
| &gEfiBlockIoProtocolGuid, | |
| (VOID **)&BlockIo | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| if (!BlockIo->Media->LogicalPartition) { | |
| // | |
| // Per spec: | |
| // The function (ReadBlocks) must return EFI_NO_MEDIA or | |
| // EFI_MEDIA_CHANGED even if LBA, BufferSize, or Buffer are invalid so the caller can probe | |
| // for changes in media state. | |
| // | |
| BlockIo->ReadBlocks ( | |
| BlockIo, | |
| BlockIo->Media->MediaId, | |
| 0, | |
| 0, | |
| NULL | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| Function for 'map' command. | |
| @param[in] ImageHandle Handle to the Image (NULL if Internal). | |
| @param[in] SystemTable Pointer to the System Table (NULL if Internal). | |
| **/ | |
| SHELL_STATUS | |
| EFIAPI | |
| ShellCommandRunMap ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| LIST_ENTRY *Package; | |
| CHAR16 *ProblemParam; | |
| CONST CHAR16 *SName; | |
| CONST CHAR16 *Mapping; | |
| EFI_HANDLE MapAsHandle; | |
| SHELL_STATUS ShellStatus; | |
| BOOLEAN SfoMode; | |
| BOOLEAN ConstMode; | |
| BOOLEAN NormlMode; | |
| CONST CHAR16 *Param1; | |
| CONST CHAR16 *TypeString; | |
| UINTN TempStringLength; | |
| ProblemParam = NULL; | |
| Mapping = NULL; | |
| SName = NULL; | |
| ShellStatus = SHELL_SUCCESS; | |
| MapAsHandle = NULL; | |
| // | |
| // initialize the shell lib (we must be in non-auto-init...) | |
| // | |
| Status = ShellInitialize (); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = CommandInit (); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // parse the command line | |
| // | |
| Status = ShellCommandLineParse (MapParamList, &Package, &ProblemParam, TRUE); | |
| if (EFI_ERROR (Status)) { | |
| if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"map", ProblemParam); | |
| FreePool (ProblemParam); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| } else { | |
| ASSERT (FALSE); | |
| } | |
| } else { | |
| // | |
| // check for "-?" | |
| // | |
| SfoMode = ShellCommandLineGetFlag (Package, L"-sfo"); | |
| ConstMode = ShellCommandLineGetFlag (Package, L"-c"); | |
| NormlMode = ShellCommandLineGetFlag (Package, L"-f"); | |
| if (ShellCommandLineGetFlag (Package, L"-?")) { | |
| ASSERT (FALSE); | |
| } else if (ShellCommandLineGetRawValue (Package, 3) != NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"map"); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| } else { | |
| // | |
| // Deleting a map name... | |
| // | |
| if (ShellCommandLineGetFlag (Package, L"-d")) { | |
| if ( ShellCommandLineGetFlag (Package, L"-r") | |
| || ShellCommandLineGetFlag (Package, L"-v") | |
| || ConstMode | |
| || NormlMode | |
| || ShellCommandLineGetFlag (Package, L"-u") | |
| || ShellCommandLineGetFlag (Package, L"-t") | |
| ) | |
| { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"map"); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| } else { | |
| SName = ShellCommandLineGetValue (Package, L"-d"); | |
| if (SName != NULL) { | |
| Status = PerformMappingDelete (SName); | |
| if (EFI_ERROR (Status)) { | |
| if (Status == EFI_ACCESS_DENIED) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map"); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| } else if (Status == EFI_NOT_FOUND) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", SName); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| } else { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status); | |
| ShellStatus = SHELL_UNSUPPORTED; | |
| } | |
| } | |
| } else { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map"); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| } | |
| } | |
| } else if ( ShellCommandLineGetFlag (Package, L"-r") | |
| // || ShellCommandLineGetFlag(Package, L"-v") | |
| || ConstMode | |
| || NormlMode | |
| || ShellCommandLineGetFlag (Package, L"-u") | |
| || ShellCommandLineGetFlag (Package, L"-t") | |
| ) | |
| { | |
| ProbeForMediaChange (); | |
| if ( ShellCommandLineGetFlag (Package, L"-r")) { | |
| // | |
| // Do the reset | |
| // | |
| Status = ShellCommandCreateInitialMappingsAndPaths (); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status); | |
| ShellStatus = SHELL_UNSUPPORTED; | |
| } | |
| } | |
| if ((ShellStatus == SHELL_SUCCESS) && ShellCommandLineGetFlag (Package, L"-u")) { | |
| // | |
| // Do the Update | |
| // | |
| Status = ShellCommandUpdateMapping (); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status); | |
| ShellStatus = SHELL_UNSUPPORTED; | |
| } | |
| } | |
| if (ShellStatus == SHELL_SUCCESS) { | |
| Param1 = ShellCommandLineGetRawValue (Package, 1); | |
| TypeString = ShellCommandLineGetValue (Package, L"-t"); | |
| if ( !ConstMode | |
| && !NormlMode | |
| && (TypeString == NULL) | |
| ) | |
| { | |
| // | |
| // now do the display... | |
| // | |
| ShellStatus = PerformMappingDisplay ( | |
| ShellCommandLineGetFlag (Package, L"-v"), | |
| TRUE, | |
| TRUE, | |
| NULL, | |
| SfoMode, | |
| Param1, | |
| TRUE | |
| ); | |
| } else { | |
| // | |
| // now do the display... | |
| // | |
| ShellStatus = PerformMappingDisplay2 ( | |
| ShellCommandLineGetFlag (Package, L"-v"), | |
| ConstMode, | |
| NormlMode, | |
| TypeString, | |
| SfoMode, | |
| Param1 | |
| ); | |
| } | |
| } | |
| } else { | |
| // | |
| // adding or displaying (there were no flags) | |
| // | |
| SName = ShellCommandLineGetRawValue (Package, 1); | |
| Mapping = ShellCommandLineGetRawValue (Package, 2); | |
| if ( (SName == NULL) | |
| && (Mapping == NULL) | |
| ) | |
| { | |
| // | |
| // display only since no flags | |
| // | |
| ShellStatus = PerformMappingDisplay ( | |
| ShellCommandLineGetFlag (Package, L"-v"), | |
| TRUE, | |
| TRUE, | |
| NULL, | |
| SfoMode, | |
| NULL, | |
| TRUE | |
| ); | |
| } else if ( (SName == NULL) | |
| || (Mapping == NULL) | |
| ) | |
| { | |
| // | |
| // Display only the one specified | |
| // | |
| ShellStatus = PerformMappingDisplay ( | |
| FALSE, | |
| FALSE, | |
| FALSE, | |
| NULL, | |
| SfoMode, | |
| SName, // note the variable here... | |
| TRUE | |
| ); | |
| } else { | |
| if (ShellIsHexOrDecimalNumber (Mapping, TRUE, FALSE)) { | |
| MapAsHandle = ConvertHandleIndexToHandle (ShellStrToUintn (Mapping)); | |
| } else { | |
| MapAsHandle = NULL; | |
| } | |
| if ((MapAsHandle == NULL) && (Mapping[StrLen (Mapping)-1] != L':')) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| } else { | |
| TempStringLength = StrLen (SName); | |
| if (!IsNumberLetterOnly (SName, TempStringLength-((SName[TempStringLength-1] == L':') ? 1 : 0))) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", SName); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| } | |
| if (ShellStatus == SHELL_SUCCESS) { | |
| if (MapAsHandle != NULL) { | |
| ShellStatus = AddMappingFromHandle (MapAsHandle, SName); | |
| } else { | |
| ShellStatus = AddMappingFromMapping (Mapping, SName); | |
| } | |
| if (ShellStatus != SHELL_SUCCESS) { | |
| switch (ShellStatus) { | |
| case SHELL_ACCESS_DENIED: | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map"); | |
| break; | |
| case SHELL_INVALID_PARAMETER: | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping); | |
| break; | |
| case SHELL_DEVICE_ERROR: | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, L"map", Mapping); | |
| break; | |
| default: | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", ShellStatus|MAX_BIT); | |
| } | |
| } else { | |
| // | |
| // now do the display... | |
| // | |
| ShellStatus = PerformMappingDisplay ( | |
| FALSE, | |
| FALSE, | |
| FALSE, | |
| NULL, | |
| SfoMode, | |
| SName, | |
| TRUE | |
| ); | |
| } // we were sucessful so do an output | |
| } | |
| } // got a valid map target | |
| } // got 2 variables | |
| } // we are adding a mapping | |
| } // got valid parameters | |
| } | |
| // | |
| // free the command line package | |
| // | |
| ShellCommandLineFreeVarList (Package); | |
| return (ShellStatus); | |
| } |