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