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