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