ShellPkg: Standardized HP Copyright Message String
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Map.c
1 /** @file\r
2   Main file for map shell level 2 command.\r
3 \r
4   (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
5   Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
6   This program and the accompanying materials\r
7   are licensed and made available under the terms and conditions of the BSD License\r
8   which accompanies this distribution.  The full text of the license may be found at\r
9   http://opensource.org/licenses/bsd-license.php\r
10 \r
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13 \r
14 **/\r
15 \r
16 #include "UefiShellLevel2CommandsLib.h"\r
17 #include <Protocol/SimpleFileSystem.h>\r
18 #include <Protocol/BlockIo.h>\r
19 #include <Library/DevicePathLib.h>\r
20 #include <Library/HandleParsingLib.h>\r
21 #include <Library/SortLib.h>\r
22 \r
23 /**\r
24   Determine if a string has only numbers and letters.\r
25 \r
26   This is useful for such things as Map names which can only be letters and numbers.\r
27 \r
28   @param[in] String       pointer to the string to analyze,\r
29   @param[in] Len          Number of characters to analyze.\r
30 \r
31   @retval TRUE            String has only numbers and letters\r
32   @retval FALSE           String has at least one other character.\r
33 **/\r
34 BOOLEAN\r
35 EFIAPI\r
36 IsNumberLetterOnly(\r
37   IN CONST CHAR16 *String,\r
38   IN CONST UINTN  Len\r
39   )\r
40 {\r
41   UINTN Count;\r
42   for (Count = 0 ; Count < Len && String != NULL && *String != CHAR_NULL ; String++,Count++) {\r
43     if (! ((*String >= L'a' && *String <= L'z') ||\r
44            (*String >= L'A' && *String <= L'Z') ||\r
45            (*String >= L'0' && *String <= L'9'))\r
46         ){\r
47       return (FALSE);\r
48     }\r
49   }\r
50   return (TRUE);\r
51 }\r
52 \r
53 /**\r
54   Do a search in the Target delimited list.\r
55 \r
56   @param[in] List         The list to seatch in.\r
57   @param[in] MetaTarget   The item to search for. MetaMatching supported.\r
58   @param[out] FullName    Optional pointer to an allocated buffer containing \r
59                           the match.\r
60   @param[in] Meta         TRUE to use MetaMatching.\r
61   @param[in] SkipTrailingNumbers  TRUE to allow for numbers after the MetaTarget.\r
62   @param[in] Target       The single character that delimits list \r
63                           items (";" normally). \r
64 **/\r
65 BOOLEAN\r
66 EFIAPI\r
67 SearchList(\r
68   IN CONST CHAR16   *List,\r
69   IN CONST CHAR16   *MetaTarget,\r
70   OUT CHAR16        **FullName OPTIONAL,\r
71   IN CONST BOOLEAN  Meta,\r
72   IN CONST BOOLEAN  SkipTrailingNumbers,\r
73   IN CONST CHAR16   *Target\r
74 \r
75   )\r
76 {\r
77   CHAR16        *TempList;\r
78   CONST CHAR16  *ListWalker;\r
79   BOOLEAN       Result;\r
80   CHAR16        *TempSpot;\r
81 \r
82   for (ListWalker = List , TempList = NULL\r
83      ; ListWalker != NULL && *ListWalker != CHAR_NULL\r
84      ;\r
85    ) {\r
86     TempList = StrnCatGrow(&TempList, NULL, ListWalker, 0);\r
87     ASSERT(TempList != NULL);\r
88     TempSpot = StrStr(TempList, Target);\r
89     if (TempSpot != NULL) {\r
90       *TempSpot = CHAR_NULL;\r
91     }\r
92 \r
93     while (SkipTrailingNumbers && (ShellIsDecimalDigitCharacter(TempList[StrLen(TempList)-1]) || TempList[StrLen(TempList)-1] == L':')) {\r
94       TempList[StrLen(TempList)-1] = CHAR_NULL;\r
95     }\r
96 \r
97     ListWalker = StrStr(ListWalker, Target);\r
98     while(ListWalker != NULL && *ListWalker == *Target) {\r
99       ListWalker++;\r
100     }\r
101     if (Meta) {\r
102       Result = gUnicodeCollation->MetaiMatch(gUnicodeCollation, (CHAR16*)TempList, (CHAR16*)MetaTarget);\r
103     } else {\r
104       Result = (BOOLEAN)(StrCmp(TempList, MetaTarget)==0);\r
105     }\r
106     if (Result) {\r
107       if (FullName != NULL) {\r
108         *FullName = TempList;\r
109       } else {\r
110         FreePool(TempList);\r
111       }\r
112       return (TRUE);\r
113     }\r
114     FreePool(TempList);\r
115     TempList = NULL;\r
116   }\r
117 \r
118   return (FALSE);\r
119 }\r
120 \r
121 /**\r
122   Determine what type of device is represented and return it's string.  The \r
123   string is in allocated memory and must be callee freed.  The HII is is listed below.\r
124   The actual string cannot be determined.\r
125 \r
126   @param[in] DevicePath     The device to analyze.\r
127 \r
128   @retval STR_MAP_MEDIA_UNKNOWN   The media type is unknown.\r
129   @retval STR_MAP_MEDIA_HARDDISK  The media is a hard drive.\r
130   @retval STR_MAP_MEDIA_CDROM     The media is a CD ROM.\r
131   @retval STR_MAP_MEDIA_FLOPPY    The media is a floppy drive.\r
132 **/\r
133 CHAR16*\r
134 EFIAPI\r
135 GetDeviceMediaType (\r
136   IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
137   )\r
138 {\r
139   ACPI_HID_DEVICE_PATH  *Acpi;\r
140 \r
141   //\r
142   //  Parse the device path:\r
143   //  Devicepath sub type                 mediatype\r
144   //    MEDIA_HANRDDRIVE_DP      ->       Hard Disk\r
145   //    MEDIA_CDROM_DP           ->       CD Rom\r
146   //    Acpi.HID = 0X0604        ->       Floppy\r
147   //\r
148   if (NULL == DevicePath) {\r
149     return HiiGetString(gShellLevel2HiiHandle, STRING_TOKEN(STR_MAP_MEDIA_UNKNOWN), NULL);\r
150   }\r
151 \r
152   for (;!IsDevicePathEndType (DevicePath) ;DevicePath = NextDevicePathNode (DevicePath)) {\r
153     if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) {\r
154       switch (DevicePathSubType (DevicePath)) {\r
155       case MEDIA_HARDDRIVE_DP:\r
156         return HiiGetString(gShellLevel2HiiHandle, STRING_TOKEN(STR_MAP_MEDIA_HARDDISK), NULL);\r
157       case MEDIA_CDROM_DP:\r
158         return HiiGetString(gShellLevel2HiiHandle, STRING_TOKEN(STR_MAP_MEDIA_CDROM), NULL);\r
159       }\r
160     } else if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH) {\r
161       Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;\r
162       if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {\r
163         return HiiGetString(gShellLevel2HiiHandle, STRING_TOKEN(STR_MAP_MEDIA_FLOPPY), NULL);\r
164       }\r
165     }\r
166   }\r
167 \r
168   return HiiGetString(gShellLevel2HiiHandle, STRING_TOKEN(STR_MAP_MEDIA_UNKNOWN), NULL);\r
169 }\r
170 \r
171 /**\r
172   Function to detemine if a handle has removable storage.\r
173 \r
174   @param[in] DevicePath             DevicePath to test.\r
175 \r
176   @retval TRUE                      The handle has removable storage.\r
177   @retval FALSE                     The handle does not have removable storage.\r
178 **/\r
179 BOOLEAN\r
180 EFIAPI\r
181 IsRemoveableDevice (\r
182   IN EFI_DEVICE_PATH_PROTOCOL      *DevicePath\r
183   )\r
184 {\r
185   if (NULL == DevicePath) {\r
186     return FALSE;\r
187   }\r
188 \r
189   while (!IsDevicePathEndType (DevicePath)) {\r
190     if (DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) {\r
191       switch (DevicePathSubType (DevicePath)) {\r
192       case MSG_USB_DP:\r
193       case MSG_SCSI_DP:\r
194         return TRUE;\r
195       default:\r
196         return FALSE;\r
197       }\r
198     }\r
199     DevicePath = NextDevicePathNode (DevicePath);\r
200   }\r
201   return FALSE;\r
202 }\r
203 \r
204 /**\r
205   Function to detemine if a something on the map list matches.\r
206 \r
207   @param[in] MapList          The pointer to the list to test.\r
208   @param[in] Specific         The pointer to a specific name to test for.\r
209   @param[in] TypeString       The pointer to the list of types.\r
210   @param[in] Normal           Always show normal mappings.\r
211   @param[in] Consist          Always show consistent mappings.\r
212 \r
213   @retval TRUE                The map should be displayed.\r
214   @retval FALSE               The map should not be displayed.\r
215 **/\r
216 BOOLEAN\r
217 EFIAPI\r
218 MappingListHasType(\r
219   IN CONST CHAR16     *MapList,\r
220   IN CONST CHAR16     *Specific,\r
221   IN CONST CHAR16     *TypeString,\r
222   IN CONST BOOLEAN    Normal,\r
223   IN CONST BOOLEAN    Consist\r
224   )\r
225 {\r
226   CHAR16 *NewSpecific;\r
227   //\r
228   // specific has priority\r
229   //\r
230   if (Specific != NULL) {\r
231     NewSpecific = AllocateCopyPool(StrSize(Specific) + sizeof(CHAR16), Specific);\r
232     if (NewSpecific == NULL){\r
233       return FALSE;\r
234     }\r
235     if (NewSpecific[StrLen(NewSpecific)-1] != L':') {\r
236       StrnCat(NewSpecific, L":", 2);\r
237     }\r
238 \r
239     if (SearchList(MapList, NewSpecific, NULL, TRUE, FALSE, L";")) {\r
240       FreePool(NewSpecific);\r
241       return (TRUE);\r
242     }\r
243     FreePool(NewSpecific);\r
244   }\r
245   if (  Consist\r
246     && Specific == NULL\r
247     && (SearchList(MapList, L"HD*",  NULL, TRUE, TRUE, L";")\r
248       ||SearchList(MapList, L"CD*",  NULL, TRUE, TRUE, L";")\r
249       ||SearchList(MapList, L"F*",   NULL, TRUE, TRUE, L";")\r
250       ||SearchList(MapList, L"FP*",  NULL, TRUE, TRUE, L";"))){\r
251     return (TRUE);\r
252   }\r
253 \r
254   if (  Normal\r
255     && Specific == NULL\r
256     && (SearchList(MapList, L"FS",  NULL, FALSE, TRUE, L";")\r
257       ||SearchList(MapList, L"BLK", NULL, FALSE, TRUE, L";"))){\r
258     return (TRUE);\r
259   }\r
260 \r
261   if (TypeString != NULL && SearchList(MapList, TypeString,  NULL, TRUE, TRUE, L";")) {\r
262     return (TRUE);\r
263   }\r
264   return (FALSE);\r
265 }\r
266 \r
267 \r
268 /**\r
269   Display a single map line for device Handle if conditions are met.\r
270 \r
271   @param[in] Verbose                TRUE to display (extra) verbose information.\r
272   @param[in] Consist                TRUE to display consistent mappings.\r
273   @param[in] Normal                 TRUE to display normal (not consist) mappings.\r
274   @param[in] TypeString             pointer to string of filter types.\r
275   @param[in] SFO                    TRUE to display output in Standard Output Format.\r
276   @param[in] Specific               pointer to string for specific map to display.\r
277   @param[in] Handle                 The handle to display from.\r
278 \r
279   @retval EFI_SUCCESS               The mapping was displayed.\r
280 **/\r
281 EFI_STATUS\r
282 EFIAPI\r
283 PerformSingleMappingDisplay(\r
284   IN CONST BOOLEAN    Verbose,\r
285   IN CONST BOOLEAN    Consist,\r
286   IN CONST BOOLEAN    Normal,\r
287   IN CONST CHAR16     *TypeString,\r
288   IN CONST BOOLEAN    SFO,\r
289   IN CONST CHAR16     *Specific OPTIONAL,\r
290   IN CONST EFI_HANDLE Handle\r
291   )\r
292 {\r
293   EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
294   EFI_DEVICE_PATH_PROTOCOL  *DevPathCopy;\r
295   CONST CHAR16              *MapList;\r
296   CHAR16                    *CurrentName;\r
297   CHAR16                    *MediaType;\r
298   CHAR16                    *DevPathString;\r
299   CHAR16                    *TempSpot;\r
300   CHAR16                    *Alias;\r
301   UINTN                     TempLen;\r
302   BOOLEAN                   Removable;\r
303   CONST CHAR16              *TempSpot2;\r
304 \r
305   Alias       = NULL;\r
306   TempSpot2   = NULL;\r
307   CurrentName = NULL;\r
308   DevPath = DevicePathFromHandle(Handle);\r
309   DevPathCopy = DevPath;\r
310   MapList = gEfiShellProtocol->GetMapFromDevicePath(&DevPathCopy);\r
311   if (MapList == NULL) {\r
312     return EFI_NOT_FOUND;\r
313   }\r
314 \r
315   if (!MappingListHasType(MapList, Specific, TypeString, Normal, Consist)){\r
316     return EFI_NOT_FOUND;\r
317   }\r
318 \r
319   if (Normal || !Consist) {\r
320     //\r
321     // need the Normal here since people can use both on command line.  otherwise unused.\r
322     //\r
323 \r
324     //\r
325     // Allocate a name\r
326     //\r
327     CurrentName = NULL;\r
328     CurrentName = StrnCatGrow(&CurrentName, 0, MapList, 0);\r
329     if (CurrentName == NULL) {\r
330       return (EFI_OUT_OF_RESOURCES);\r
331     }\r
332 \r
333     //\r
334     // Chop off the other names that become "Alias(s)"\r
335     // leaving just the normal name\r
336     //\r
337     TempSpot = StrStr(CurrentName, L";");\r
338     if (TempSpot != NULL) {\r
339       *TempSpot = CHAR_NULL;\r
340     }\r
341   } else {\r
342     CurrentName = NULL;\r
343 \r
344     //\r
345     // Skip the first name.  This is the standard name.\r
346     //\r
347     TempSpot = StrStr(MapList, L";");\r
348     if (TempSpot != NULL) {\r
349       TempSpot++;\r
350     }\r
351     SearchList(TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";");\r
352     if (CurrentName == NULL) {\r
353       SearchList(TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";");\r
354     }\r
355     if (CurrentName == NULL) {\r
356       SearchList(TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";");\r
357     }\r
358     if (CurrentName == NULL) {\r
359       SearchList(TempSpot, L"F*",  &CurrentName, TRUE, FALSE, L";");\r
360     }\r
361     if (CurrentName == NULL) {\r
362       //\r
363       // We didnt find anything, so just the first one in the list...\r
364       //\r
365       CurrentName = StrnCatGrow(&CurrentName, 0, MapList, 0);\r
366       if (CurrentName == NULL) {\r
367         return (EFI_OUT_OF_RESOURCES);\r
368       }\r
369       TempSpot = StrStr(CurrentName, L";");\r
370       if (TempSpot != NULL) {\r
371         *TempSpot = CHAR_NULL;\r
372       }\r
373     } else {\r
374       Alias = StrnCatGrow(&Alias, 0, MapList, 0);\r
375       if (Alias == NULL) {\r
376         return EFI_OUT_OF_RESOURCES;\r
377       }\r
378       TempSpot = StrStr(Alias, CurrentName);\r
379       if (TempSpot != NULL) {\r
380         TempSpot2 = StrStr(TempSpot, L";");\r
381         if (TempSpot2 != NULL) {\r
382           TempSpot2++; // Move past ";" from CurrentName\r
383           CopyMem(TempSpot, TempSpot2, StrSize(TempSpot2));\r
384         } else {\r
385           *TempSpot = CHAR_NULL;\r
386         }\r
387       }\r
388       if (Alias[StrLen(Alias)-1] == L';') {\r
389         Alias[StrLen(Alias)-1] = CHAR_NULL;\r
390       }\r
391     }\r
392   }\r
393   DevPathString = ConvertDevicePathToText(DevPath, TRUE, FALSE);\r
394   TempLen = StrLen(CurrentName);\r
395   if (!SFO) {\r
396     ShellPrintHiiEx (\r
397       -1,\r
398       -1,\r
399       NULL,\r
400       STRING_TOKEN (STR_MAP_ENTRY),\r
401       gShellLevel2HiiHandle,\r
402       CurrentName,\r
403       Alias!=NULL?Alias:(TempLen < StrLen(MapList)?MapList + TempLen+1:L""),\r
404       DevPathString\r
405      );\r
406     if (Verbose) {\r
407       //\r
408       // also print handle, media type, removable (y/n), and current directory\r
409       //\r
410       MediaType = GetDeviceMediaType(DevPath);\r
411       if ((TypeString != NULL &&MediaType != NULL && StrStr(TypeString, MediaType) != NULL) || TypeString == NULL) {\r
412         Removable = IsRemoveableDevice(DevPath);\r
413         TempSpot2 = ShellGetCurrentDir(CurrentName);\r
414         ShellPrintHiiEx (\r
415           -1,\r
416           -1,\r
417           NULL,\r
418           STRING_TOKEN (STR_MAP_ENTRY_VERBOSE),\r
419           gShellLevel2HiiHandle,\r
420           ConvertHandleToHandleIndex(Handle),\r
421           MediaType,\r
422           Removable?L"Yes":L"No",\r
423           TempSpot2\r
424          );\r
425       }\r
426       SHELL_FREE_NON_NULL(MediaType);\r
427     }\r
428   } else {\r
429     ShellPrintHiiEx (\r
430       -1,\r
431       -1,\r
432       NULL,\r
433       STRING_TOKEN (STR_MAP_SFO_MAPPINGS),\r
434       gShellLevel2HiiHandle,\r
435       CurrentName,\r
436       DevPathString,\r
437       Consist?L"":(TempLen < StrLen(MapList)?MapList + TempLen+1:L"")\r
438      );\r
439   }\r
440   SHELL_FREE_NON_NULL(DevPathString);\r
441   SHELL_FREE_NON_NULL(CurrentName);\r
442   SHELL_FREE_NON_NULL(Alias);\r
443   return EFI_SUCCESS;\r
444 }\r
445 \r
446 /**\r
447   Delete Specific from the list of maps for device Handle.\r
448 \r
449   @param[in] Specific   The name to delete.\r
450   @param[in] Handle     The device to look on.\r
451 \r
452   @retval EFI_SUCCESS     The delete was successful.\r
453   @retval EFI_NOT_FOUND   Name was not a map on Handle.\r
454 **/\r
455 EFI_STATUS\r
456 EFIAPI\r
457 PerformSingleMappingDelete(\r
458   IN CONST CHAR16     *Specific,\r
459   IN CONST EFI_HANDLE Handle\r
460   )\r
461 {\r
462   EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
463   EFI_DEVICE_PATH_PROTOCOL  *DevPathCopy;\r
464   CONST CHAR16              *MapList;\r
465   CHAR16                    *CurrentName;\r
466 \r
467   DevPath     = DevicePathFromHandle(Handle);\r
468   DevPathCopy = DevPath;\r
469   MapList     = gEfiShellProtocol->GetMapFromDevicePath(&DevPathCopy);\r
470   CurrentName = NULL;\r
471 \r
472   if (MapList == NULL) {\r
473     return (EFI_NOT_FOUND);\r
474   }\r
475   //\r
476   // if there is a specific and its not on the list...\r
477   //\r
478   if (!SearchList(MapList, Specific, &CurrentName, TRUE, FALSE, L";")) {\r
479     return (EFI_NOT_FOUND);\r
480   }\r
481   return (gEfiShellProtocol->SetMap(NULL, CurrentName));\r
482 }\r
483 \r
484 CONST CHAR16 Cd[] = L"cd*";\r
485 CONST CHAR16 Hd[] = L"hd*";\r
486 CONST CHAR16 Fp[] = L"fp*";\r
487 CONST CHAR16 AnyF[] = L"F*";\r
488 /**\r
489   Function to display mapping information to the user.\r
490 \r
491   If Specific is specified then Consist and Normal will be ignored since information will\r
492   be printed for the specific item only.\r
493 \r
494   @param[in] Verbose                TRUE to display (extra) verbose information.\r
495   @param[in] Consist                TRUE to display consistent mappings.\r
496   @param[in] Normal                 TRUE to display normal (not consist) mappings.\r
497   @param[in] TypeString             Pointer to string of filter types.\r
498   @param[in] SFO                    TRUE to display output in Standard Output Format.\r
499   @param[in] Specific               Pointer to string for specific map to display.\r
500   @param[in] Header                 TRUE to print the header block.\r
501 \r
502   @retval SHELL_SUCCESS               The display was printed.\r
503   @retval SHELL_INVALID_PARAMETER     One of Consist or Normal must be TRUE if no Specific.\r
504 \r
505 **/\r
506 SHELL_STATUS\r
507 EFIAPI\r
508 PerformMappingDisplay(\r
509   IN CONST BOOLEAN Verbose,\r
510   IN CONST BOOLEAN Consist,\r
511   IN CONST BOOLEAN Normal,\r
512   IN CONST CHAR16  *TypeString,\r
513   IN CONST BOOLEAN SFO,\r
514   IN CONST CHAR16  *Specific OPTIONAL,\r
515   IN CONST BOOLEAN Header\r
516   )\r
517 {\r
518   EFI_STATUS                Status;\r
519   EFI_HANDLE                *HandleBuffer;\r
520   UINTN                     BufferSize;\r
521   UINTN                     LoopVar;\r
522   CHAR16                    *Test;\r
523   BOOLEAN                   Found;\r
524 \r
525   if (!Consist && !Normal && Specific == NULL && TypeString == NULL) {\r
526     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");  \r
527     return (SHELL_INVALID_PARAMETER);\r
528   }\r
529 \r
530   if (TypeString != NULL) {\r
531     Test = (CHAR16*)Cd;\r
532     if (StrnCmp(TypeString, Test, StrLen(Test)-1) != 0) {\r
533       Test = (CHAR16*)Hd;\r
534       if (StrnCmp(TypeString, Test, StrLen(Test)-1) != 0) {\r
535         Test = (CHAR16*)Fp;\r
536         if (StrnCmp(TypeString, Test, StrLen(Test)-1) != 0) {\r
537           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", TypeString);  \r
538           return (SHELL_INVALID_PARAMETER);\r
539         }\r
540       } else if (Test == NULL) {\r
541         Test = (CHAR16*)AnyF;\r
542       }\r
543     }\r
544   } else {\r
545     Test = NULL;\r
546   }\r
547 \r
548   if (Header) {\r
549     //\r
550     // Print the header\r
551     //\r
552     if (!SFO) {\r
553       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle);\r
554     } else {\r
555       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"map");\r
556     }\r
557   }\r
558 \r
559   BufferSize    = 0;\r
560   HandleBuffer  = NULL;\r
561 \r
562   //\r
563   // Look up all SimpleFileSystems in the platform\r
564   //\r
565   Status = gBS->LocateHandle(\r
566     ByProtocol,\r
567     &gEfiSimpleFileSystemProtocolGuid,\r
568     NULL,\r
569     &BufferSize,\r
570     HandleBuffer);\r
571   if (Status == EFI_BUFFER_TOO_SMALL) {\r
572     HandleBuffer = AllocateZeroPool(BufferSize);\r
573     if (HandleBuffer == NULL) {\r
574       return (SHELL_OUT_OF_RESOURCES);\r
575     }\r
576     Status = gBS->LocateHandle(\r
577       ByProtocol,\r
578       &gEfiSimpleFileSystemProtocolGuid,\r
579       NULL,\r
580       &BufferSize,\r
581       HandleBuffer);\r
582   }\r
583 \r
584   //\r
585   // Get the map name(s) for each one.\r
586   //\r
587   for ( LoopVar = 0, Found = FALSE\r
588       ; LoopVar < (BufferSize / sizeof(EFI_HANDLE)) && HandleBuffer != NULL\r
589       ; LoopVar ++\r
590      ){\r
591     Status = PerformSingleMappingDisplay(\r
592       Verbose,\r
593       Consist,\r
594       Normal,\r
595       Test,\r
596       SFO,\r
597       Specific,\r
598       HandleBuffer[LoopVar]);\r
599     if (!EFI_ERROR(Status)) {\r
600       Found = TRUE;\r
601     }\r
602   }\r
603 \r
604   //\r
605   // Look up all BlockIo in the platform\r
606   //\r
607   Status = gBS->LocateHandle(\r
608     ByProtocol,\r
609     &gEfiBlockIoProtocolGuid,\r
610     NULL,\r
611     &BufferSize,\r
612     HandleBuffer);\r
613   if (Status == EFI_BUFFER_TOO_SMALL) {\r
614     SHELL_FREE_NON_NULL(HandleBuffer);\r
615     HandleBuffer = AllocateZeroPool(BufferSize);\r
616     if (HandleBuffer == NULL) {\r
617       return (SHELL_OUT_OF_RESOURCES);\r
618     }\r
619     Status = gBS->LocateHandle(\r
620       ByProtocol,\r
621       &gEfiBlockIoProtocolGuid,\r
622       NULL,\r
623       &BufferSize,\r
624       HandleBuffer);\r
625   }\r
626   if (!EFI_ERROR(Status) && HandleBuffer != NULL) {\r
627     //\r
628     // Get the map name(s) for each one.\r
629     //\r
630     for ( LoopVar = 0\r
631         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)\r
632         ; LoopVar ++\r
633        ){\r
634       //\r
635       // Skip any that were already done...\r
636       //\r
637       if (gBS->OpenProtocol(\r
638         HandleBuffer[LoopVar],\r
639         &gEfiSimpleFileSystemProtocolGuid,\r
640         NULL,\r
641         gImageHandle,\r
642         NULL,\r
643         EFI_OPEN_PROTOCOL_TEST_PROTOCOL) == EFI_SUCCESS) {\r
644           continue;\r
645       }\r
646       Status = PerformSingleMappingDisplay(\r
647         Verbose,\r
648         Consist,\r
649         Normal,\r
650         Test,\r
651         SFO,\r
652         Specific,\r
653         HandleBuffer[LoopVar]);\r
654       if (!EFI_ERROR(Status)) {\r
655         Found = TRUE;\r
656       }\r
657     }\r
658     FreePool(HandleBuffer);\r
659   }\r
660   if (!Found) {\r
661     if (Specific != NULL) {\r
662       ShellPrintHiiEx(gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", Specific);  \r
663     } else {\r
664       ShellPrintHiiEx(gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"map");  \r
665     }\r
666   }\r
667   return (SHELL_SUCCESS);\r
668 }\r
669 \r
670 /**\r
671   Perform a mapping display and parse for multiple types in the TypeString.\r
672 \r
673   @param[in] Verbose      TRUE to use verbose output.\r
674   @param[in] Consist      TRUE to display consistent names.\r
675   @param[in] Normal       TRUE to display normal names.\r
676   @param[in] TypeString   An optional comma-delimited list of types.\r
677   @param[in] SFO          TRUE to display in SFO format.  See Spec.\r
678   @param[in] Specific     An optional specific map name to display alone.\r
679 \r
680   @retval SHELL_INVALID_PARAMETER   A parameter was invalid.\r
681   @retval SHELL_SUCCESS             The display was successful.\r
682   @sa PerformMappingDisplay\r
683 **/\r
684 SHELL_STATUS\r
685 EFIAPI\r
686 PerformMappingDisplay2(\r
687   IN CONST BOOLEAN Verbose,\r
688   IN CONST BOOLEAN Consist,\r
689   IN CONST BOOLEAN Normal,\r
690   IN CONST CHAR16  *TypeString,\r
691   IN CONST BOOLEAN SFO,\r
692   IN CONST CHAR16  *Specific OPTIONAL\r
693   )\r
694 {\r
695   CONST CHAR16  *TypeWalker;\r
696   SHELL_STATUS  ShellStatus;\r
697   CHAR16        *Comma;\r
698 \r
699 \r
700   if (TypeString == NULL) {\r
701     return (PerformMappingDisplay(Verbose, Consist, Normal, NULL, SFO, Specific, TRUE));\r
702   }\r
703   ShellStatus = SHELL_SUCCESS;\r
704   for (TypeWalker = TypeString ; TypeWalker != NULL && *TypeWalker != CHAR_NULL ;) {\r
705     Comma = StrStr(TypeWalker, L",");\r
706     if (Comma == NULL) {\r
707       if (ShellStatus == SHELL_SUCCESS) {\r
708         ShellStatus = PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
709       } else {\r
710         PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
711       }\r
712       break;\r
713     } else {\r
714       *Comma = CHAR_NULL;\r
715       if (ShellStatus == SHELL_SUCCESS) {\r
716         ShellStatus = PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
717       } else {\r
718         PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
719       }\r
720       *Comma = L',';\r
721       TypeWalker = Comma + 1;\r
722     }\r
723   }\r
724 \r
725   return (ShellStatus);\r
726 }\r
727 \r
728 /**\r
729   Delete a specific map.\r
730 \r
731   @param[in] Specific  The pointer to the name of the map to delete.\r
732 \r
733   @retval EFI_INVALID_PARAMETER     Specific was NULL.\r
734   @retval EFI_SUCCESS               The operation was successful.\r
735   @retval EFI_NOT_FOUND             Specific could not be found.\r
736 **/\r
737 EFI_STATUS\r
738 EFIAPI\r
739 PerformMappingDelete(\r
740   IN CONST CHAR16  *Specific\r
741   )\r
742 {\r
743   EFI_STATUS                Status;\r
744   EFI_HANDLE                *HandleBuffer;\r
745   UINTN                     BufferSize;\r
746   UINTN                     LoopVar;\r
747   BOOLEAN                   Deleted;\r
748 \r
749   if (Specific == NULL) {\r
750     return (EFI_INVALID_PARAMETER);\r
751   }\r
752 \r
753   BufferSize    = 0;\r
754   HandleBuffer  = NULL;\r
755   Deleted       = FALSE;\r
756 \r
757   //\r
758   // Look up all SimpleFileSystems in the platform\r
759   //\r
760   Status = gBS->LocateHandle(\r
761     ByProtocol,\r
762     &gEfiDevicePathProtocolGuid,\r
763     NULL,\r
764     &BufferSize,\r
765     HandleBuffer);\r
766   if (Status == EFI_BUFFER_TOO_SMALL) {\r
767     HandleBuffer = AllocateZeroPool(BufferSize);\r
768     if (HandleBuffer == NULL) {\r
769       return (EFI_OUT_OF_RESOURCES);\r
770     }\r
771     Status = gBS->LocateHandle(\r
772       ByProtocol,\r
773       &gEfiDevicePathProtocolGuid,\r
774       NULL,\r
775       &BufferSize,\r
776       HandleBuffer);\r
777   }\r
778   if (EFI_ERROR(Status)) {\r
779     SHELL_FREE_NON_NULL(HandleBuffer);\r
780     return (Status);\r
781   }\r
782 \r
783   if (HandleBuffer != NULL) {\r
784     //\r
785     // Get the map name(s) for each one.\r
786     //\r
787     for ( LoopVar = 0\r
788         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)\r
789         ; LoopVar ++\r
790        ){\r
791       if (PerformSingleMappingDelete(Specific,HandleBuffer[LoopVar]) == SHELL_SUCCESS) {\r
792           Deleted = TRUE;\r
793       }\r
794     }\r
795   }\r
796   //\r
797   // Look up all BlockIo in the platform\r
798   //\r
799   Status = gBS->LocateHandle(\r
800     ByProtocol,\r
801     &gEfiBlockIoProtocolGuid,\r
802     NULL,\r
803     &BufferSize,\r
804     HandleBuffer);\r
805   if (Status == EFI_BUFFER_TOO_SMALL) {\r
806     FreePool(HandleBuffer);\r
807     HandleBuffer = AllocateZeroPool(BufferSize);\r
808     if (HandleBuffer == NULL) {\r
809       return (EFI_OUT_OF_RESOURCES);\r
810     }\r
811     Status = gBS->LocateHandle(\r
812       ByProtocol,\r
813       &gEfiBlockIoProtocolGuid,\r
814       NULL,\r
815       &BufferSize,\r
816       HandleBuffer);\r
817   }\r
818   if (EFI_ERROR(Status)) {\r
819     SHELL_FREE_NON_NULL(HandleBuffer);\r
820     return (Status);\r
821   }\r
822 \r
823   if (HandleBuffer != NULL) {\r
824     //\r
825     // Get the map name(s) for each one.\r
826     //\r
827     for ( LoopVar = 0\r
828         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)\r
829         ; LoopVar ++\r
830        ){\r
831       //\r
832       // Skip any that were already done...\r
833       //\r
834       if (gBS->OpenProtocol(\r
835         HandleBuffer[LoopVar],\r
836         &gEfiDevicePathProtocolGuid,\r
837         NULL,\r
838         gImageHandle,\r
839         NULL,\r
840         EFI_OPEN_PROTOCOL_TEST_PROTOCOL) == EFI_SUCCESS) {\r
841           continue;\r
842       }\r
843       if (PerformSingleMappingDelete(Specific,HandleBuffer[LoopVar]) == SHELL_SUCCESS) {\r
844           Deleted = TRUE;\r
845       }\r
846     }\r
847   }\r
848   SHELL_FREE_NON_NULL(HandleBuffer);\r
849   if (!Deleted) {\r
850     return (EFI_NOT_FOUND);\r
851   }\r
852   return (EFI_SUCCESS);\r
853 }\r
854 \r
855 /**\r
856   function to add a mapping from mapping.\r
857 \r
858   This function will get the device path associated with the mapping and call SetMap.\r
859 \r
860   @param[in] Map         The Map to add a mapping for\r
861   @param[in] SName       The name of the new mapping\r
862 \r
863   @retval SHELL_SUCCESS             the mapping was added\r
864   @retval SHELL_INVALID_PARAMETER   the device path for Map could not be retrieved.\r
865   @return                           Shell version of a return value from EfiShellProtocol->SetMap\r
866 \r
867 **/\r
868 SHELL_STATUS\r
869 EFIAPI\r
870 AddMappingFromMapping(\r
871   IN CONST CHAR16     *Map,\r
872   IN CONST CHAR16     *SName\r
873   )\r
874 {\r
875   CONST EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
876   EFI_STATUS                      Status;\r
877   CHAR16                          *NewSName;\r
878   \r
879   NewSName = AllocateCopyPool(StrSize(SName) + sizeof(CHAR16), SName);\r
880   if (NewSName == NULL) {\r
881     return (SHELL_OUT_OF_RESOURCES);\r
882   }\r
883   if (NewSName[StrLen(NewSName)-1] != L':') {\r
884     StrnCat(NewSName, L":", 2);\r
885   }\r
886 \r
887   if (!IsNumberLetterOnly(NewSName, StrLen(NewSName)-1)) {\r
888     FreePool(NewSName);\r
889     return (SHELL_INVALID_PARAMETER);\r
890   }\r
891 \r
892   DevPath = gEfiShellProtocol->GetDevicePathFromMap(Map);\r
893   if (DevPath == NULL) {\r
894     FreePool(NewSName);\r
895     return (SHELL_INVALID_PARAMETER);\r
896   }\r
897 \r
898   Status = gEfiShellProtocol->SetMap(DevPath, NewSName);\r
899   FreePool(NewSName);\r
900   if (EFI_ERROR(Status)) {\r
901     return (SHELL_DEVICE_ERROR);\r
902   }\r
903   return (SHELL_SUCCESS);\r
904 }\r
905 \r
906 /**\r
907   function to add a mapping from an EFI_HANDLE.\r
908 \r
909   This function will get the device path associated with the Handle and call SetMap.\r
910 \r
911   @param[in] Handle       The handle to add a mapping for\r
912   @param[in] SName        The name of the new mapping\r
913 \r
914   @retval SHELL_SUCCESS           the mapping was added\r
915   @retval SHELL_INVALID_PARAMETER SName was not valid for a map name.\r
916   @return                         Shell version of a return value from either\r
917                                   gBS->OpenProtocol or EfiShellProtocol->SetMap\r
918 \r
919 **/\r
920 SHELL_STATUS\r
921 EFIAPI\r
922 AddMappingFromHandle(\r
923   IN CONST EFI_HANDLE Handle,\r
924   IN CONST CHAR16     *SName\r
925   )\r
926 {\r
927   EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
928   EFI_STATUS                Status;\r
929   CHAR16                    *NewSName;\r
930   \r
931   NewSName = AllocateCopyPool(StrSize(SName) + sizeof(CHAR16), SName);\r
932   if (NewSName == NULL) {\r
933     return (SHELL_OUT_OF_RESOURCES);\r
934   }\r
935   if (NewSName[StrLen(NewSName)-1] != L':') {\r
936     StrnCat(NewSName, L":", 2);\r
937   }\r
938 \r
939   if (!IsNumberLetterOnly(NewSName, StrLen(NewSName)-1)) {\r
940     FreePool(NewSName);\r
941     return (SHELL_INVALID_PARAMETER);\r
942   }\r
943 \r
944   Status = gBS->OpenProtocol(\r
945     Handle,\r
946     &gEfiDevicePathProtocolGuid,\r
947     (VOID**)&DevPath,\r
948     gImageHandle,\r
949     NULL,\r
950     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
951    );\r
952   if (EFI_ERROR(Status)) {\r
953     FreePool(NewSName);\r
954     return (SHELL_DEVICE_ERROR);\r
955   }\r
956   Status = gEfiShellProtocol->SetMap(DevPath, NewSName);\r
957   FreePool(NewSName);\r
958   if (EFI_ERROR(Status)) {\r
959     return (SHELL_DEVICE_ERROR);\r
960   }\r
961   return (SHELL_SUCCESS);\r
962 }\r
963 \r
964 STATIC CONST SHELL_PARAM_ITEM MapParamList[] = {\r
965   {L"-d", TypeValue},\r
966   {L"-r", TypeFlag},\r
967   {L"-v", TypeFlag},\r
968   {L"-c", TypeFlag},\r
969   {L"-f", TypeFlag},\r
970   {L"-u", TypeFlag},\r
971   {L"-t", TypeValue},\r
972   {L"-sfo", TypeValue},\r
973   {NULL, TypeMax}\r
974   };\r
975 \r
976 /**\r
977   Function for 'map' command.\r
978 \r
979   @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
980   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
981 **/\r
982 SHELL_STATUS\r
983 EFIAPI\r
984 ShellCommandRunMap (\r
985   IN EFI_HANDLE        ImageHandle,\r
986   IN EFI_SYSTEM_TABLE  *SystemTable\r
987   )\r
988 {\r
989   EFI_STATUS    Status;\r
990   LIST_ENTRY    *Package;\r
991   CHAR16        *ProblemParam;\r
992   CONST CHAR16  *SName;\r
993   CONST CHAR16  *Mapping;\r
994   EFI_HANDLE    MapAsHandle;\r
995   SHELL_STATUS  ShellStatus;\r
996   BOOLEAN       SfoMode;\r
997   BOOLEAN       ConstMode;\r
998   BOOLEAN       NormlMode;\r
999   CONST CHAR16  *Param1;\r
1000   CONST CHAR16  *TypeString;\r
1001   UINTN         TempStringLength;\r
1002 \r
1003   ProblemParam  = NULL;\r
1004   Mapping       = NULL;\r
1005   SName         = NULL;\r
1006   ShellStatus   = SHELL_SUCCESS;\r
1007   MapAsHandle = NULL;\r
1008 \r
1009   //\r
1010   // initialize the shell lib (we must be in non-auto-init...)\r
1011   //\r
1012   Status = ShellInitialize();\r
1013   ASSERT_EFI_ERROR(Status);\r
1014 \r
1015   Status = CommandInit();\r
1016   ASSERT_EFI_ERROR(Status);\r
1017 \r
1018   //\r
1019   // parse the command line\r
1020   //\r
1021   Status = ShellCommandLineParse (MapParamList, &Package, &ProblemParam, TRUE);\r
1022   if (EFI_ERROR(Status)) {\r
1023     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
1024       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"map", ProblemParam);  \r
1025       FreePool(ProblemParam);\r
1026       ShellStatus = SHELL_INVALID_PARAMETER;\r
1027     } else {\r
1028       ASSERT(FALSE);\r
1029     }\r
1030   } else {\r
1031     //\r
1032     // check for "-?"\r
1033     //\r
1034     SfoMode   = ShellCommandLineGetFlag(Package, L"-sfo");\r
1035     ConstMode = ShellCommandLineGetFlag(Package, L"-c");\r
1036     NormlMode = ShellCommandLineGetFlag(Package, L"-f");\r
1037     if (ShellCommandLineGetFlag(Package, L"-?")) {\r
1038       ASSERT(FALSE);\r
1039     } else if (ShellCommandLineGetRawValue(Package, 3) != NULL) {\r
1040       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"map");  \r
1041       ShellStatus = SHELL_INVALID_PARAMETER;\r
1042     } else {\r
1043       //\r
1044       // Deleting a map name...\r
1045       //\r
1046       if (ShellCommandLineGetFlag(Package, L"-d")) {\r
1047         if ( ShellCommandLineGetFlag(Package, L"-r")\r
1048           || ShellCommandLineGetFlag(Package, L"-v")\r
1049           || ConstMode\r
1050           || NormlMode\r
1051           || ShellCommandLineGetFlag(Package, L"-u")\r
1052           || ShellCommandLineGetFlag(Package, L"-t")\r
1053          ){\r
1054           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"map");  \r
1055           ShellStatus = SHELL_INVALID_PARAMETER;\r
1056         } else {\r
1057           SName = ShellCommandLineGetValue(Package, L"-d");\r
1058           if (SName != NULL) {\r
1059             Status = PerformMappingDelete(SName);\r
1060             if (EFI_ERROR(Status)) {\r
1061               if (Status == EFI_ACCESS_DENIED) {\r
1062                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");  \r
1063                 ShellStatus = SHELL_ACCESS_DENIED;\r
1064               } else if (Status == EFI_NOT_FOUND) {\r
1065                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", SName);  \r
1066                 ShellStatus = SHELL_INVALID_PARAMETER;\r
1067               } else {\r
1068                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);  \r
1069                 ShellStatus = SHELL_UNSUPPORTED;\r
1070               }\r
1071             }\r
1072           } else {\r
1073             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");  \r
1074             ShellStatus = SHELL_INVALID_PARAMETER;\r
1075           }\r
1076         }\r
1077       } else if ( ShellCommandLineGetFlag(Package, L"-r")\r
1078 //               || ShellCommandLineGetFlag(Package, L"-v")\r
1079                || ConstMode\r
1080                || NormlMode\r
1081                || ShellCommandLineGetFlag(Package, L"-u")\r
1082                || ShellCommandLineGetFlag(Package, L"-t")\r
1083               ){\r
1084         if ( ShellCommandLineGetFlag(Package, L"-r")) {\r
1085           //\r
1086           // Do the reset\r
1087           //\r
1088           Status = ShellCommandCreateInitialMappingsAndPaths();\r
1089           if (EFI_ERROR(Status)) {\r
1090             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);  \r
1091             ShellStatus = SHELL_UNSUPPORTED;\r
1092           }\r
1093         }\r
1094         if ( ShellStatus == SHELL_SUCCESS && ShellCommandLineGetFlag(Package, L"-u")) {\r
1095           //\r
1096           // Do the Update\r
1097           //\r
1098           Status = ShellCommandUpdateMapping ();\r
1099           if (EFI_ERROR(Status)) {\r
1100             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);  \r
1101             ShellStatus = SHELL_UNSUPPORTED;\r
1102           }\r
1103         }\r
1104         if (ShellStatus == SHELL_SUCCESS) {\r
1105           Param1 = ShellCommandLineGetRawValue(Package, 1);\r
1106           TypeString = ShellCommandLineGetValue(Package, L"-t");\r
1107           if (!ConstMode\r
1108             &&!NormlMode\r
1109             &&TypeString  == NULL\r
1110             ) {\r
1111             //\r
1112             // now do the display...\r
1113             //\r
1114             ShellStatus = PerformMappingDisplay(\r
1115               ShellCommandLineGetFlag(Package, L"-v"),\r
1116               TRUE,\r
1117               TRUE,\r
1118               NULL,\r
1119               SfoMode,\r
1120               Param1,\r
1121               TRUE\r
1122              );\r
1123           } else {\r
1124             //\r
1125             // now do the display...\r
1126             //\r
1127             ShellStatus = PerformMappingDisplay2(\r
1128               ShellCommandLineGetFlag(Package, L"-v"),\r
1129               ConstMode,\r
1130               NormlMode,\r
1131               TypeString,\r
1132               SfoMode,\r
1133               Param1\r
1134              );\r
1135           }\r
1136         }\r
1137       } else {\r
1138         //\r
1139         // adding or displaying (there were no flags)\r
1140         //\r
1141         SName = ShellCommandLineGetRawValue(Package, 1);\r
1142         Mapping = ShellCommandLineGetRawValue(Package, 2);\r
1143         if ( SName == NULL\r
1144           && Mapping == NULL\r
1145          ){\r
1146           //\r
1147           // display only since no flags\r
1148           //\r
1149           ShellStatus = PerformMappingDisplay(\r
1150             ShellCommandLineGetFlag(Package, L"-v"),\r
1151             TRUE,\r
1152             TRUE,\r
1153             NULL,\r
1154             SfoMode,\r
1155             NULL,\r
1156             TRUE\r
1157            );\r
1158         } else if ( SName == NULL\r
1159           || Mapping == NULL\r
1160          ){\r
1161             //\r
1162             // Display only the one specified\r
1163             //\r
1164           ShellStatus = PerformMappingDisplay(\r
1165             FALSE,\r
1166             FALSE,\r
1167             FALSE,\r
1168             NULL,\r
1169             SfoMode,\r
1170             SName, // note the variable here...\r
1171             TRUE\r
1172            );\r
1173         } else {\r
1174           if (ShellIsHexOrDecimalNumber(Mapping, TRUE, FALSE)) {\r
1175             MapAsHandle = ConvertHandleIndexToHandle(ShellStrToUintn(Mapping));\r
1176           } else {\r
1177             MapAsHandle = NULL;\r
1178           }\r
1179           if (MapAsHandle == NULL && Mapping[StrLen(Mapping)-1] != L':') {\r
1180             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);  \r
1181             ShellStatus = SHELL_INVALID_PARAMETER;\r
1182           } else {\r
1183             if (MapAsHandle != NULL) {\r
1184               TempStringLength = StrLen(SName);\r
1185               if (!IsNumberLetterOnly(SName, TempStringLength-(SName[TempStringLength-1]==L':'?1:0))) {\r
1186                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", SName);\r
1187                 ShellStatus = SHELL_INVALID_PARAMETER;\r
1188               } else {\r
1189                 ShellStatus = AddMappingFromHandle(MapAsHandle, SName);\r
1190               }\r
1191             } else {\r
1192               TempStringLength = StrLen(SName);\r
1193               if (!IsNumberLetterOnly(SName, TempStringLength-(SName[TempStringLength-1]==L':'?1:0))) {\r
1194                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", SName);\r
1195                 ShellStatus = SHELL_INVALID_PARAMETER;\r
1196               } else {\r
1197                 ShellStatus = AddMappingFromMapping(Mapping, SName);\r
1198               }\r
1199             }\r
1200             if (ShellStatus != SHELL_SUCCESS) {\r
1201               switch (ShellStatus) {\r
1202                 case SHELL_ACCESS_DENIED:\r
1203                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");\r
1204                   break;\r
1205                 case SHELL_INVALID_PARAMETER:\r
1206                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);\r
1207                   break;\r
1208                 case SHELL_DEVICE_ERROR:\r
1209                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, L"map", Mapping);\r
1210                   break;\r
1211                 default:\r
1212                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", ShellStatus|MAX_BIT);\r
1213               }\r
1214             } else {\r
1215               //\r
1216               // now do the display...\r
1217               //\r
1218               ShellStatus = PerformMappingDisplay(\r
1219                 FALSE,\r
1220                 FALSE,\r
1221                 FALSE,\r
1222                 NULL,\r
1223                 SfoMode,\r
1224                 SName,\r
1225                 TRUE\r
1226                );\r
1227             } // we were sucessful so do an output\r
1228           } // got a valid map target\r
1229         } // got 2 variables\r
1230       } // we are adding a mapping\r
1231     } // got valid parameters\r
1232   }\r
1233 \r
1234   //\r
1235   // free the command line package\r
1236   //\r
1237   ShellCommandLineFreeVarList (Package);\r
1238 \r
1239   return (ShellStatus);\r
1240 }\r
1241 \r