Home | History | Annotate | Download | only in UefiShellLevel2CommandsLib
      1 /** @file
      2   Main file for map shell level 2 command.
      3 
      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>
      7 
      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
     12 
     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.
     15 
     16 **/
     17 
     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>
     24 
     25 /**
     26   Determine if a string has only numbers and letters.
     27 
     28   This is useful for such things as Map names which can only be letters and numbers.
     29 
     30   @param[in] String       pointer to the string to analyze,
     31   @param[in] Len          Number of characters to analyze.
     32 
     33   @retval TRUE            String has only numbers and letters
     34   @retval FALSE           String has at least one other character.
     35 **/
     36 BOOLEAN
     37 EFIAPI
     38 IsNumberLetterOnly(
     39   IN CONST CHAR16 *String,
     40   IN CONST UINTN  Len
     41   )
     42 {
     43   UINTN Count;
     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'))
     48         ){
     49       return (FALSE);
     50     }
     51   }
     52   return (TRUE);
     53 }
     54 
     55 /**
     56   Do a search in the Target delimited list.
     57 
     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
     61                           the match.
     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
     65                           items (";" normally).
     66 **/
     67 BOOLEAN
     68 EFIAPI
     69 SearchList(
     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
     76 
     77   )
     78 {
     79   CHAR16        *TempList;
     80   CONST CHAR16  *ListWalker;
     81   BOOLEAN       Result;
     82   CHAR16        *TempSpot;
     83 
     84   for (ListWalker = List , TempList = NULL
     85      ; ListWalker != NULL && *ListWalker != CHAR_NULL
     86      ;
     87    ) {
     88     TempList = StrnCatGrow(&TempList, NULL, ListWalker, 0);
     89     ASSERT(TempList != NULL);
     90     TempSpot = StrStr(TempList, Target);
     91     if (TempSpot != NULL) {
     92       *TempSpot = CHAR_NULL;
     93     }
     94 
     95     while (SkipTrailingNumbers && (ShellIsDecimalDigitCharacter(TempList[StrLen(TempList)-1]) || TempList[StrLen(TempList)-1] == L':')) {
     96       TempList[StrLen(TempList)-1] = CHAR_NULL;
     97     }
     98 
     99     ListWalker = StrStr(ListWalker, Target);
    100     while(ListWalker != NULL && *ListWalker == *Target) {
    101       ListWalker++;
    102     }
    103     if (Meta) {
    104       Result = gUnicodeCollation->MetaiMatch(gUnicodeCollation, (CHAR16*)TempList, (CHAR16*)MetaTarget);
    105     } else {
    106       Result = (BOOLEAN)(StrCmp(TempList, MetaTarget)==0);
    107     }
    108     if (Result) {
    109       if (FullName != NULL) {
    110         *FullName = TempList;
    111       } else {
    112         FreePool(TempList);
    113       }
    114       return (TRUE);
    115     }
    116     FreePool(TempList);
    117     TempList = NULL;
    118   }
    119 
    120   return (FALSE);
    121 }
    122 
    123 /**
    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.
    127 
    128   @param[in] DevicePath     The device to analyze.
    129 
    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.
    134 **/
    135 CHAR16*
    136 EFIAPI
    137 GetDeviceMediaType (
    138   IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
    139   )
    140 {
    141   ACPI_HID_DEVICE_PATH  *Acpi;
    142 
    143   //
    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
    149   //
    150   if (NULL == DevicePath) {
    151     return HiiGetString(gShellLevel2HiiHandle, STRING_TOKEN(STR_MAP_MEDIA_UNKNOWN), NULL);
    152   }
    153 
    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);
    159       case MEDIA_CDROM_DP:
    160         return HiiGetString(gShellLevel2HiiHandle, STRING_TOKEN(STR_MAP_MEDIA_CDROM), NULL);
    161       }
    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);
    166       }
    167     }
    168   }
    169 
    170   return HiiGetString(gShellLevel2HiiHandle, STRING_TOKEN(STR_MAP_MEDIA_UNKNOWN), NULL);
    171 }
    172 
    173 /**
    174   Function to detemine if a handle has removable storage.
    175 
    176   @param[in] DevicePath             DevicePath to test.
    177 
    178   @retval TRUE                      The handle has removable storage.
    179   @retval FALSE                     The handle does not have removable storage.
    180 **/
    181 BOOLEAN
    182 EFIAPI
    183 IsRemoveableDevice (
    184   IN EFI_DEVICE_PATH_PROTOCOL      *DevicePath
    185   )
    186 {
    187   if (NULL == DevicePath) {
    188     return FALSE;
    189   }
    190 
    191   while (!IsDevicePathEndType (DevicePath)) {
    192     if (DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) {
    193       switch (DevicePathSubType (DevicePath)) {
    194       case MSG_USB_DP:
    195       case MSG_SCSI_DP:
    196         return TRUE;
    197       default:
    198         return FALSE;
    199       }
    200     }
    201     DevicePath = NextDevicePathNode (DevicePath);
    202   }
    203   return FALSE;
    204 }
    205 
    206 /**
    207   Function to detemine if a something on the map list matches.
    208 
    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.
    214 
    215   @retval TRUE                The map should be displayed.
    216   @retval FALSE               The map should not be displayed.
    217 **/
    218 BOOLEAN
    219 EFIAPI
    220 MappingListHasType(
    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
    226   )
    227 {
    228   CHAR16 *NewSpecific;
    229   RETURN_STATUS  Status;
    230 
    231   //
    232   // specific has priority
    233   //
    234   if (Specific != NULL) {
    235     NewSpecific = AllocateCopyPool(StrSize(Specific) + sizeof(CHAR16), Specific);
    236     if (NewSpecific == NULL){
    237       return FALSE;
    238     }
    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);
    243         return FALSE;
    244       }
    245     }
    246 
    247     if (SearchList(MapList, NewSpecific, NULL, TRUE, FALSE, L";")) {
    248       FreePool(NewSpecific);
    249       return (TRUE);
    250     }
    251     FreePool(NewSpecific);
    252   }
    253   if (  Consist
    254     && Specific == NULL
    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";"))){
    259     return (TRUE);
    260   }
    261 
    262   if (  Normal
    263     && Specific == NULL
    264     && (SearchList(MapList, L"FS",  NULL, FALSE, TRUE, L";")
    265       ||SearchList(MapList, L"BLK", NULL, FALSE, TRUE, L";"))){
    266     return (TRUE);
    267   }
    268 
    269   if (TypeString != NULL && SearchList(MapList, TypeString,  NULL, TRUE, TRUE, L";")) {
    270     return (TRUE);
    271   }
    272   return (FALSE);
    273 }
    274 
    275 
    276 /**
    277   Display a single map line for device Handle if conditions are met.
    278 
    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.
    286 
    287   @retval EFI_SUCCESS               The mapping was displayed.
    288 **/
    289 EFI_STATUS
    290 EFIAPI
    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
    299   )
    300 {
    301   EFI_DEVICE_PATH_PROTOCOL  *DevPath;
    302   EFI_DEVICE_PATH_PROTOCOL  *DevPathCopy;
    303   CONST CHAR16              *MapList;
    304   CHAR16                    *CurrentName;
    305   CHAR16                    *MediaType;
    306   CHAR16                    *DevPathString;
    307   CHAR16                    *TempSpot;
    308   CHAR16                    *Alias;
    309   UINTN                     TempLen;
    310   BOOLEAN                   Removable;
    311   CONST CHAR16              *TempSpot2;
    312 
    313   Alias       = NULL;
    314   TempSpot2   = NULL;
    315   CurrentName = NULL;
    316   DevPath = DevicePathFromHandle(Handle);
    317   DevPathCopy = DevPath;
    318   MapList = gEfiShellProtocol->GetMapFromDevicePath(&DevPathCopy);
    319   if (MapList == NULL) {
    320     return EFI_NOT_FOUND;
    321   }
    322 
    323   if (!MappingListHasType(MapList, Specific, TypeString, Normal, Consist)){
    324     return EFI_NOT_FOUND;
    325   }
    326 
    327   if (Normal || !Consist) {
    328     //
    329     // need the Normal here since people can use both on command line.  otherwise unused.
    330     //
    331 
    332     //
    333     // Allocate a name
    334     //
    335     CurrentName = NULL;
    336     CurrentName = StrnCatGrow(&CurrentName, 0, MapList, 0);
    337     if (CurrentName == NULL) {
    338       return (EFI_OUT_OF_RESOURCES);
    339     }
    340 
    341     //
    342     // Chop off the other names that become "Alias(s)"
    343     // leaving just the normal name
    344     //
    345     TempSpot = StrStr(CurrentName, L";");
    346     if (TempSpot != NULL) {
    347       *TempSpot = CHAR_NULL;
    348     }
    349   } else {
    350     CurrentName = NULL;
    351 
    352     //
    353     // Skip the first name.  This is the standard name.
    354     //
    355     TempSpot = StrStr(MapList, L";");
    356     if (TempSpot != NULL) {
    357       TempSpot++;
    358     }
    359     SearchList(TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";");
    360     if (CurrentName == NULL) {
    361       SearchList(TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";");
    362     }
    363     if (CurrentName == NULL) {
    364       SearchList(TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";");
    365     }
    366     if (CurrentName == NULL) {
    367       SearchList(TempSpot, L"F*",  &CurrentName, TRUE, FALSE, L";");
    368     }
    369     if (CurrentName == NULL) {
    370       //
    371       // We didnt find anything, so just the first one in the list...
    372       //
    373       CurrentName = StrnCatGrow(&CurrentName, 0, MapList, 0);
    374       if (CurrentName == NULL) {
    375         return (EFI_OUT_OF_RESOURCES);
    376       }
    377       TempSpot = StrStr(CurrentName, L";");
    378       if (TempSpot != NULL) {
    379         *TempSpot = CHAR_NULL;
    380       }
    381     } else {
    382       Alias = StrnCatGrow(&Alias, 0, MapList, 0);
    383       if (Alias == NULL) {
    384         return EFI_OUT_OF_RESOURCES;
    385       }
    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));
    392         } else {
    393           *TempSpot = CHAR_NULL;
    394         }
    395       }
    396       if (Alias[StrLen(Alias)-1] == L';') {
    397         Alias[StrLen(Alias)-1] = CHAR_NULL;
    398       }
    399     }
    400   }
    401   DevPathString = ConvertDevicePathToText(DevPath, TRUE, FALSE);
    402   TempLen = StrLen(CurrentName);
    403   if (!SFO) {
    404     ShellPrintHiiEx (
    405       -1,
    406       -1,
    407       NULL,
    408       STRING_TOKEN (STR_MAP_ENTRY),
    409       gShellLevel2HiiHandle,
    410       CurrentName,
    411       Alias!=NULL?Alias:(TempLen < StrLen(MapList)?MapList + TempLen+1:L""),
    412       DevPathString
    413      );
    414     if (Verbose) {
    415       //
    416       // also print handle, media type, removable (y/n), and current directory
    417       //
    418       MediaType = GetDeviceMediaType(DevPath);
    419       if ((TypeString != NULL &&MediaType != NULL && StrStr(TypeString, MediaType) != NULL) || TypeString == NULL) {
    420         Removable = IsRemoveableDevice(DevPath);
    421         TempSpot2 = ShellGetCurrentDir(CurrentName);
    422         ShellPrintHiiEx (
    423           -1,
    424           -1,
    425           NULL,
    426           STRING_TOKEN (STR_MAP_ENTRY_VERBOSE),
    427           gShellLevel2HiiHandle,
    428           ConvertHandleToHandleIndex(Handle),
    429           MediaType,
    430           Removable?L"Yes":L"No",
    431           TempSpot2
    432          );
    433       }
    434       SHELL_FREE_NON_NULL(MediaType);
    435     }
    436   } else {
    437     ShellPrintHiiEx (
    438       -1,
    439       -1,
    440       NULL,
    441       STRING_TOKEN (STR_MAP_SFO_MAPPINGS),
    442       gShellLevel2HiiHandle,
    443       CurrentName,
    444       DevPathString,
    445       Consist?L"":(TempLen < StrLen(MapList)?MapList + TempLen+1:L"")
    446      );
    447   }
    448   SHELL_FREE_NON_NULL(DevPathString);
    449   SHELL_FREE_NON_NULL(CurrentName);
    450   SHELL_FREE_NON_NULL(Alias);
    451   return EFI_SUCCESS;
    452 }
    453 
    454 /**
    455   Delete Specific from the list of maps for device Handle.
    456 
    457   @param[in] Specific   The name to delete.
    458   @param[in] Handle     The device to look on.
    459 
    460   @retval EFI_SUCCESS     The delete was successful.
    461   @retval EFI_NOT_FOUND   Name was not a map on Handle.
    462 **/
    463 EFI_STATUS
    464 EFIAPI
    465 PerformSingleMappingDelete(
    466   IN CONST CHAR16     *Specific,
    467   IN CONST EFI_HANDLE Handle
    468   )
    469 {
    470   EFI_DEVICE_PATH_PROTOCOL  *DevPath;
    471   EFI_DEVICE_PATH_PROTOCOL  *DevPathCopy;
    472   CONST CHAR16              *MapList;
    473   CHAR16                    *CurrentName;
    474 
    475   DevPath     = DevicePathFromHandle(Handle);
    476   DevPathCopy = DevPath;
    477   MapList     = gEfiShellProtocol->GetMapFromDevicePath(&DevPathCopy);
    478   CurrentName = NULL;
    479 
    480   if (MapList == NULL) {
    481     return (EFI_NOT_FOUND);
    482   }
    483   //
    484   // if there is a specific and its not on the list...
    485   //
    486   if (!SearchList(MapList, Specific, &CurrentName, TRUE, FALSE, L";")) {
    487     return (EFI_NOT_FOUND);
    488   }
    489   return (gEfiShellProtocol->SetMap(NULL, CurrentName));
    490 }
    491 
    492 CONST CHAR16 Cd[] = L"cd*";
    493 CONST CHAR16 Hd[] = L"hd*";
    494 CONST CHAR16 Fp[] = L"fp*";
    495 CONST CHAR16 AnyF[] = L"F*";
    496 /**
    497   Function to display mapping information to the user.
    498 
    499   If Specific is specified then Consist and Normal will be ignored since information will
    500   be printed for the specific item only.
    501 
    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.
    509 
    510   @retval SHELL_SUCCESS               The display was printed.
    511   @retval SHELL_INVALID_PARAMETER     One of Consist or Normal must be TRUE if no Specific.
    512 
    513 **/
    514 SHELL_STATUS
    515 EFIAPI
    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
    524   )
    525 {
    526   EFI_STATUS                Status;
    527   EFI_HANDLE                *HandleBuffer;
    528   UINTN                     BufferSize;
    529   UINTN                     LoopVar;
    530   CHAR16                    *Test;
    531   BOOLEAN                   Found;
    532 
    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);
    536   }
    537 
    538   if (TypeString != NULL) {
    539     Test = (CHAR16*)Cd;
    540     if (StrnCmp(TypeString, Test, StrLen(Test)-1) != 0) {
    541       Test = (CHAR16*)Hd;
    542       if (StrnCmp(TypeString, Test, StrLen(Test)-1) != 0) {
    543         Test = (CHAR16*)Fp;
    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);
    547         }
    548       } else if (Test == NULL) {
    549         Test = (CHAR16*)AnyF;
    550       }
    551     }
    552   } else {
    553     Test = NULL;
    554   }
    555 
    556   if (Header) {
    557     //
    558     // Print the header
    559     //
    560     if (!SFO) {
    561       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle);
    562     } else {
    563       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"map");
    564     }
    565   }
    566 
    567   BufferSize    = 0;
    568   HandleBuffer  = NULL;
    569 
    570   //
    571   // Look up all SimpleFileSystems in the platform
    572   //
    573   Status = gBS->LocateHandle(
    574     ByProtocol,
    575     &gEfiSimpleFileSystemProtocolGuid,
    576     NULL,
    577     &BufferSize,
    578     HandleBuffer);
    579   if (Status == EFI_BUFFER_TOO_SMALL) {
    580     HandleBuffer = AllocateZeroPool(BufferSize);
    581     if (HandleBuffer == NULL) {
    582       return (SHELL_OUT_OF_RESOURCES);
    583     }
    584     Status = gBS->LocateHandle(
    585       ByProtocol,
    586       &gEfiSimpleFileSystemProtocolGuid,
    587       NULL,
    588       &BufferSize,
    589       HandleBuffer);
    590   }
    591 
    592   //
    593   // Get the map name(s) for each one.
    594   //
    595   for ( LoopVar = 0, Found = FALSE
    596       ; LoopVar < (BufferSize / sizeof(EFI_HANDLE)) && HandleBuffer != NULL
    597       ; LoopVar ++
    598      ){
    599     Status = PerformSingleMappingDisplay(
    600       Verbose,
    601       Consist,
    602       Normal,
    603       Test,
    604       SFO,
    605       Specific,
    606       HandleBuffer[LoopVar]);
    607     if (!EFI_ERROR(Status)) {
    608       Found = TRUE;
    609     }
    610   }
    611 
    612   //
    613   // Look up all BlockIo in the platform
    614   //
    615   Status = gBS->LocateHandle(
    616     ByProtocol,
    617     &gEfiBlockIoProtocolGuid,
    618     NULL,
    619     &BufferSize,
    620     HandleBuffer);
    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);
    626     }
    627     Status = gBS->LocateHandle(
    628       ByProtocol,
    629       &gEfiBlockIoProtocolGuid,
    630       NULL,
    631       &BufferSize,
    632       HandleBuffer);
    633   }
    634   if (!EFI_ERROR(Status) && HandleBuffer != NULL) {
    635     //
    636     // Get the map name(s) for each one.
    637     //
    638     for ( LoopVar = 0
    639         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)
    640         ; LoopVar ++
    641        ){
    642       //
    643       // Skip any that were already done...
    644       //
    645       if (gBS->OpenProtocol(
    646         HandleBuffer[LoopVar],
    647         &gEfiSimpleFileSystemProtocolGuid,
    648         NULL,
    649         gImageHandle,
    650         NULL,
    651         EFI_OPEN_PROTOCOL_TEST_PROTOCOL) == EFI_SUCCESS) {
    652           continue;
    653       }
    654       Status = PerformSingleMappingDisplay(
    655         Verbose,
    656         Consist,
    657         Normal,
    658         Test,
    659         SFO,
    660         Specific,
    661         HandleBuffer[LoopVar]);
    662       if (!EFI_ERROR(Status)) {
    663         Found = TRUE;
    664       }
    665     }
    666     FreePool(HandleBuffer);
    667   }
    668   if (!Found) {
    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);
    671     } else {
    672       ShellPrintHiiEx(gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"map");
    673     }
    674   }
    675   return (SHELL_SUCCESS);
    676 }
    677 
    678 /**
    679   Perform a mapping display and parse for multiple types in the TypeString.
    680 
    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.
    687 
    688   @retval SHELL_INVALID_PARAMETER   A parameter was invalid.
    689   @retval SHELL_SUCCESS             The display was successful.
    690   @sa PerformMappingDisplay
    691 **/
    692 SHELL_STATUS
    693 EFIAPI
    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
    701   )
    702 {
    703   CONST CHAR16  *TypeWalker;
    704   SHELL_STATUS  ShellStatus;
    705   CHAR16        *Comma;
    706 
    707 
    708   if (TypeString == NULL) {
    709     return (PerformMappingDisplay(Verbose, Consist, Normal, NULL, SFO, Specific, TRUE));
    710   }
    711   ShellStatus = SHELL_SUCCESS;
    712   for (TypeWalker = TypeString ; TypeWalker != NULL && *TypeWalker != CHAR_NULL ;) {
    713     Comma = StrStr(TypeWalker, L",");
    714     if (Comma == NULL) {
    715       if (ShellStatus == SHELL_SUCCESS) {
    716         ShellStatus = PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
    717       } else {
    718         PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
    719       }
    720       break;
    721     } else {
    722       *Comma = CHAR_NULL;
    723       if (ShellStatus == SHELL_SUCCESS) {
    724         ShellStatus = PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
    725       } else {
    726         PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));
    727       }
    728       *Comma = L',';
    729       TypeWalker = Comma + 1;
    730     }
    731   }
    732 
    733   return (ShellStatus);
    734 }
    735 
    736 /**
    737   Delete a specific map.
    738 
    739   @param[in] Specific  The pointer to the name of the map to delete.
    740 
    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.
    744 **/
    745 EFI_STATUS
    746 EFIAPI
    747 PerformMappingDelete(
    748   IN CONST CHAR16  *Specific
    749   )
    750 {
    751   EFI_STATUS                Status;
    752   EFI_HANDLE                *HandleBuffer;
    753   UINTN                     BufferSize;
    754   UINTN                     LoopVar;
    755   BOOLEAN                   Deleted;
    756 
    757   if (Specific == NULL) {
    758     return (EFI_INVALID_PARAMETER);
    759   }
    760 
    761   BufferSize    = 0;
    762   HandleBuffer  = NULL;
    763   Deleted       = FALSE;
    764 
    765   //
    766   // Look up all SimpleFileSystems in the platform
    767   //
    768   Status = gBS->LocateHandle(
    769     ByProtocol,
    770     &gEfiDevicePathProtocolGuid,
    771     NULL,
    772     &BufferSize,
    773     HandleBuffer);
    774   if (Status == EFI_BUFFER_TOO_SMALL) {
    775     HandleBuffer = AllocateZeroPool(BufferSize);
    776     if (HandleBuffer == NULL) {
    777       return (EFI_OUT_OF_RESOURCES);
    778     }
    779     Status = gBS->LocateHandle(
    780       ByProtocol,
    781       &gEfiDevicePathProtocolGuid,
    782       NULL,
    783       &BufferSize,
    784       HandleBuffer);
    785   }
    786   if (EFI_ERROR(Status)) {
    787     SHELL_FREE_NON_NULL(HandleBuffer);
    788     return (Status);
    789   }
    790 
    791   if (HandleBuffer != NULL) {
    792     //
    793     // Get the map name(s) for each one.
    794     //
    795     for ( LoopVar = 0
    796         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)
    797         ; LoopVar ++
    798        ){
    799       if (PerformSingleMappingDelete(Specific,HandleBuffer[LoopVar]) == SHELL_SUCCESS) {
    800           Deleted = TRUE;
    801       }
    802     }
    803   }
    804   //
    805   // Look up all BlockIo in the platform
    806   //
    807   Status = gBS->LocateHandle(
    808     ByProtocol,
    809     &gEfiBlockIoProtocolGuid,
    810     NULL,
    811     &BufferSize,
    812     HandleBuffer);
    813   if (Status == EFI_BUFFER_TOO_SMALL) {
    814     FreePool(HandleBuffer);
    815     HandleBuffer = AllocateZeroPool(BufferSize);
    816     if (HandleBuffer == NULL) {
    817       return (EFI_OUT_OF_RESOURCES);
    818     }
    819     Status = gBS->LocateHandle(
    820       ByProtocol,
    821       &gEfiBlockIoProtocolGuid,
    822       NULL,
    823       &BufferSize,
    824       HandleBuffer);
    825   }
    826   if (EFI_ERROR(Status)) {
    827     SHELL_FREE_NON_NULL(HandleBuffer);
    828     return (Status);
    829   }
    830 
    831   if (HandleBuffer != NULL) {
    832     //
    833     // Get the map name(s) for each one.
    834     //
    835     for ( LoopVar = 0
    836         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)
    837         ; LoopVar ++
    838        ){
    839       //
    840       // Skip any that were already done...
    841       //
    842       if (gBS->OpenProtocol(
    843         HandleBuffer[LoopVar],
    844         &gEfiDevicePathProtocolGuid,
    845         NULL,
    846         gImageHandle,
    847         NULL,
    848         EFI_OPEN_PROTOCOL_TEST_PROTOCOL) == EFI_SUCCESS) {
    849           continue;
    850       }
    851       if (PerformSingleMappingDelete(Specific,HandleBuffer[LoopVar]) == SHELL_SUCCESS) {
    852           Deleted = TRUE;
    853       }
    854     }
    855   }
    856   SHELL_FREE_NON_NULL(HandleBuffer);
    857   if (!Deleted) {
    858     return (EFI_NOT_FOUND);
    859   }
    860   return (EFI_SUCCESS);
    861 }
    862 
    863 /**
    864   function to add a mapping from mapping.
    865 
    866   This function will get the device path associated with the mapping and call SetMap.
    867 
    868   @param[in] Map         The Map to add a mapping for
    869   @param[in] SName       The name of the new mapping
    870 
    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
    874 
    875 **/
    876 SHELL_STATUS
    877 EFIAPI
    878 AddMappingFromMapping(
    879   IN CONST CHAR16     *Map,
    880   IN CONST CHAR16     *SName
    881   )
    882 {
    883   CONST EFI_DEVICE_PATH_PROTOCOL  *DevPath;
    884   EFI_STATUS                      Status;
    885   CHAR16                          *NewSName;
    886   RETURN_STATUS                   StrRetStatus;
    887 
    888   NewSName = AllocateCopyPool(StrSize(SName) + sizeof(CHAR16), SName);
    889   if (NewSName == NULL) {
    890     return (SHELL_OUT_OF_RESOURCES);
    891   }
    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)) {
    895       FreePool(NewSName);
    896       return ((SHELL_STATUS) (StrRetStatus & (~MAX_BIT)));
    897     }
    898   }
    899 
    900   if (!IsNumberLetterOnly(NewSName, StrLen(NewSName)-1)) {
    901     FreePool(NewSName);
    902     return (SHELL_INVALID_PARAMETER);
    903   }
    904 
    905   DevPath = gEfiShellProtocol->GetDevicePathFromMap(Map);
    906   if (DevPath == NULL) {
    907     FreePool(NewSName);
    908     return (SHELL_INVALID_PARAMETER);
    909   }
    910 
    911   Status = gEfiShellProtocol->SetMap(DevPath, NewSName);
    912   FreePool(NewSName);
    913   if (EFI_ERROR(Status)) {
    914     return (SHELL_DEVICE_ERROR);
    915   }
    916   return (SHELL_SUCCESS);
    917 }
    918 
    919 /**
    920   function to add a mapping from an EFI_HANDLE.
    921 
    922   This function will get the device path associated with the Handle and call SetMap.
    923 
    924   @param[in] Handle       The handle to add a mapping for
    925   @param[in] SName        The name of the new mapping
    926 
    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
    931 
    932 **/
    933 SHELL_STATUS
    934 EFIAPI
    935 AddMappingFromHandle(
    936   IN CONST EFI_HANDLE Handle,
    937   IN CONST CHAR16     *SName
    938   )
    939 {
    940   EFI_DEVICE_PATH_PROTOCOL  *DevPath;
    941   EFI_STATUS                Status;
    942   CHAR16                    *NewSName;
    943   RETURN_STATUS             StrRetStatus;
    944 
    945   NewSName = AllocateCopyPool(StrSize(SName) + sizeof(CHAR16), SName);
    946   if (NewSName == NULL) {
    947     return (SHELL_OUT_OF_RESOURCES);
    948   }
    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)) {
    952       FreePool(NewSName);
    953       return ((SHELL_STATUS) (StrRetStatus & (~MAX_BIT)));
    954     }
    955   }
    956 
    957   if (!IsNumberLetterOnly(NewSName, StrLen(NewSName)-1)) {
    958     FreePool(NewSName);
    959     return (SHELL_INVALID_PARAMETER);
    960   }
    961 
    962   Status = gBS->OpenProtocol(
    963     Handle,
    964     &gEfiDevicePathProtocolGuid,
    965     (VOID**)&DevPath,
    966     gImageHandle,
    967     NULL,
    968     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    969    );
    970   if (EFI_ERROR(Status)) {
    971     FreePool(NewSName);
    972     return (SHELL_DEVICE_ERROR);
    973   }
    974   Status = gEfiShellProtocol->SetMap(DevPath, NewSName);
    975   FreePool(NewSName);
    976   if (EFI_ERROR(Status)) {
    977     return (SHELL_DEVICE_ERROR);
    978   }
    979   return (SHELL_SUCCESS);
    980 }
    981 
    982 STATIC CONST SHELL_PARAM_ITEM MapParamList[] = {
    983   {L"-d", TypeValue},
    984   {L"-r", TypeFlag},
    985   {L"-v", TypeFlag},
    986   {L"-c", TypeFlag},
    987   {L"-f", TypeFlag},
    988   {L"-u", TypeFlag},
    989   {L"-t", TypeValue},
    990   {L"-sfo", TypeValue},
    991   {NULL, TypeMax}
    992   };
    993 
    994 /**
    995   Function for 'map' command.
    996 
    997   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
    998   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
    999 **/
   1000 SHELL_STATUS
   1001 EFIAPI
   1002 ShellCommandRunMap (
   1003   IN EFI_HANDLE        ImageHandle,
   1004   IN EFI_SYSTEM_TABLE  *SystemTable
   1005   )
   1006 {
   1007   EFI_STATUS    Status;
   1008   LIST_ENTRY    *Package;
   1009   CHAR16        *ProblemParam;
   1010   CONST CHAR16  *SName;
   1011   CONST CHAR16  *Mapping;
   1012   EFI_HANDLE    MapAsHandle;
   1013   SHELL_STATUS  ShellStatus;
   1014   BOOLEAN       SfoMode;
   1015   BOOLEAN       ConstMode;
   1016   BOOLEAN       NormlMode;
   1017   CONST CHAR16  *Param1;
   1018   CONST CHAR16  *TypeString;
   1019   UINTN         TempStringLength;
   1020 
   1021   ProblemParam  = NULL;
   1022   Mapping       = NULL;
   1023   SName         = NULL;
   1024   ShellStatus   = SHELL_SUCCESS;
   1025   MapAsHandle = NULL;
   1026 
   1027   //
   1028   // initialize the shell lib (we must be in non-auto-init...)
   1029   //
   1030   Status = ShellInitialize();
   1031   ASSERT_EFI_ERROR(Status);
   1032 
   1033   Status = CommandInit();
   1034   ASSERT_EFI_ERROR(Status);
   1035 
   1036   //
   1037   // parse the command line
   1038   //
   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;
   1045     } else {
   1046       ASSERT(FALSE);
   1047     }
   1048   } else {
   1049     //
   1050     // check for "-?"
   1051     //
   1052     SfoMode   = ShellCommandLineGetFlag(Package, L"-sfo");
   1053     ConstMode = ShellCommandLineGetFlag(Package, L"-c");
   1054     NormlMode = ShellCommandLineGetFlag(Package, L"-f");
   1055     if (ShellCommandLineGetFlag(Package, L"-?")) {
   1056       ASSERT(FALSE);
   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;
   1060     } else {
   1061       //
   1062       // Deleting a map name...
   1063       //
   1064       if (ShellCommandLineGetFlag(Package, L"-d")) {
   1065         if ( ShellCommandLineGetFlag(Package, L"-r")
   1066           || ShellCommandLineGetFlag(Package, L"-v")
   1067           || ConstMode
   1068           || NormlMode
   1069           || ShellCommandLineGetFlag(Package, L"-u")
   1070           || ShellCommandLineGetFlag(Package, L"-t")
   1071          ){
   1072           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"map");
   1073           ShellStatus = SHELL_INVALID_PARAMETER;
   1074         } else {
   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;
   1085               } else {
   1086                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);
   1087                 ShellStatus = SHELL_UNSUPPORTED;
   1088               }
   1089             }
   1090           } else {
   1091             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");
   1092             ShellStatus = SHELL_INVALID_PARAMETER;
   1093           }
   1094         }
   1095       } else if ( ShellCommandLineGetFlag(Package, L"-r")
   1096 //               || ShellCommandLineGetFlag(Package, L"-v")
   1097                || ConstMode
   1098                || NormlMode
   1099                || ShellCommandLineGetFlag(Package, L"-u")
   1100                || ShellCommandLineGetFlag(Package, L"-t")
   1101               ){
   1102         if ( ShellCommandLineGetFlag(Package, L"-r")) {
   1103           //
   1104           // Do the reset
   1105           //
   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;
   1110           }
   1111         }
   1112         if ( ShellStatus == SHELL_SUCCESS && ShellCommandLineGetFlag(Package, L"-u")) {
   1113           //
   1114           // Do the Update
   1115           //
   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;
   1120           }
   1121         }
   1122         if (ShellStatus == SHELL_SUCCESS) {
   1123           Param1 = ShellCommandLineGetRawValue(Package, 1);
   1124           TypeString = ShellCommandLineGetValue(Package, L"-t");
   1125           if (!ConstMode
   1126             &&!NormlMode
   1127             &&TypeString  == NULL
   1128             ) {
   1129             //
   1130             // now do the display...
   1131             //
   1132             ShellStatus = PerformMappingDisplay(
   1133               ShellCommandLineGetFlag(Package, L"-v"),
   1134               TRUE,
   1135               TRUE,
   1136               NULL,
   1137               SfoMode,
   1138               Param1,
   1139               TRUE
   1140              );
   1141           } else {
   1142             //
   1143             // now do the display...
   1144             //
   1145             ShellStatus = PerformMappingDisplay2(
   1146               ShellCommandLineGetFlag(Package, L"-v"),
   1147               ConstMode,
   1148               NormlMode,
   1149               TypeString,
   1150               SfoMode,
   1151               Param1
   1152              );
   1153           }
   1154         }
   1155       } else {
   1156         //
   1157         // adding or displaying (there were no flags)
   1158         //
   1159         SName = ShellCommandLineGetRawValue(Package, 1);
   1160         Mapping = ShellCommandLineGetRawValue(Package, 2);
   1161         if ( SName == NULL
   1162           && Mapping == NULL
   1163          ){
   1164           //
   1165           // display only since no flags
   1166           //
   1167           ShellStatus = PerformMappingDisplay(
   1168             ShellCommandLineGetFlag(Package, L"-v"),
   1169             TRUE,
   1170             TRUE,
   1171             NULL,
   1172             SfoMode,
   1173             NULL,
   1174             TRUE
   1175            );
   1176         } else if ( SName == NULL
   1177           || Mapping == NULL
   1178          ){
   1179             //
   1180             // Display only the one specified
   1181             //
   1182           ShellStatus = PerformMappingDisplay(
   1183             FALSE,
   1184             FALSE,
   1185             FALSE,
   1186             NULL,
   1187             SfoMode,
   1188             SName, // note the variable here...
   1189             TRUE
   1190            );
   1191         } else {
   1192           if (ShellIsHexOrDecimalNumber(Mapping, TRUE, FALSE)) {
   1193             MapAsHandle = ConvertHandleIndexToHandle(ShellStrToUintn(Mapping));
   1194           } else {
   1195             MapAsHandle = NULL;
   1196           }
   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;
   1200           } else {
   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;
   1205             }
   1206 
   1207             if (ShellStatus == SHELL_SUCCESS) {
   1208               if (MapAsHandle != NULL) {
   1209                 ShellStatus = AddMappingFromHandle(MapAsHandle, SName);
   1210               } else {
   1211                 ShellStatus = AddMappingFromMapping(Mapping, SName);
   1212               }
   1213 
   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");
   1218                     break;
   1219                   case SHELL_INVALID_PARAMETER:
   1220                     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);
   1221                     break;
   1222                   case SHELL_DEVICE_ERROR:
   1223                     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, L"map", Mapping);
   1224                     break;
   1225                   default:
   1226                     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", ShellStatus|MAX_BIT);
   1227                 }
   1228               } else {
   1229                 //
   1230                 // now do the display...
   1231                 //
   1232                 ShellStatus = PerformMappingDisplay(
   1233                   FALSE,
   1234                   FALSE,
   1235                   FALSE,
   1236                   NULL,
   1237                   SfoMode,
   1238                   SName,
   1239                   TRUE
   1240                  );
   1241               } // we were sucessful so do an output
   1242             }
   1243           } // got a valid map target
   1244         } // got 2 variables
   1245       } // we are adding a mapping
   1246     } // got valid parameters
   1247   }
   1248 
   1249   //
   1250   // free the command line package
   1251   //
   1252   ShellCommandLineFreeVarList (Package);
   1253 
   1254   return (ShellStatus);
   1255 }
   1256 
   1257