Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1376 lines
41 KiB
C
Raw Permalink Normal View History

2010-09-14 05:18:09 +00:00
/** @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>
2018-06-27 21:13:38 +08:00
SPDX-License-Identifier: BSD-2-Clause-Patent
2010-09-14 05:18:09 +00:00
**/
#include "UefiShellLevel2CommandsLib.h"
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/BlockIo.h>
#include <Library/DevicePathLib.h>
#include <Library/HandleParsingLib.h>
#include <Library/SortLib.h>
2011-03-25 20:58:08 +00:00
/**
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;
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
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);
}
}
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
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.
2018-06-27 21:13:38 +08:00
@param[out] FullName Optional pointer to an allocated buffer containing
2011-03-25 20:58:08 +00:00
the match.
@param[in] Meta TRUE to use MetaMatching.
@param[in] SkipTrailingNumbers TRUE to allow for numbers after the MetaTarget.
2018-06-27 21:13:38 +08:00
@param[in] Target The single character that delimits list
items (";" normally).
2011-03-25 20:58:08 +00:00
**/
2010-09-14 05:18:09 +00:00
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);
if (TempList == NULL) {
ASSERT (TempList != NULL);
return (FALSE);
}
2010-09-14 05:18:09 +00:00
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++;
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
if (Meta) {
Result = gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)TempList, (CHAR16 *)MetaTarget);
} else {
Result = (BOOLEAN)(StrCmp (TempList, MetaTarget) == 0);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
if (Result) {
if (FullName != NULL) {
*FullName = TempList;
} else {
FreePool (TempList);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
return (TRUE);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
FreePool (TempList);
TempList = NULL;
}
return (FALSE);
}
2011-03-25 20:58:08 +00:00
/**
2018-06-27 21:13:38 +08:00
Determine what type of device is represented and return it's string. The
2011-03-25 20:58:08 +00:00
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.
**/
2010-09-14 05:18:09 +00:00
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;
}
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
DevicePath = NextDevicePathNode (DevicePath);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
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;
2018-06-27 21:13:38 +08:00
2010-09-14 05:18:09 +00:00
//
// specific has priority
//
2011-03-25 20:58:08 +00:00
if (Specific != NULL) {
Length = StrLen (Specific);
//
// Allocate enough buffer for Specific and potential ":"
//
NewSpecific = AllocatePool ((Length + 2) * sizeof (CHAR16));
if (NewSpecific == NULL) {
return FALSE;
}
2021-12-05 14:54:13 -08:00
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;
}
2011-03-25 20:58:08 +00:00
}
2010-09-14 05:18:09 +00:00
2011-03-25 20:58:08 +00:00
if (SearchList (MapList, NewSpecific, NULL, TRUE, FALSE, L";")) {
FreePool (NewSpecific);
return (TRUE);
}
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
FreePool (NewSpecific);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
if ( Consist
&& (Specific == NULL)
2010-09-14 05:18:09 +00:00
&& ( SearchList (MapList, L"HD*", NULL, TRUE, TRUE, L";")
|| SearchList (MapList, L"CD*", NULL, TRUE, TRUE, L";")
2011-05-17 20:32:47 +00:00
|| SearchList (MapList, L"F*", NULL, TRUE, TRUE, L";")
2010-09-14 05:18:09 +00:00
|| SearchList (MapList, L"FP*", NULL, TRUE, TRUE, L";")))
{
return (TRUE);
}
if ( Normal
&& (Specific == NULL)
2010-09-14 05:18:09 +00:00
&& ( 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);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
return (FALSE);
}
2011-03-25 20:58:08 +00:00
/**
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
2010-09-14 05:18:09 +00:00
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;
2013-11-21 22:51:52 +00:00
CHAR16 *Alias;
2010-09-14 05:18:09 +00:00
UINTN TempLen;
BOOLEAN Removable;
CONST CHAR16 *TempSpot2;
2013-11-21 22:51:52 +00:00
Alias = NULL;
TempSpot2 = NULL;
CurrentName = NULL;
2010-09-14 05:18:09 +00:00
DevPath = DevicePathFromHandle (Handle);
DevPathCopy = DevPath;
MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy);
if (MapList == NULL) {
2011-03-25 20:58:08 +00:00
return EFI_NOT_FOUND;
2010-09-14 05:18:09 +00:00
}
if (!MappingListHasType (MapList, Specific, TypeString, Normal, Consist)) {
2011-03-25 20:58:08 +00:00
return EFI_NOT_FOUND;
2010-09-14 05:18:09 +00:00
}
if (Normal || !Consist) {
//
// need the Normal here since people can use both on command line. otherwise unused.
//
2013-11-21 22:51:52 +00:00
//
// 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 {
2013-11-21 22:51:52 +00:00
CurrentName = NULL;
//
// Skip the first name. This is the standard name.
//
TempSpot = StrStr (MapList, L";");
if (TempSpot != NULL) {
TempSpot++;
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
SearchList (TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";");
if (CurrentName == NULL) {
SearchList (TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";");
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
if (CurrentName == NULL) {
SearchList (TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";");
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
if (CurrentName == NULL) {
SearchList (TempSpot, L"F*", &CurrentName, TRUE, FALSE, L";");
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
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);
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
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;
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
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;
}
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
if (Alias[StrLen (Alias)-1] == L';') {
Alias[StrLen (Alias)-1] = CHAR_NULL;
}
}
2010-09-14 05:18:09 +00:00
}
2021-12-05 14:54:13 -08:00
DevPathString = ConvertDevicePathToText (DevPath, TRUE, FALSE);
TempLen = StrLen (CurrentName);
2010-09-14 05:18:09 +00:00
if (!SFO) {
ShellPrintHiiEx (
-1,
-1,
NULL,
STRING_TOKEN (STR_MAP_ENTRY),
gShellLevel2HiiHandle,
CurrentName,
2013-11-21 22:51:52 +00:00
Alias != NULL ? Alias : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L""),
2010-09-14 05:18:09 +00:00
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
);
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
SHELL_FREE_NON_NULL (MediaType);
2010-09-14 05:18:09 +00:00
}
} else {
ShellPrintHiiEx (
-1,
-1,
NULL,
STRING_TOKEN (STR_MAP_SFO_MAPPINGS),
gShellLevel2HiiHandle,
CurrentName,
DevPathString,
2013-11-21 22:51:52 +00:00
Consist ? L"" : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L"")
2010-09-14 05:18:09 +00:00
);
}
2021-12-05 14:54:13 -08:00
2013-11-21 22:51:52 +00:00
SHELL_FREE_NON_NULL (DevPathString);
SHELL_FREE_NON_NULL (CurrentName);
SHELL_FREE_NON_NULL (Alias);
2011-03-25 20:58:08 +00:00
return EFI_SUCCESS;
2010-09-14 05:18:09 +00:00
}
2011-03-25 20:58:08 +00:00
/**
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.
**/
2010-09-14 05:18:09 +00:00
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);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
//
// if there is a specific and its not on the list...
//
if (!SearchList (MapList, Specific, &CurrentName, TRUE, FALSE, L";")) {
return (EFI_NOT_FOUND);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
return (gEfiShellProtocol->SetMap (NULL, CurrentName));
}
2011-03-25 20:58:08 +00:00
CONST CHAR16 Cd[] = L"cd*";
CONST CHAR16 Hd[] = L"hd*";
CONST CHAR16 Fp[] = L"fp*";
CONST CHAR16 AnyF[] = L"F*";
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
/**
Function to display mapping information to the user.
If Specific is specified then Consist and Normal will be ignored since information will
2010-09-14 05:18:09 +00:00
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.
2010-09-14 05:18:09 +00:00
@retval SHELL_SUCCESS The display was printed.
@retval SHELL_INVALID_PARAMETER One of Consist or Normal must be TRUE if no Specific.
2010-09-14 05:18:09 +00:00
**/
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;
2011-03-25 20:58:08 +00:00
BOOLEAN Found;
2010-09-14 05:18:09 +00:00
if (!Consist && !Normal && (Specific == NULL) && (TypeString == NULL)) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");
2010-09-14 05:18:09 +00:00
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) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", TypeString);
2010-09-14 05:18:09 +00:00
return (SHELL_INVALID_PARAMETER);
}
} else if (Test == NULL) {
2011-03-25 20:58:08 +00:00
Test = (CHAR16 *)AnyF;
2010-09-14 05:18:09 +00:00
}
}
} 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,
2011-03-25 20:58:08 +00:00
&gEfiSimpleFileSystemProtocolGuid,
2010-09-14 05:18:09 +00:00
NULL,
&BufferSize,
HandleBuffer
);
if (Status == EFI_BUFFER_TOO_SMALL) {
2011-03-25 20:58:08 +00:00
HandleBuffer = AllocateZeroPool (BufferSize);
2010-10-04 16:30:40 +00:00
if (HandleBuffer == NULL) {
return (SHELL_OUT_OF_RESOURCES);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
Status = gBS->LocateHandle (
ByProtocol,
2011-03-25 20:58:08 +00:00
&gEfiSimpleFileSystemProtocolGuid,
2010-09-14 05:18:09 +00:00
NULL,
&BufferSize,
HandleBuffer
);
}
//
// Get the map name(s) for each one.
//
2011-03-25 20:58:08 +00:00
for ( LoopVar = 0, Found = FALSE
; LoopVar < (BufferSize / sizeof (EFI_HANDLE)) && HandleBuffer != NULL
2010-09-14 05:18:09 +00:00
; LoopVar++
)
{
2011-03-25 20:58:08 +00:00
Status = PerformSingleMappingDisplay (
2010-09-14 05:18:09 +00:00
Verbose,
Consist,
Normal,
Test,
SFO,
Specific,
HandleBuffer[LoopVar]
);
2011-03-25 20:58:08 +00:00
if (!EFI_ERROR (Status)) {
Found = TRUE;
}
2010-09-14 05:18:09 +00:00
}
//
// 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);
2011-03-25 20:58:08 +00:00
HandleBuffer = AllocateZeroPool (BufferSize);
2010-10-04 16:30:40 +00:00
if (HandleBuffer == NULL) {
return (SHELL_OUT_OF_RESOURCES);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
Status = gBS->LocateHandle (
ByProtocol,
&gEfiBlockIoProtocolGuid,
NULL,
&BufferSize,
HandleBuffer
);
}
2021-12-05 14:54:13 -08:00
2011-04-01 22:16:01 +00:00
if (!EFI_ERROR (Status) && (HandleBuffer != NULL)) {
2010-09-14 05:18:09 +00:00
//
2010-10-04 16:30:40 +00:00
// Get the map name(s) for each one.
2010-09-14 05:18:09 +00:00
//
2010-10-04 16:30:40 +00:00
for ( LoopVar = 0
; LoopVar < BufferSize / sizeof (EFI_HANDLE)
; LoopVar++
)
{
//
// Skip any that were already done...
//
if (gBS->OpenProtocol (
HandleBuffer[LoopVar],
2011-03-25 20:58:08 +00:00
&gEfiSimpleFileSystemProtocolGuid,
2010-10-04 16:30:40 +00:00
NULL,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) == EFI_SUCCESS)
{
continue;
}
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
Status = PerformSingleMappingDisplay (
2010-10-04 16:30:40 +00:00
Verbose,
Consist,
Normal,
Test,
SFO,
Specific,
HandleBuffer[LoopVar]
);
2011-03-25 20:58:08 +00:00
if (!EFI_ERROR (Status)) {
Found = TRUE;
}
2010-09-14 05:18:09 +00:00
}
2021-12-05 14:54:13 -08:00
2010-10-04 16:30:40 +00:00
FreePool (HandleBuffer);
2010-09-14 05:18:09 +00:00
}
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
if (!Found) {
2011-05-17 20:32:47 +00:00
if (Specific != NULL) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", Specific);
2011-05-17 20:32:47 +00:00
} else {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"map");
2011-05-17 20:32:47 +00:00
}
2011-03-25 20:58:08 +00:00
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
return (SHELL_SUCCESS);
}
2011-03-25 20:58:08 +00:00
/**
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
**/
2010-09-14 05:18:09 +00:00
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));
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
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));
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
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));
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
*Comma = L',';
TypeWalker = Comma + 1;
}
}
return (ShellStatus);
}
2011-03-25 20:58:08 +00:00
/**
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.
**/
2010-09-14 05:18:09 +00:00
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) {
2011-03-25 20:58:08 +00:00
HandleBuffer = AllocateZeroPool (BufferSize);
2010-10-04 16:44:57 +00:00
if (HandleBuffer == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
Status = gBS->LocateHandle (
ByProtocol,
&gEfiDevicePathProtocolGuid,
NULL,
&BufferSize,
HandleBuffer
);
}
2021-12-05 14:54:13 -08:00
2010-10-04 16:44:57 +00:00
if (EFI_ERROR (Status)) {
SHELL_FREE_NON_NULL (HandleBuffer);
return (Status);
}
2010-09-14 05:18:09 +00:00
2010-12-06 18:10:34 +00:00
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;
}
2010-09-14 05:18:09 +00:00
}
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
//
// Look up all BlockIo in the platform
//
Status = gBS->LocateHandle (
ByProtocol,
&gEfiBlockIoProtocolGuid,
NULL,
&BufferSize,
HandleBuffer
);
if (Status == EFI_BUFFER_TOO_SMALL) {
FreePool (HandleBuffer);
2011-03-25 20:58:08 +00:00
HandleBuffer = AllocateZeroPool (BufferSize);
2010-10-04 16:44:57 +00:00
if (HandleBuffer == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
Status = gBS->LocateHandle (
ByProtocol,
&gEfiBlockIoProtocolGuid,
NULL,
&BufferSize,
HandleBuffer
);
}
2021-12-05 14:54:13 -08:00
2010-10-04 16:44:57 +00:00
if (EFI_ERROR (Status)) {
SHELL_FREE_NON_NULL (HandleBuffer);
return (Status);
}
2010-09-14 05:18:09 +00:00
2010-12-06 18:10:34 +00:00
if (HandleBuffer != NULL) {
2010-09-14 05:18:09 +00:00
//
2010-12-06 18:10:34 +00:00
// Get the map name(s) for each one.
2010-09-14 05:18:09 +00:00
//
2010-12-06 18:10:34 +00:00
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;
}
2021-12-05 14:54:13 -08:00
2010-12-06 18:10:34 +00:00
if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) {
Deleted = TRUE;
}
2010-09-14 05:18:09 +00:00
}
}
2021-12-05 14:54:13 -08:00
2010-12-06 18:10:34 +00:00
SHELL_FREE_NON_NULL (HandleBuffer);
2010-09-14 05:18:09 +00:00
if (!Deleted) {
return (EFI_NOT_FOUND);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
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;
2011-03-25 20:58:08 +00:00
CHAR16 *NewSName;
RETURN_STATUS StrRetStatus;
2018-06-27 21:13:38 +08:00
NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName);
if (NewSName == NULL) {
return (SHELL_OUT_OF_RESOURCES);
}
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
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)));
}
2011-03-25 20:58:08 +00:00
}
2010-09-14 05:18:09 +00:00
2011-03-25 20:58:08 +00:00
if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) {
FreePool (NewSName);
2010-09-14 05:18:09 +00:00
return (SHELL_INVALID_PARAMETER);
}
DevPath = gEfiShellProtocol->GetDevicePathFromMap (Map);
if (DevPath == NULL) {
2011-03-25 20:58:08 +00:00
FreePool (NewSName);
2010-09-14 05:18:09 +00:00
return (SHELL_INVALID_PARAMETER);
}
2011-03-25 20:58:08 +00:00
Status = gEfiShellProtocol->SetMap (DevPath, NewSName);
FreePool (NewSName);
2010-09-14 05:18:09 +00:00
if (EFI_ERROR (Status)) {
return (SHELL_DEVICE_ERROR);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
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;
2011-03-25 20:58:08 +00:00
CHAR16 *NewSName;
RETURN_STATUS StrRetStatus;
2018-06-27 21:13:38 +08:00
NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName);
if (NewSName == NULL) {
return (SHELL_OUT_OF_RESOURCES);
}
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
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)));
}
2011-03-25 20:58:08 +00:00
}
2010-09-14 05:18:09 +00:00
2011-03-25 20:58:08 +00:00
if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) {
FreePool (NewSName);
2010-09-14 05:18:09 +00:00
return (SHELL_INVALID_PARAMETER);
}
Status = gBS->OpenProtocol (
Handle,
&gEfiDevicePathProtocolGuid,
(VOID **)&DevPath,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
2011-03-25 20:58:08 +00:00
FreePool (NewSName);
2010-09-14 05:18:09 +00:00
return (SHELL_DEVICE_ERROR);
}
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
Status = gEfiShellProtocol->SetMap (DevPath, NewSName);
FreePool (NewSName);
2010-09-14 05:18:09 +00:00
if (EFI_ERROR (Status)) {
return (SHELL_DEVICE_ERROR);
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
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 }
};
2017-07-25 15:30:23 +08:00
/**
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
);
}
}
}
}
2010-09-14 05:18:09 +00:00
/**
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;
2011-03-25 20:58:08 +00:00
EFI_HANDLE MapAsHandle;
2010-09-14 05:18:09 +00:00
SHELL_STATUS ShellStatus;
BOOLEAN SfoMode;
BOOLEAN ConstMode;
BOOLEAN NormlMode;
CONST CHAR16 *Param1;
CONST CHAR16 *TypeString;
2011-03-25 20:58:08 +00:00
UINTN TempStringLength;
2010-09-14 05:18:09 +00:00
ProblemParam = NULL;
Mapping = NULL;
SName = NULL;
ShellStatus = SHELL_SUCCESS;
2011-03-25 20:58:08 +00:00
MapAsHandle = NULL;
2010-09-14 05:18:09 +00:00
//
// 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)) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"map", ProblemParam);
2010-09-14 05:18:09 +00:00
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) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"map");
2010-09-14 05:18:09 +00:00
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")
)
{
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"map");
2010-09-14 05:18:09 +00:00
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
SName = ShellCommandLineGetValue (Package, L"-d");
if (SName != NULL) {
Status = PerformMappingDelete (SName);
if (EFI_ERROR (Status)) {
2013-05-13 02:36:09 +00:00
if (Status == EFI_ACCESS_DENIED) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");
2013-05-13 02:36:09 +00:00
ShellStatus = SHELL_ACCESS_DENIED;
} else if (Status == EFI_NOT_FOUND) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", SName);
2013-05-13 02:36:09 +00:00
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
2013-05-13 02:36:09 +00:00
ShellStatus = SHELL_UNSUPPORTED;
2010-09-14 05:18:09 +00:00
}
}
} else {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");
2010-09-14 05:18:09 +00:00
ShellStatus = SHELL_INVALID_PARAMETER;
}
}
} else if ( ShellCommandLineGetFlag (Package, L"-r")
// || ShellCommandLineGetFlag(Package, L"-v")
|| ConstMode
|| NormlMode
|| ShellCommandLineGetFlag (Package, L"-u")
|| ShellCommandLineGetFlag (Package, L"-t")
)
{
2017-07-25 15:30:23 +08:00
ProbeForMediaChange ();
2010-09-14 05:18:09 +00:00
if ( ShellCommandLineGetFlag (Package, L"-r")) {
//
// Do the reset
//
Status = ShellCommandCreateInitialMappingsAndPaths ();
if (EFI_ERROR (Status)) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
2010-09-14 05:18:09 +00:00
ShellStatus = SHELL_UNSUPPORTED;
}
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
if ((ShellStatus == SHELL_SUCCESS) && ShellCommandLineGetFlag (Package, L"-u")) {
//
// Do the Update
//
Status = ShellCommandUpdateMapping ();
2010-09-14 05:18:09 +00:00
if (EFI_ERROR (Status)) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
2010-09-14 05:18:09 +00:00
ShellStatus = SHELL_UNSUPPORTED;
}
}
2021-12-05 14:54:13 -08:00
2010-09-14 05:18:09 +00:00
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)) {
2011-03-25 20:58:08 +00:00
MapAsHandle = ConvertHandleIndexToHandle (ShellStrToUintn (Mapping));
2010-09-14 05:18:09 +00:00
} else {
2011-03-25 20:58:08 +00:00
MapAsHandle = NULL;
2010-09-14 05:18:09 +00:00
}
2021-12-05 14:54:13 -08:00
2011-03-25 20:58:08 +00:00
if ((MapAsHandle == NULL) && (Mapping[StrLen (Mapping)-1] != L':')) {
2018-06-27 21:13:38 +08:00
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);
2010-09-14 05:18:09 +00:00
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) {
2011-03-25 20:58:08 +00:00
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
);
2023-11-09 11:27:09 -08:00
} // we were successful so do an output
2010-09-14 05:18:09 +00:00
}
} // 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);
}