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