ShellPkg: Add checking for memory allocation and pointer returns from functions.
[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   CONST EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
1029   SHELL_STATUS  ShellStatus;\r
1030   BOOLEAN       SfoMode;\r
1031   BOOLEAN       ConstMode;\r
1032   BOOLEAN       NormlMode;\r
1033   CONST CHAR16  *Param1;\r
1034   CONST CHAR16  *TypeString;\r
1035   UINTN         TempStringLength;\r
1036 \r
1037   ProblemParam  = NULL;\r
1038   Mapping       = NULL;\r
1039   SName         = NULL;\r
1040   DevPath       = NULL;\r
1041   ShellStatus   = SHELL_SUCCESS;\r
1042   MapAsHandle = NULL;\r
1043 \r
1044   //\r
1045   // initialize the shell lib (we must be in non-auto-init...)\r
1046   //\r
1047   Status = ShellInitialize();\r
1048   ASSERT_EFI_ERROR(Status);\r
1049 \r
1050   Status = CommandInit();\r
1051   ASSERT_EFI_ERROR(Status);\r
1052 \r
1053   //\r
1054   // parse the command line\r
1055   //\r
1056   Status = ShellCommandLineParse (MapParamList, &Package, &ProblemParam, TRUE);\r
1057   if (EFI_ERROR(Status)) {\r
1058     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
1059       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
1060       FreePool(ProblemParam);\r
1061       ShellStatus = SHELL_INVALID_PARAMETER;\r
1062     } else {\r
1063       ASSERT(FALSE);\r
1064     }\r
1065   } else {\r
1066     //\r
1067     // check for "-?"\r
1068     //\r
1069     SfoMode   = ShellCommandLineGetFlag(Package, L"-sfo");\r
1070     ConstMode = ShellCommandLineGetFlag(Package, L"-c");\r
1071     NormlMode = ShellCommandLineGetFlag(Package, L"-f");\r
1072     if (ShellCommandLineGetFlag(Package, L"-?")) {\r
1073       ASSERT(FALSE);\r
1074     } else if (ShellCommandLineGetRawValue(Package, 3) != NULL) {\r
1075       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
1076       ShellStatus = SHELL_INVALID_PARAMETER;\r
1077     } else {\r
1078       //\r
1079       // Deleting a map name...\r
1080       //\r
1081       if (ShellCommandLineGetFlag(Package, L"-d")) {\r
1082         if ( ShellCommandLineGetFlag(Package, L"-r")\r
1083           || ShellCommandLineGetFlag(Package, L"-v")\r
1084           || ConstMode\r
1085           || NormlMode\r
1086           || ShellCommandLineGetFlag(Package, L"-u")\r
1087           || ShellCommandLineGetFlag(Package, L"-t")\r
1088          ){\r
1089           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle);\r
1090           ShellStatus = SHELL_INVALID_PARAMETER;\r
1091         } else {\r
1092           SName = ShellCommandLineGetValue(Package, L"-d");\r
1093           if (SName != NULL) {\r
1094             Status = PerformMappingDelete(SName);\r
1095             if (EFI_ERROR(Status)) {\r
1096               switch (Status) {\r
1097                 case EFI_ACCESS_DENIED:\r
1098                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle);\r
1099                   ShellStatus = SHELL_ACCESS_DENIED;\r
1100                   break;\r
1101                 case EFI_NOT_FOUND:\r
1102                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, SName);\r
1103                   ShellStatus = SHELL_INVALID_PARAMETER;\r
1104                   break;\r
1105                 default:\r
1106                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
1107                   ShellStatus = SHELL_UNSUPPORTED;\r
1108               }\r
1109             }\r
1110           } else {\r
1111             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle);\r
1112             ShellStatus = SHELL_INVALID_PARAMETER;\r
1113           }\r
1114         }\r
1115       } else if ( ShellCommandLineGetFlag(Package, L"-r")\r
1116 //               || ShellCommandLineGetFlag(Package, L"-v")\r
1117                || ConstMode\r
1118                || NormlMode\r
1119                || ShellCommandLineGetFlag(Package, L"-u")\r
1120                || ShellCommandLineGetFlag(Package, L"-t")\r
1121               ){\r
1122         if ( ShellCommandLineGetFlag(Package, L"-r")) {\r
1123           //\r
1124           // Do the reset\r
1125           //\r
1126           Status = ShellCommandCreateInitialMappingsAndPaths();\r
1127           if (EFI_ERROR(Status)) {\r
1128             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
1129             ShellStatus = SHELL_UNSUPPORTED;\r
1130           }\r
1131         }\r
1132         if ( ShellStatus == SHELL_SUCCESS && ShellCommandLineGetFlag(Package, L"-u")) {\r
1133           //\r
1134           // Do the Update\r
1135           //\r
1136           Status = UpdateMapping();\r
1137           if (EFI_ERROR(Status)) {\r
1138             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
1139             ShellStatus = SHELL_UNSUPPORTED;\r
1140           }\r
1141         }\r
1142         if (ShellStatus == SHELL_SUCCESS) {\r
1143           Param1 = ShellCommandLineGetRawValue(Package, 1);\r
1144           TypeString = ShellCommandLineGetValue(Package, L"-t");\r
1145           if (!ConstMode\r
1146             &&!NormlMode\r
1147             &&TypeString  == NULL\r
1148             ) {\r
1149             //\r
1150             // now do the display...\r
1151             //\r
1152             ShellStatus = PerformMappingDisplay(\r
1153               ShellCommandLineGetFlag(Package, L"-v"),\r
1154               TRUE,\r
1155               TRUE,\r
1156               NULL,\r
1157               SfoMode,\r
1158               Param1,\r
1159               TRUE\r
1160              );\r
1161           } else {\r
1162             //\r
1163             // now do the display...\r
1164             //\r
1165             ShellStatus = PerformMappingDisplay2(\r
1166               ShellCommandLineGetFlag(Package, L"-v"),\r
1167               ConstMode,\r
1168               NormlMode,\r
1169               TypeString,\r
1170               SfoMode,\r
1171               Param1\r
1172              );\r
1173           }\r
1174         }\r
1175       } else {\r
1176         //\r
1177         // adding or displaying (there were no flags)\r
1178         //\r
1179         SName = ShellCommandLineGetRawValue(Package, 1);\r
1180         Mapping = ShellCommandLineGetRawValue(Package, 2);\r
1181         if ( SName == NULL\r
1182           && Mapping == NULL\r
1183          ){\r
1184           //\r
1185           // display only since no flags\r
1186           //\r
1187           ShellStatus = PerformMappingDisplay(\r
1188             ShellCommandLineGetFlag(Package, L"-v"),\r
1189             TRUE,\r
1190             TRUE,\r
1191             NULL,\r
1192             SfoMode,\r
1193             NULL,\r
1194             TRUE\r
1195            );\r
1196         } else if ( SName == NULL\r
1197           || Mapping == NULL\r
1198          ){\r
1199             //\r
1200             // Display only the one specified\r
1201             //\r
1202           ShellStatus = PerformMappingDisplay(\r
1203             FALSE,\r
1204             FALSE,\r
1205             FALSE,\r
1206             NULL,\r
1207             SfoMode,\r
1208             SName, // note the variable here...\r
1209             TRUE\r
1210            );\r
1211         } else {\r
1212           if (ShellIsHexOrDecimalNumber(Mapping, TRUE, FALSE)) {\r
1213             MapAsHandle = ConvertHandleIndexToHandle(ShellStrToUintn(Mapping));\r
1214           } else {\r
1215             MapAsHandle = NULL;\r
1216           }\r
1217           if (MapAsHandle == NULL && Mapping[StrLen(Mapping)-1] != L':') {\r
1218             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, Mapping);\r
1219             ShellStatus = SHELL_INVALID_PARAMETER;\r
1220           } else {\r
1221             if (MapAsHandle != NULL) {\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 = AddMappingFromHandle(MapAsHandle, SName);\r
1228               }\r
1229             } else {\r
1230               TempStringLength = StrLen(SName);\r
1231               if (!IsNumberLetterOnly(SName, TempStringLength-(SName[TempStringLength-1]==L':'?1:0))) {\r
1232                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, SName);\r
1233                 ShellStatus = SHELL_INVALID_PARAMETER;\r
1234               } else {\r
1235                 ShellStatus = AddMappingFromMapping(Mapping, SName);\r
1236               }\r
1237             }\r
1238             if (ShellStatus != SHELL_SUCCESS) {\r
1239               switch (ShellStatus) {\r
1240                 case SHELL_ACCESS_DENIED:\r
1241                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle);\r
1242                   break;\r
1243                 case SHELL_INVALID_PARAMETER:\r
1244                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle);\r
1245                   break;\r
1246                 case SHELL_DEVICE_ERROR:\r
1247                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, Mapping);\r
1248                   break;\r
1249                 default:\r
1250                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, ShellStatus|MAX_BIT);\r
1251               }\r
1252             } else {\r
1253               //\r
1254               // now do the display...\r
1255               //\r
1256               ShellStatus = PerformMappingDisplay(\r
1257                 FALSE,\r
1258                 FALSE,\r
1259                 FALSE,\r
1260                 NULL,\r
1261                 SfoMode,\r
1262                 SName,\r
1263                 TRUE\r
1264                );\r
1265             } // we were sucessful so do an output\r
1266           } // got a valid map target\r
1267         } // got 2 variables\r
1268       } // we are adding a mapping\r
1269     } // got valid parameters\r
1270   }\r
1271 \r
1272   //\r
1273   // free the command line package\r
1274   //\r
1275   ShellCommandLineFreeVarList (Package);\r
1276 \r
1277   return (ShellStatus);\r
1278 }\r
1279 \r