add comments to function declarations and definitions and updated to match coding...
[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"AnyF*",   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   TempSpot = StrStr(CurrentName, L";");\r
418   if (TempSpot != NULL) {\r
419     *TempSpot = CHAR_NULL;\r
420   }\r
421   DevPathString = gDevPathToText->ConvertDevicePathToText(DevPath, TRUE, FALSE);\r
422   if (!SFO) {\r
423     TempLen = StrLen(CurrentName);\r
424     ShellPrintHiiEx (\r
425       -1,\r
426       -1,\r
427       NULL,\r
428       STRING_TOKEN (STR_MAP_ENTRY),\r
429       gShellLevel2HiiHandle,\r
430       CurrentName,\r
431       TempLen < StrLen(MapList)?MapList + TempLen+1:L"",\r
432       DevPathString\r
433      );\r
434     if (Verbose) {\r
435       //\r
436       // also print handle, media type, removable (y/n), and current directory\r
437       //\r
438       MediaType = GetDeviceMediaType(DevPath);\r
439       if ((TypeString != NULL &&MediaType != NULL && StrStr(TypeString, MediaType) != NULL) || TypeString == NULL) {\r
440         Removable = IsRemoveableDevice(DevPath);\r
441         TempSpot2 = ShellGetCurrentDir(CurrentName);\r
442         ShellPrintHiiEx (\r
443           -1,\r
444           -1,\r
445           NULL,\r
446           STRING_TOKEN (STR_MAP_ENTRY_VERBOSE),\r
447           gShellLevel2HiiHandle,\r
448           ConvertHandleToHandleIndex(Handle),\r
449           MediaType,\r
450           Removable?L"Yes":L"No",\r
451           TempSpot2\r
452          );\r
453       }\r
454       FreePool(MediaType);\r
455     }\r
456   } else {\r
457     TempLen = StrLen(CurrentName);\r
458     ShellPrintHiiEx (\r
459       -1,\r
460       -1,\r
461       NULL,\r
462       STRING_TOKEN (STR_MAP_SFO_MAPPINGS),\r
463       gShellLevel2HiiHandle,\r
464       CurrentName,\r
465       DevPathString,\r
466       TempLen < StrLen(MapList)?MapList + TempLen+1:L""\r
467      );\r
468   }\r
469   FreePool(DevPathString);\r
470   FreePool(CurrentName);\r
471   return EFI_SUCCESS;\r
472 }\r
473 \r
474 /**\r
475   Delete Specific from the list of maps for device Handle.\r
476 \r
477   @param[in] Specific   The name to delete.\r
478   @param[in] Handle     The device to look on.\r
479 \r
480   @retval EFI_SUCCESS     The delete was successful.\r
481   @retval EFI_NOT_FOUND   Name was not a map on Handle.\r
482 **/\r
483 EFI_STATUS\r
484 EFIAPI\r
485 PerformSingleMappingDelete(\r
486   IN CONST CHAR16     *Specific,\r
487   IN CONST EFI_HANDLE Handle\r
488   )\r
489 {\r
490   EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
491   EFI_DEVICE_PATH_PROTOCOL  *DevPathCopy;\r
492   CONST CHAR16              *MapList;\r
493   CHAR16                    *CurrentName;\r
494 \r
495   DevPath     = DevicePathFromHandle(Handle);\r
496   DevPathCopy = DevPath;\r
497   MapList     = gEfiShellProtocol->GetMapFromDevicePath(&DevPathCopy);\r
498   CurrentName = NULL;\r
499 \r
500   if (MapList == NULL) {\r
501     return (EFI_NOT_FOUND);\r
502   }\r
503   //\r
504   // if there is a specific and its not on the list...\r
505   //\r
506   if (!SearchList(MapList, Specific, &CurrentName, TRUE, FALSE, L";")) {\r
507     return (EFI_NOT_FOUND);\r
508   }\r
509   return (gEfiShellProtocol->SetMap(NULL, CurrentName));\r
510 }\r
511 \r
512 CONST CHAR16 Cd[] = L"cd*";\r
513 CONST CHAR16 Hd[] = L"hd*";\r
514 CONST CHAR16 Fp[] = L"fp*";\r
515 CONST CHAR16 AnyF[] = L"F*";\r
516 /**\r
517   Function to display mapping information to the user.\r
518 \r
519   If Specific is specified then Consist and Normal will be ignored since information will\r
520   be printed for the specific item only.\r
521 \r
522   @param[in] Verbose                TRUE to display (extra) verbose information.\r
523   @param[in] Consist                TRUE to display consistent mappings.\r
524   @param[in] Normal                 TRUE to display normal (not consist) mappings.\r
525   @param[in] TypeString             Pointer to string of filter types.\r
526   @param[in] SFO                    TRUE to display output in Standard Output Format.\r
527   @param[in] Specific               Pointer to string for specific map to display.\r
528   @param[in] Header                 TRUE to print the header block.\r
529 \r
530   @retval SHELL_SUCCESS               The display was printed.\r
531   @retval SHELL_INVALID_PARAMETER     One of Consist or Normal must be TRUE if no Specific.\r
532 \r
533 **/\r
534 SHELL_STATUS\r
535 EFIAPI\r
536 PerformMappingDisplay(\r
537   IN CONST BOOLEAN Verbose,\r
538   IN CONST BOOLEAN Consist,\r
539   IN CONST BOOLEAN Normal,\r
540   IN CONST CHAR16  *TypeString,\r
541   IN CONST BOOLEAN SFO,\r
542   IN CONST CHAR16  *Specific OPTIONAL,\r
543   IN CONST BOOLEAN Header\r
544   )\r
545 {\r
546   EFI_STATUS                Status;\r
547   EFI_HANDLE                *HandleBuffer;\r
548   UINTN                     BufferSize;\r
549   UINTN                     LoopVar;\r
550   CHAR16                    *Test;\r
551   BOOLEAN                   Found;\r
552 \r
553   if (!Consist && !Normal && Specific == NULL && TypeString == NULL) {\r
554     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle);\r
555     return (SHELL_INVALID_PARAMETER);\r
556   }\r
557 \r
558   if (TypeString != NULL) {\r
559     Test = (CHAR16*)Cd;\r
560     if (StrnCmp(TypeString, Test, StrLen(Test)-1) != 0) {\r
561       Test = (CHAR16*)Hd;\r
562       if (StrnCmp(TypeString, Test, StrLen(Test)-1) != 0) {\r
563         Test = (CHAR16*)Fp;\r
564         if (StrnCmp(TypeString, Test, StrLen(Test)-1) != 0) {\r
565           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, TypeString);\r
566           return (SHELL_INVALID_PARAMETER);\r
567         }\r
568       } else if (Test == NULL) {\r
569         Test = (CHAR16*)AnyF;\r
570       }\r
571     }\r
572   } else {\r
573     Test = NULL;\r
574   }\r
575 \r
576   if (Header) {\r
577     //\r
578     // Print the header\r
579     //\r
580     if (!SFO) {\r
581       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle);\r
582     } else {\r
583       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"map");\r
584     }\r
585   }\r
586 \r
587   BufferSize    = 0;\r
588   HandleBuffer  = NULL;\r
589 \r
590   //\r
591   // Look up all SimpleFileSystems in the platform\r
592   //\r
593   Status = gBS->LocateHandle(\r
594     ByProtocol,\r
595     &gEfiSimpleFileSystemProtocolGuid,\r
596     NULL,\r
597     &BufferSize,\r
598     HandleBuffer);\r
599   if (Status == EFI_BUFFER_TOO_SMALL) {\r
600     HandleBuffer = AllocateZeroPool(BufferSize);\r
601     if (HandleBuffer == NULL) {\r
602       return (SHELL_OUT_OF_RESOURCES);\r
603     }\r
604     Status = gBS->LocateHandle(\r
605       ByProtocol,\r
606       &gEfiSimpleFileSystemProtocolGuid,\r
607       NULL,\r
608       &BufferSize,\r
609       HandleBuffer);\r
610   }\r
611 \r
612   //\r
613   // Get the map name(s) for each one.\r
614   //\r
615   for ( LoopVar = 0, Found = FALSE\r
616       ; LoopVar < (BufferSize / sizeof(EFI_HANDLE)) && HandleBuffer != NULL\r
617       ; LoopVar ++\r
618      ){\r
619     Status = PerformSingleMappingDisplay(\r
620       Verbose,\r
621       Consist,\r
622       Normal,\r
623       Test,\r
624       SFO,\r
625       Specific,\r
626       HandleBuffer[LoopVar]);\r
627     if (!EFI_ERROR(Status)) {\r
628       Found = TRUE;\r
629     }\r
630   }\r
631 \r
632   //\r
633   // Look up all BlockIo in the platform\r
634   //\r
635   Status = gBS->LocateHandle(\r
636     ByProtocol,\r
637     &gEfiBlockIoProtocolGuid,\r
638     NULL,\r
639     &BufferSize,\r
640     HandleBuffer);\r
641   if (Status == EFI_BUFFER_TOO_SMALL) {\r
642     SHELL_FREE_NON_NULL(HandleBuffer);\r
643     HandleBuffer = AllocateZeroPool(BufferSize);\r
644     if (HandleBuffer == NULL) {\r
645       return (SHELL_OUT_OF_RESOURCES);\r
646     }\r
647     Status = gBS->LocateHandle(\r
648       ByProtocol,\r
649       &gEfiBlockIoProtocolGuid,\r
650       NULL,\r
651       &BufferSize,\r
652       HandleBuffer);\r
653   }\r
654   if (!EFI_ERROR(Status) && HandleBuffer != NULL) {\r
655     //\r
656     // Get the map name(s) for each one.\r
657     //\r
658     for ( LoopVar = 0\r
659         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)\r
660         ; LoopVar ++\r
661        ){\r
662       //\r
663       // Skip any that were already done...\r
664       //\r
665       if (gBS->OpenProtocol(\r
666         HandleBuffer[LoopVar],\r
667         &gEfiSimpleFileSystemProtocolGuid,\r
668         NULL,\r
669         gImageHandle,\r
670         NULL,\r
671         EFI_OPEN_PROTOCOL_TEST_PROTOCOL) == EFI_SUCCESS) {\r
672           continue;\r
673       }\r
674       Status = PerformSingleMappingDisplay(\r
675         Verbose,\r
676         Consist,\r
677         Normal,\r
678         Test,\r
679         SFO,\r
680         Specific,\r
681         HandleBuffer[LoopVar]);\r
682       if (!EFI_ERROR(Status)) {\r
683         Found = TRUE;\r
684       }\r
685     }\r
686     FreePool(HandleBuffer);\r
687   }\r
688   if (!Found) {\r
689     ShellPrintHiiEx(gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, Specific);\r
690   }\r
691   return (SHELL_SUCCESS);\r
692 }\r
693 \r
694 /**\r
695   Perform a mapping display and parse for multiple types in the TypeString.\r
696 \r
697   @param[in] Verbose      TRUE to use verbose output.\r
698   @param[in] Consist      TRUE to display consistent names.\r
699   @param[in] Normal       TRUE to display normal names.\r
700   @param[in] TypeString   An optional comma-delimited list of types.\r
701   @param[in] SFO          TRUE to display in SFO format.  See Spec.\r
702   @param[in] Specific     An optional specific map name to display alone.\r
703 \r
704   @retval SHELL_INVALID_PARAMETER   A parameter was invalid.\r
705   @retval SHELL_SUCCESS             The display was successful.\r
706   @sa PerformMappingDisplay\r
707 **/\r
708 SHELL_STATUS\r
709 EFIAPI\r
710 PerformMappingDisplay2(\r
711   IN CONST BOOLEAN Verbose,\r
712   IN CONST BOOLEAN Consist,\r
713   IN CONST BOOLEAN Normal,\r
714   IN CONST CHAR16  *TypeString,\r
715   IN CONST BOOLEAN SFO,\r
716   IN CONST CHAR16  *Specific OPTIONAL\r
717   )\r
718 {\r
719   CONST CHAR16  *TypeWalker;\r
720   SHELL_STATUS  ShellStatus;\r
721   CHAR16        *Comma;\r
722 \r
723 \r
724   if (TypeString == NULL) {\r
725     return (PerformMappingDisplay(Verbose, Consist, Normal, NULL, SFO, Specific, TRUE));\r
726   }\r
727   ShellStatus = SHELL_SUCCESS;\r
728   for (TypeWalker = TypeString ; TypeWalker != NULL && *TypeWalker != CHAR_NULL ;) {\r
729     Comma = StrStr(TypeWalker, L",");\r
730     if (Comma == NULL) {\r
731       if (ShellStatus == SHELL_SUCCESS) {\r
732         ShellStatus = PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
733       } else {\r
734         PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
735       }\r
736       break;\r
737     } else {\r
738       *Comma = CHAR_NULL;\r
739       if (ShellStatus == SHELL_SUCCESS) {\r
740         ShellStatus = PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
741       } else {\r
742         PerformMappingDisplay(Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
743       }\r
744       *Comma = L',';\r
745       TypeWalker = Comma + 1;\r
746     }\r
747   }\r
748 \r
749   return (ShellStatus);\r
750 }\r
751 \r
752 /**\r
753   Delete a specific map.\r
754 \r
755   @param[in] Specific  The pointer to the name of the map to delete.\r
756 \r
757   @retval EFI_INVALID_PARAMETER     Specific was NULL.\r
758   @retval EFI_SUCCESS               The operation was successful.\r
759   @retval EFI_NOT_FOUND             Specific could not be found.\r
760 **/\r
761 EFI_STATUS\r
762 EFIAPI\r
763 PerformMappingDelete(\r
764   IN CONST CHAR16  *Specific\r
765   )\r
766 {\r
767   EFI_STATUS                Status;\r
768   EFI_HANDLE                *HandleBuffer;\r
769   UINTN                     BufferSize;\r
770   UINTN                     LoopVar;\r
771   BOOLEAN                   Deleted;\r
772 \r
773   if (Specific == NULL) {\r
774     return (EFI_INVALID_PARAMETER);\r
775   }\r
776 \r
777   BufferSize    = 0;\r
778   HandleBuffer  = NULL;\r
779   Deleted       = FALSE;\r
780 \r
781   //\r
782   // Look up all SimpleFileSystems in the platform\r
783   //\r
784   Status = gBS->LocateHandle(\r
785     ByProtocol,\r
786     &gEfiDevicePathProtocolGuid,\r
787     NULL,\r
788     &BufferSize,\r
789     HandleBuffer);\r
790   if (Status == EFI_BUFFER_TOO_SMALL) {\r
791     HandleBuffer = AllocateZeroPool(BufferSize);\r
792     if (HandleBuffer == NULL) {\r
793       return (EFI_OUT_OF_RESOURCES);\r
794     }\r
795     Status = gBS->LocateHandle(\r
796       ByProtocol,\r
797       &gEfiDevicePathProtocolGuid,\r
798       NULL,\r
799       &BufferSize,\r
800       HandleBuffer);\r
801   }\r
802   if (EFI_ERROR(Status)) {\r
803     SHELL_FREE_NON_NULL(HandleBuffer);\r
804     return (Status);\r
805   }\r
806 \r
807   if (HandleBuffer != NULL) {\r
808     //\r
809     // Get the map name(s) for each one.\r
810     //\r
811     for ( LoopVar = 0\r
812         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)\r
813         ; LoopVar ++\r
814        ){\r
815       if (PerformSingleMappingDelete(Specific,HandleBuffer[LoopVar]) == SHELL_SUCCESS) {\r
816           Deleted = TRUE;\r
817       }\r
818     }\r
819   }\r
820   //\r
821   // Look up all BlockIo in the platform\r
822   //\r
823   Status = gBS->LocateHandle(\r
824     ByProtocol,\r
825     &gEfiBlockIoProtocolGuid,\r
826     NULL,\r
827     &BufferSize,\r
828     HandleBuffer);\r
829   if (Status == EFI_BUFFER_TOO_SMALL) {\r
830     FreePool(HandleBuffer);\r
831     HandleBuffer = AllocateZeroPool(BufferSize);\r
832     if (HandleBuffer == NULL) {\r
833       return (EFI_OUT_OF_RESOURCES);\r
834     }\r
835     Status = gBS->LocateHandle(\r
836       ByProtocol,\r
837       &gEfiBlockIoProtocolGuid,\r
838       NULL,\r
839       &BufferSize,\r
840       HandleBuffer);\r
841   }\r
842   if (EFI_ERROR(Status)) {\r
843     SHELL_FREE_NON_NULL(HandleBuffer);\r
844     return (Status);\r
845   }\r
846 \r
847   if (HandleBuffer != NULL) {\r
848     //\r
849     // Get the map name(s) for each one.\r
850     //\r
851     for ( LoopVar = 0\r
852         ; LoopVar < BufferSize / sizeof(EFI_HANDLE)\r
853         ; LoopVar ++\r
854        ){\r
855       //\r
856       // Skip any that were already done...\r
857       //\r
858       if (gBS->OpenProtocol(\r
859         HandleBuffer[LoopVar],\r
860         &gEfiDevicePathProtocolGuid,\r
861         NULL,\r
862         gImageHandle,\r
863         NULL,\r
864         EFI_OPEN_PROTOCOL_TEST_PROTOCOL) == EFI_SUCCESS) {\r
865           continue;\r
866       }\r
867       if (PerformSingleMappingDelete(Specific,HandleBuffer[LoopVar]) == SHELL_SUCCESS) {\r
868           Deleted = TRUE;\r
869       }\r
870     }\r
871   }\r
872   SHELL_FREE_NON_NULL(HandleBuffer);\r
873   if (!Deleted) {\r
874     return (EFI_NOT_FOUND);\r
875   }\r
876   return (EFI_SUCCESS);\r
877 }\r
878 \r
879 /**\r
880   function to add a mapping from mapping.\r
881 \r
882   This function will get the device path associated with the mapping and call SetMap.\r
883 \r
884   @param[in] Map         The Map to add a mapping for\r
885   @param[in] SName       The name of the new mapping\r
886 \r
887   @retval SHELL_SUCCESS             the mapping was added\r
888   @retval SHELL_INVALID_PARAMETER   the device path for Map could not be retrieved.\r
889   @return                           Shell version of a return value from EfiShellProtocol->SetMap\r
890 \r
891 **/\r
892 SHELL_STATUS\r
893 EFIAPI\r
894 AddMappingFromMapping(\r
895   IN CONST CHAR16     *Map,\r
896   IN CONST CHAR16     *SName\r
897   )\r
898 {\r
899   CONST EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
900   EFI_STATUS                      Status;\r
901   CHAR16                          *NewSName;\r
902   \r
903   NewSName = AllocateZeroPool(StrSize(SName) + sizeof(CHAR16));\r
904   if (NewSName == NULL) {\r
905     return (SHELL_OUT_OF_RESOURCES);\r
906   }\r
907   StrCpy(NewSName, SName);\r
908   if (NewSName[StrLen(NewSName)-1] != L':') {\r
909     StrCat(NewSName, L":");\r
910   }\r
911 \r
912   if (!IsNumberLetterOnly(NewSName, StrLen(NewSName)-1)) {\r
913     FreePool(NewSName);\r
914     return (SHELL_INVALID_PARAMETER);\r
915   }\r
916 \r
917   DevPath = gEfiShellProtocol->GetDevicePathFromMap(Map);\r
918   if (DevPath == NULL) {\r
919     FreePool(NewSName);\r
920     return (SHELL_INVALID_PARAMETER);\r
921   }\r
922 \r
923   Status = gEfiShellProtocol->SetMap(DevPath, NewSName);\r
924   FreePool(NewSName);\r
925   if (EFI_ERROR(Status)) {\r
926     return (SHELL_DEVICE_ERROR);\r
927   }\r
928   return (SHELL_SUCCESS);\r
929 }\r
930 \r
931 /**\r
932   function to add a mapping from an EFI_HANDLE.\r
933 \r
934   This function will get the device path associated with the Handle and call SetMap.\r
935 \r
936   @param[in] Handle       The handle to add a mapping for\r
937   @param[in] SName        The name of the new mapping\r
938 \r
939   @retval SHELL_SUCCESS           the mapping was added\r
940   @retval SHELL_INVALID_PARAMETER SName was not valid for a map name.\r
941   @return                         Shell version of a return value from either\r
942                                   gBS->OpenProtocol or EfiShellProtocol->SetMap\r
943 \r
944 **/\r
945 SHELL_STATUS\r
946 EFIAPI\r
947 AddMappingFromHandle(\r
948   IN CONST EFI_HANDLE Handle,\r
949   IN CONST CHAR16     *SName\r
950   )\r
951 {\r
952   EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
953   EFI_STATUS                Status;\r
954   CHAR16                    *NewSName;\r
955   \r
956   NewSName = AllocateZeroPool(StrSize(SName) + sizeof(CHAR16));\r
957   if (NewSName == NULL) {\r
958     return (SHELL_OUT_OF_RESOURCES);\r
959   }\r
960   StrCpy(NewSName, SName);\r
961   if (NewSName[StrLen(NewSName)-1] != L':') {\r
962     StrCat(NewSName, L":");\r
963   }\r
964 \r
965   if (!IsNumberLetterOnly(NewSName, StrLen(NewSName)-1)) {\r
966     FreePool(NewSName);\r
967     return (SHELL_INVALID_PARAMETER);\r
968   }\r
969 \r
970   Status = gBS->OpenProtocol(\r
971     Handle,\r
972     &gEfiDevicePathProtocolGuid,\r
973     (VOID**)&DevPath,\r
974     gImageHandle,\r
975     NULL,\r
976     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
977    );\r
978   if (EFI_ERROR(Status)) {\r
979     FreePool(NewSName);\r
980     return (SHELL_DEVICE_ERROR);\r
981   }\r
982   Status = gEfiShellProtocol->SetMap(DevPath, NewSName);\r
983   FreePool(NewSName);\r
984   if (EFI_ERROR(Status)) {\r
985     return (SHELL_DEVICE_ERROR);\r
986   }\r
987   return (SHELL_SUCCESS);\r
988 }\r
989 \r
990 STATIC CONST SHELL_PARAM_ITEM MapParamList[] = {\r
991   {L"-d", TypeValue},\r
992   {L"-r", TypeFlag},\r
993   {L"-v", TypeFlag},\r
994   {L"-c", TypeFlag},\r
995   {L"-f", TypeFlag},\r
996   {L"-u", TypeFlag},\r
997   {L"-t", TypeValue},\r
998   {L"-sfo", TypeValue},\r
999   {NULL, TypeMax}\r
1000   };\r
1001 \r
1002 /**\r
1003   Function for 'map' command.\r
1004 \r
1005   @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
1006   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
1007 **/\r
1008 SHELL_STATUS\r
1009 EFIAPI\r
1010 ShellCommandRunMap (\r
1011   IN EFI_HANDLE        ImageHandle,\r
1012   IN EFI_SYSTEM_TABLE  *SystemTable\r
1013   )\r
1014 {\r
1015   EFI_STATUS    Status;\r
1016   LIST_ENTRY    *Package;\r
1017   CHAR16        *ProblemParam;\r
1018   CONST CHAR16  *SName;\r
1019   CONST CHAR16  *Mapping;\r
1020   EFI_HANDLE    MapAsHandle;\r
1021   CONST EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
1022   SHELL_STATUS  ShellStatus;\r
1023   BOOLEAN       SfoMode;\r
1024   BOOLEAN       ConstMode;\r
1025   BOOLEAN       NormlMode;\r
1026   CONST CHAR16  *Param1;\r
1027   CONST CHAR16  *TypeString;\r
1028   UINTN         TempStringLength;\r
1029 \r
1030   ProblemParam  = NULL;\r
1031   Mapping       = NULL;\r
1032   SName         = NULL;\r
1033   DevPath       = NULL;\r
1034   ShellStatus   = SHELL_SUCCESS;\r
1035   MapAsHandle = NULL;\r
1036 \r
1037   //\r
1038   // initialize the shell lib (we must be in non-auto-init...)\r
1039   //\r
1040   Status = ShellInitialize();\r
1041   ASSERT_EFI_ERROR(Status);\r
1042 \r
1043   Status = CommandInit();\r
1044   ASSERT_EFI_ERROR(Status);\r
1045 \r
1046   //\r
1047   // parse the command line\r
1048   //\r
1049   Status = ShellCommandLineParse (MapParamList, &Package, &ProblemParam, TRUE);\r
1050   if (EFI_ERROR(Status)) {\r
1051     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
1052       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
1053       FreePool(ProblemParam);\r
1054       ShellStatus = SHELL_INVALID_PARAMETER;\r
1055     } else {\r
1056       ASSERT(FALSE);\r
1057     }\r
1058   } else {\r
1059     //\r
1060     // check for "-?"\r
1061     //\r
1062     SfoMode   = ShellCommandLineGetFlag(Package, L"-sfo");\r
1063     ConstMode = ShellCommandLineGetFlag(Package, L"-c");\r
1064     NormlMode = ShellCommandLineGetFlag(Package, L"-f");\r
1065     if (ShellCommandLineGetFlag(Package, L"-?")) {\r
1066       ASSERT(FALSE);\r
1067     } else if (ShellCommandLineGetRawValue(Package, 3) != NULL) {\r
1068       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
1069       ShellStatus = SHELL_INVALID_PARAMETER;\r
1070     } else {\r
1071       //\r
1072       // Deleting a map name...\r
1073       //\r
1074       if (ShellCommandLineGetFlag(Package, L"-d")) {\r
1075         if ( ShellCommandLineGetFlag(Package, L"-r")\r
1076           || ShellCommandLineGetFlag(Package, L"-v")\r
1077           || ConstMode\r
1078           || NormlMode\r
1079           || ShellCommandLineGetFlag(Package, L"-u")\r
1080           || ShellCommandLineGetFlag(Package, L"-t")\r
1081          ){\r
1082           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle);\r
1083           ShellStatus = SHELL_INVALID_PARAMETER;\r
1084         } else {\r
1085           SName = ShellCommandLineGetValue(Package, L"-d");\r
1086           if (SName != NULL) {\r
1087             Status = PerformMappingDelete(SName);\r
1088             if (EFI_ERROR(Status)) {\r
1089               switch (Status) {\r
1090                 case EFI_ACCESS_DENIED:\r
1091                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle);\r
1092                   ShellStatus = SHELL_ACCESS_DENIED;\r
1093                   break;\r
1094                 case EFI_NOT_FOUND:\r
1095                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, SName);\r
1096                   ShellStatus = SHELL_INVALID_PARAMETER;\r
1097                   break;\r
1098                 default:\r
1099                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
1100                   ShellStatus = SHELL_UNSUPPORTED;\r
1101               }\r
1102             }\r
1103           } else {\r
1104             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle);\r
1105             ShellStatus = SHELL_INVALID_PARAMETER;\r
1106           }\r
1107         }\r
1108       } else if ( ShellCommandLineGetFlag(Package, L"-r")\r
1109 //               || ShellCommandLineGetFlag(Package, L"-v")\r
1110                || ConstMode\r
1111                || NormlMode\r
1112                || ShellCommandLineGetFlag(Package, L"-u")\r
1113                || ShellCommandLineGetFlag(Package, L"-t")\r
1114               ){\r
1115         if ( ShellCommandLineGetFlag(Package, L"-r")) {\r
1116           //\r
1117           // Do the reset\r
1118           //\r
1119           Status = ShellCommandCreateInitialMappingsAndPaths();\r
1120           if (EFI_ERROR(Status)) {\r
1121             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
1122             ShellStatus = SHELL_UNSUPPORTED;\r
1123           }\r
1124         }\r
1125         if ( ShellStatus == SHELL_SUCCESS && ShellCommandLineGetFlag(Package, L"-u")) {\r
1126           //\r
1127           // Do the Update\r
1128           //\r
1129           Status = UpdateMapping();\r
1130           if (EFI_ERROR(Status)) {\r
1131             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
1132             ShellStatus = SHELL_UNSUPPORTED;\r
1133           }\r
1134         }\r
1135         if (ShellStatus == SHELL_SUCCESS) {\r
1136           Param1 = ShellCommandLineGetRawValue(Package, 1);\r
1137           TypeString = ShellCommandLineGetValue(Package, L"-t");\r
1138           if (!ConstMode\r
1139             &&!NormlMode\r
1140             &&TypeString  == NULL\r
1141             ) {\r
1142             //\r
1143             // now do the display...\r
1144             //\r
1145             ShellStatus = PerformMappingDisplay(\r
1146               ShellCommandLineGetFlag(Package, L"-v"),\r
1147               TRUE,\r
1148               TRUE,\r
1149               NULL,\r
1150               SfoMode,\r
1151               Param1,\r
1152               TRUE\r
1153              );\r
1154           } else {\r
1155             //\r
1156             // now do the display...\r
1157             //\r
1158             ShellStatus = PerformMappingDisplay2(\r
1159               ShellCommandLineGetFlag(Package, L"-v"),\r
1160               ConstMode,\r
1161               NormlMode,\r
1162               TypeString,\r
1163               SfoMode,\r
1164               Param1\r
1165              );\r
1166           }\r
1167         }\r
1168       } else {\r
1169         //\r
1170         // adding or displaying (there were no flags)\r
1171         //\r
1172         SName = ShellCommandLineGetRawValue(Package, 1);\r
1173         Mapping = ShellCommandLineGetRawValue(Package, 2);\r
1174         if ( SName == NULL\r
1175           && Mapping == NULL\r
1176          ){\r
1177           //\r
1178           // display only since no flags\r
1179           //\r
1180           ShellStatus = PerformMappingDisplay(\r
1181             ShellCommandLineGetFlag(Package, L"-v"),\r
1182             TRUE,\r
1183             TRUE,\r
1184             NULL,\r
1185             SfoMode,\r
1186             NULL,\r
1187             TRUE\r
1188            );\r
1189         } else if ( SName == NULL\r
1190           || Mapping == NULL\r
1191          ){\r
1192             //\r
1193             // Display only the one specified\r
1194             //\r
1195           ShellStatus = PerformMappingDisplay(\r
1196             FALSE,\r
1197             FALSE,\r
1198             FALSE,\r
1199             NULL,\r
1200             SfoMode,\r
1201             SName, // note the variable here...\r
1202             TRUE\r
1203            );\r
1204         } else {\r
1205           if (ShellIsHexOrDecimalNumber(Mapping, TRUE, FALSE)) {\r
1206             MapAsHandle = ConvertHandleIndexToHandle(ShellStrToUintn(Mapping));\r
1207           } else {\r
1208             MapAsHandle = NULL;\r
1209           }\r
1210           if (MapAsHandle == NULL && Mapping[StrLen(Mapping)-1] != L':') {\r
1211             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, Mapping);\r
1212             ShellStatus = SHELL_INVALID_PARAMETER;\r
1213           } else {\r
1214             if (MapAsHandle != NULL) {\r
1215               TempStringLength = StrLen(SName);\r
1216               if (!IsNumberLetterOnly(SName, TempStringLength-(SName[TempStringLength-1]==L':'?1:0))) {\r
1217                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, SName);\r
1218                 ShellStatus = SHELL_INVALID_PARAMETER;\r
1219               } else {\r
1220                 ShellStatus = AddMappingFromHandle(MapAsHandle, SName);\r
1221               }\r
1222             } else {\r
1223               TempStringLength = StrLen(SName);\r
1224               if (!IsNumberLetterOnly(SName, TempStringLength-(SName[TempStringLength-1]==L':'?1:0))) {\r
1225                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, SName);\r
1226                 ShellStatus = SHELL_INVALID_PARAMETER;\r
1227               } else {\r
1228                 ShellStatus = AddMappingFromMapping(Mapping, SName);\r
1229               }\r
1230             }\r
1231             if (ShellStatus != SHELL_SUCCESS) {\r
1232               switch (ShellStatus) {\r
1233                 case SHELL_ACCESS_DENIED:\r
1234                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle);\r
1235                   break;\r
1236                 case SHELL_INVALID_PARAMETER:\r
1237                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle);\r
1238                   break;\r
1239                 case SHELL_DEVICE_ERROR:\r
1240                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, Mapping);\r
1241                   break;\r
1242                 default:\r
1243                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, ShellStatus|MAX_BIT);\r
1244               }\r
1245             } else {\r
1246               //\r
1247               // now do the display...\r
1248               //\r
1249               ShellStatus = PerformMappingDisplay(\r
1250                 FALSE,\r
1251                 FALSE,\r
1252                 FALSE,\r
1253                 NULL,\r
1254                 SfoMode,\r
1255                 SName,\r
1256                 TRUE\r
1257                );\r
1258             } // we were sucessful so do an output\r
1259           } // got a valid map target\r
1260         } // got 2 variables\r
1261       } // we are adding a mapping\r
1262     } // got valid parameters\r
1263   }\r
1264 \r
1265   //\r
1266   // free the command line package\r
1267   //\r
1268   ShellCommandLineFreeVarList (Package);\r
1269 \r
1270   return (ShellStatus);\r
1271 }\r
1272 \r