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