]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Map.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for map shell level 2 command.\r
3\r
4887443e 4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
e49ecad0
TS
5 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
6 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
ba0014b9 7\r
56ba3746 8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a405b86d 9\r
10**/\r
11\r
12#include "UefiShellLevel2CommandsLib.h"\r
13#include <Protocol/SimpleFileSystem.h>\r
14#include <Protocol/BlockIo.h>\r
15#include <Library/DevicePathLib.h>\r
16#include <Library/HandleParsingLib.h>\r
17#include <Library/SortLib.h>\r
18\r
b54fd049 19/**\r
20 Determine if a string has only numbers and letters.\r
21\r
22 This is useful for such things as Map names which can only be letters and numbers.\r
23\r
24 @param[in] String pointer to the string to analyze,\r
25 @param[in] Len Number of characters to analyze.\r
26\r
27 @retval TRUE String has only numbers and letters\r
28 @retval FALSE String has at least one other character.\r
29**/\r
30BOOLEAN\r
47d20b54
MK
31IsNumberLetterOnly (\r
32 IN CONST CHAR16 *String,\r
33 IN CONST UINTN Len\r
b54fd049 34 )\r
35{\r
47d20b54
MK
36 UINTN Count;\r
37\r
38 for (Count = 0; Count < Len && String != NULL && *String != CHAR_NULL; String++, Count++) {\r
39 if (!(((*String >= L'a') && (*String <= L'z')) ||\r
40 ((*String >= L'A') && (*String <= L'Z')) ||\r
41 ((*String >= L'0') && (*String <= L'9')))\r
42 )\r
43 {\r
b54fd049 44 return (FALSE);\r
45 }\r
46 }\r
47d20b54 47\r
b54fd049 48 return (TRUE);\r
49}\r
50\r
51/**\r
52 Do a search in the Target delimited list.\r
53\r
54 @param[in] List The list to seatch in.\r
55 @param[in] MetaTarget The item to search for. MetaMatching supported.\r
ba0014b9 56 @param[out] FullName Optional pointer to an allocated buffer containing\r
b54fd049 57 the match.\r
58 @param[in] Meta TRUE to use MetaMatching.\r
59 @param[in] SkipTrailingNumbers TRUE to allow for numbers after the MetaTarget.\r
ba0014b9
LG
60 @param[in] Target The single character that delimits list\r
61 items (";" normally).\r
b54fd049 62**/\r
a405b86d 63BOOLEAN\r
47d20b54 64SearchList (\r
a405b86d 65 IN CONST CHAR16 *List,\r
66 IN CONST CHAR16 *MetaTarget,\r
67 OUT CHAR16 **FullName OPTIONAL,\r
68 IN CONST BOOLEAN Meta,\r
69 IN CONST BOOLEAN SkipTrailingNumbers,\r
70 IN CONST CHAR16 *Target\r
71\r
72 )\r
73{\r
74 CHAR16 *TempList;\r
75 CONST CHAR16 *ListWalker;\r
76 BOOLEAN Result;\r
77 CHAR16 *TempSpot;\r
78\r
47d20b54
MK
79 for (ListWalker = List, TempList = NULL\r
80 ; ListWalker != NULL && *ListWalker != CHAR_NULL\r
81 ;\r
82 )\r
83 {\r
84 TempList = StrnCatGrow (&TempList, NULL, ListWalker, 0);\r
85 ASSERT (TempList != NULL);\r
86 TempSpot = StrStr (TempList, Target);\r
a405b86d 87 if (TempSpot != NULL) {\r
88 *TempSpot = CHAR_NULL;\r
89 }\r
90\r
47d20b54
MK
91 while (SkipTrailingNumbers && (ShellIsDecimalDigitCharacter (TempList[StrLen (TempList)-1]) || TempList[StrLen (TempList)-1] == L':')) {\r
92 TempList[StrLen (TempList)-1] = CHAR_NULL;\r
a405b86d 93 }\r
94\r
47d20b54
MK
95 ListWalker = StrStr (ListWalker, Target);\r
96 while (ListWalker != NULL && *ListWalker == *Target) {\r
a405b86d 97 ListWalker++;\r
98 }\r
47d20b54 99\r
a405b86d 100 if (Meta) {\r
47d20b54 101 Result = gUnicodeCollation->MetaiMatch (gUnicodeCollation, (CHAR16 *)TempList, (CHAR16 *)MetaTarget);\r
a405b86d 102 } else {\r
47d20b54 103 Result = (BOOLEAN)(StrCmp (TempList, MetaTarget) == 0);\r
a405b86d 104 }\r
47d20b54 105\r
a405b86d 106 if (Result) {\r
107 if (FullName != NULL) {\r
108 *FullName = TempList;\r
109 } else {\r
47d20b54 110 FreePool (TempList);\r
a405b86d 111 }\r
47d20b54 112\r
a405b86d 113 return (TRUE);\r
114 }\r
47d20b54
MK
115\r
116 FreePool (TempList);\r
a405b86d 117 TempList = NULL;\r
118 }\r
119\r
120 return (FALSE);\r
121}\r
122\r
b54fd049 123/**\r
ba0014b9 124 Determine what type of device is represented and return it's string. The\r
b54fd049 125 string is in allocated memory and must be callee freed. The HII is is listed below.\r
126 The actual string cannot be determined.\r
127\r
128 @param[in] DevicePath The device to analyze.\r
129\r
130 @retval STR_MAP_MEDIA_UNKNOWN The media type is unknown.\r
131 @retval STR_MAP_MEDIA_HARDDISK The media is a hard drive.\r
132 @retval STR_MAP_MEDIA_CDROM The media is a CD ROM.\r
133 @retval STR_MAP_MEDIA_FLOPPY The media is a floppy drive.\r
134**/\r
47d20b54 135CHAR16 *\r
a405b86d 136GetDeviceMediaType (\r
47d20b54 137 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 138 )\r
139{\r
140 ACPI_HID_DEVICE_PATH *Acpi;\r
141\r
142 //\r
143 // Parse the device path:\r
144 // Devicepath sub type mediatype\r
145 // MEDIA_HANRDDRIVE_DP -> Hard Disk\r
146 // MEDIA_CDROM_DP -> CD Rom\r
147 // Acpi.HID = 0X0604 -> Floppy\r
148 //\r
149 if (NULL == DevicePath) {\r
47d20b54 150 return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL);\r
a405b86d 151 }\r
152\r
47d20b54 153 for ( ; !IsDevicePathEndType (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {\r
a405b86d 154 if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) {\r
155 switch (DevicePathSubType (DevicePath)) {\r
47d20b54
MK
156 case MEDIA_HARDDRIVE_DP:\r
157 return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_HARDDISK), NULL);\r
158 case MEDIA_CDROM_DP:\r
159 return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_CDROM), NULL);\r
a405b86d 160 }\r
161 } else if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH) {\r
47d20b54 162 Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath;\r
a405b86d 163 if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {\r
47d20b54 164 return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_FLOPPY), NULL);\r
a405b86d 165 }\r
166 }\r
167 }\r
168\r
47d20b54 169 return HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MAP_MEDIA_UNKNOWN), NULL);\r
a405b86d 170}\r
171\r
172/**\r
173 Function to detemine if a handle has removable storage.\r
174\r
175 @param[in] DevicePath DevicePath to test.\r
176\r
177 @retval TRUE The handle has removable storage.\r
178 @retval FALSE The handle does not have removable storage.\r
179**/\r
180BOOLEAN\r
a405b86d 181IsRemoveableDevice (\r
47d20b54 182 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 183 )\r
184{\r
185 if (NULL == DevicePath) {\r
186 return FALSE;\r
187 }\r
188\r
189 while (!IsDevicePathEndType (DevicePath)) {\r
190 if (DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) {\r
191 switch (DevicePathSubType (DevicePath)) {\r
47d20b54
MK
192 case MSG_USB_DP:\r
193 case MSG_SCSI_DP:\r
194 return TRUE;\r
195 default:\r
196 return FALSE;\r
a405b86d 197 }\r
198 }\r
47d20b54 199\r
a405b86d 200 DevicePath = NextDevicePathNode (DevicePath);\r
201 }\r
47d20b54 202\r
a405b86d 203 return FALSE;\r
204}\r
205\r
206/**\r
207 Function to detemine if a something on the map list matches.\r
208\r
209 @param[in] MapList The pointer to the list to test.\r
210 @param[in] Specific The pointer to a specific name to test for.\r
211 @param[in] TypeString The pointer to the list of types.\r
212 @param[in] Normal Always show normal mappings.\r
213 @param[in] Consist Always show consistent mappings.\r
214\r
215 @retval TRUE The map should be displayed.\r
216 @retval FALSE The map should not be displayed.\r
217**/\r
218BOOLEAN\r
47d20b54
MK
219MappingListHasType (\r
220 IN CONST CHAR16 *MapList,\r
221 IN CONST CHAR16 *Specific,\r
222 IN CONST CHAR16 *TypeString,\r
223 IN CONST BOOLEAN Normal,\r
224 IN CONST BOOLEAN Consist\r
a405b86d 225 )\r
226{\r
47d20b54
MK
227 CHAR16 *NewSpecific;\r
228 RETURN_STATUS Status;\r
229 UINTN Length;\r
ba0014b9 230\r
a405b86d 231 //\r
232 // specific has priority\r
233 //\r
b54fd049 234 if (Specific != NULL) {\r
47d20b54 235 Length = StrLen (Specific);\r
4887443e
RN
236 //\r
237 // Allocate enough buffer for Specific and potential ":"\r
238 //\r
47d20b54
MK
239 NewSpecific = AllocatePool ((Length + 2) * sizeof (CHAR16));\r
240 if (NewSpecific == NULL) {\r
33c031ee 241 return FALSE;\r
242 }\r
47d20b54 243\r
4887443e
RN
244 StrCpyS (NewSpecific, Length + 2, Specific);\r
245 if (Specific[Length - 1] != L':') {\r
47d20b54 246 Status = StrnCatS (NewSpecific, Length + 2, L":", StrLen (L":"));\r
db906063 247 if (EFI_ERROR (Status)) {\r
47d20b54 248 FreePool (NewSpecific);\r
db906063
QS
249 return FALSE;\r
250 }\r
b54fd049 251 }\r
a405b86d 252\r
47d20b54
MK
253 if (SearchList (MapList, NewSpecific, NULL, TRUE, FALSE, L";")) {\r
254 FreePool (NewSpecific);\r
b54fd049 255 return (TRUE);\r
256 }\r
47d20b54
MK
257\r
258 FreePool (NewSpecific);\r
b54fd049 259 }\r
47d20b54 260\r
a405b86d 261 if ( Consist\r
47d20b54
MK
262 && (Specific == NULL)\r
263 && ( SearchList (MapList, L"HD*", NULL, TRUE, TRUE, L";")\r
264 || SearchList (MapList, L"CD*", NULL, TRUE, TRUE, L";")\r
265 || SearchList (MapList, L"F*", NULL, TRUE, TRUE, L";")\r
266 || SearchList (MapList, L"FP*", NULL, TRUE, TRUE, L";")))\r
267 {\r
a405b86d 268 return (TRUE);\r
269 }\r
270\r
271 if ( Normal\r
47d20b54
MK
272 && (Specific == NULL)\r
273 && ( SearchList (MapList, L"FS", NULL, FALSE, TRUE, L";")\r
274 || SearchList (MapList, L"BLK", NULL, FALSE, TRUE, L";")))\r
275 {\r
a405b86d 276 return (TRUE);\r
277 }\r
278\r
47d20b54 279 if ((TypeString != NULL) && SearchList (MapList, TypeString, NULL, TRUE, TRUE, L";")) {\r
a405b86d 280 return (TRUE);\r
281 }\r
47d20b54 282\r
a405b86d 283 return (FALSE);\r
284}\r
285\r
b54fd049 286/**\r
287 Display a single map line for device Handle if conditions are met.\r
288\r
289 @param[in] Verbose TRUE to display (extra) verbose information.\r
290 @param[in] Consist TRUE to display consistent mappings.\r
291 @param[in] Normal TRUE to display normal (not consist) mappings.\r
292 @param[in] TypeString pointer to string of filter types.\r
293 @param[in] SFO TRUE to display output in Standard Output Format.\r
294 @param[in] Specific pointer to string for specific map to display.\r
295 @param[in] Handle The handle to display from.\r
296\r
297 @retval EFI_SUCCESS The mapping was displayed.\r
298**/\r
299EFI_STATUS\r
47d20b54
MK
300PerformSingleMappingDisplay (\r
301 IN CONST BOOLEAN Verbose,\r
302 IN CONST BOOLEAN Consist,\r
303 IN CONST BOOLEAN Normal,\r
304 IN CONST CHAR16 *TypeString,\r
305 IN CONST BOOLEAN SFO,\r
306 IN CONST CHAR16 *Specific OPTIONAL,\r
307 IN CONST EFI_HANDLE Handle\r
a405b86d 308 )\r
309{\r
310 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
311 EFI_DEVICE_PATH_PROTOCOL *DevPathCopy;\r
312 CONST CHAR16 *MapList;\r
313 CHAR16 *CurrentName;\r
314 CHAR16 *MediaType;\r
315 CHAR16 *DevPathString;\r
316 CHAR16 *TempSpot;\r
64a5bae2 317 CHAR16 *Alias;\r
a405b86d 318 UINTN TempLen;\r
319 BOOLEAN Removable;\r
320 CONST CHAR16 *TempSpot2;\r
321\r
64a5bae2
JC
322 Alias = NULL;\r
323 TempSpot2 = NULL;\r
324 CurrentName = NULL;\r
47d20b54 325 DevPath = DevicePathFromHandle (Handle);\r
a405b86d 326 DevPathCopy = DevPath;\r
47d20b54 327 MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy);\r
a405b86d 328 if (MapList == NULL) {\r
b54fd049 329 return EFI_NOT_FOUND;\r
a405b86d 330 }\r
331\r
47d20b54 332 if (!MappingListHasType (MapList, Specific, TypeString, Normal, Consist)) {\r
b54fd049 333 return EFI_NOT_FOUND;\r
a405b86d 334 }\r
335\r
f747c71e
JC
336 if (Normal || !Consist) {\r
337 //\r
338 // need the Normal here since people can use both on command line. otherwise unused.\r
339 //\r
340\r
64a5bae2
JC
341 //\r
342 // Allocate a name\r
343 //\r
344 CurrentName = NULL;\r
47d20b54 345 CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0);\r
64a5bae2
JC
346 if (CurrentName == NULL) {\r
347 return (EFI_OUT_OF_RESOURCES);\r
348 }\r
349\r
350 //\r
351 // Chop off the other names that become "Alias(s)"\r
352 // leaving just the normal name\r
353 //\r
47d20b54 354 TempSpot = StrStr (CurrentName, L";");\r
64a5bae2
JC
355 if (TempSpot != NULL) {\r
356 *TempSpot = CHAR_NULL;\r
357 }\r
f747c71e 358 } else {\r
64a5bae2
JC
359 CurrentName = NULL;\r
360\r
361 //\r
362 // Skip the first name. This is the standard name.\r
363 //\r
47d20b54 364 TempSpot = StrStr (MapList, L";");\r
64a5bae2
JC
365 if (TempSpot != NULL) {\r
366 TempSpot++;\r
367 }\r
47d20b54
MK
368\r
369 SearchList (TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";");\r
64a5bae2 370 if (CurrentName == NULL) {\r
47d20b54 371 SearchList (TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";");\r
64a5bae2 372 }\r
47d20b54 373\r
64a5bae2 374 if (CurrentName == NULL) {\r
47d20b54 375 SearchList (TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";");\r
64a5bae2 376 }\r
47d20b54 377\r
64a5bae2 378 if (CurrentName == NULL) {\r
47d20b54 379 SearchList (TempSpot, L"F*", &CurrentName, TRUE, FALSE, L";");\r
64a5bae2 380 }\r
47d20b54 381\r
64a5bae2
JC
382 if (CurrentName == NULL) {\r
383 //\r
384 // We didnt find anything, so just the first one in the list...\r
385 //\r
47d20b54 386 CurrentName = StrnCatGrow (&CurrentName, 0, MapList, 0);\r
64a5bae2
JC
387 if (CurrentName == NULL) {\r
388 return (EFI_OUT_OF_RESOURCES);\r
389 }\r
47d20b54
MK
390\r
391 TempSpot = StrStr (CurrentName, L";");\r
64a5bae2
JC
392 if (TempSpot != NULL) {\r
393 *TempSpot = CHAR_NULL;\r
394 }\r
395 } else {\r
47d20b54 396 Alias = StrnCatGrow (&Alias, 0, MapList, 0);\r
c6cef635
SQ
397 if (Alias == NULL) {\r
398 return EFI_OUT_OF_RESOURCES;\r
399 }\r
47d20b54
MK
400\r
401 TempSpot = StrStr (Alias, CurrentName);\r
64a5bae2 402 if (TempSpot != NULL) {\r
47d20b54 403 TempSpot2 = StrStr (TempSpot, L";");\r
64a5bae2
JC
404 if (TempSpot2 != NULL) {\r
405 TempSpot2++; // Move past ";" from CurrentName\r
47d20b54 406 CopyMem (TempSpot, TempSpot2, StrSize (TempSpot2));\r
64a5bae2
JC
407 } else {\r
408 *TempSpot = CHAR_NULL;\r
409 }\r
410 }\r
47d20b54
MK
411\r
412 if (Alias[StrLen (Alias)-1] == L';') {\r
413 Alias[StrLen (Alias)-1] = CHAR_NULL;\r
64a5bae2
JC
414 }\r
415 }\r
a405b86d 416 }\r
47d20b54
MK
417\r
418 DevPathString = ConvertDevicePathToText (DevPath, TRUE, FALSE);\r
419 TempLen = StrLen (CurrentName);\r
a405b86d 420 if (!SFO) {\r
a405b86d 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
47d20b54 428 Alias != NULL ? Alias : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L""),\r
a405b86d 429 DevPathString\r
47d20b54 430 );\r
a405b86d 431 if (Verbose) {\r
432 //\r
433 // also print handle, media type, removable (y/n), and current directory\r
434 //\r
47d20b54
MK
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
a405b86d 439 ShellPrintHiiEx (\r
440 -1,\r
441 -1,\r
442 NULL,\r
443 STRING_TOKEN (STR_MAP_ENTRY_VERBOSE),\r
444 gShellLevel2HiiHandle,\r
47d20b54 445 ConvertHandleToHandleIndex (Handle),\r
a405b86d 446 MediaType,\r
47d20b54 447 Removable ? L"Yes" : L"No",\r
a405b86d 448 TempSpot2\r
47d20b54 449 );\r
a405b86d 450 }\r
47d20b54
MK
451\r
452 SHELL_FREE_NON_NULL (MediaType);\r
a405b86d 453 }\r
454 } else {\r
a405b86d 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
47d20b54
MK
463 Consist ? L"" : (TempLen < StrLen (MapList) ? MapList + TempLen+1 : L"")\r
464 );\r
a405b86d 465 }\r
47d20b54
MK
466\r
467 SHELL_FREE_NON_NULL (DevPathString);\r
468 SHELL_FREE_NON_NULL (CurrentName);\r
469 SHELL_FREE_NON_NULL (Alias);\r
b54fd049 470 return EFI_SUCCESS;\r
a405b86d 471}\r
472\r
b54fd049 473/**\r
474 Delete Specific from the list of maps for device Handle.\r
475\r
476 @param[in] Specific The name to delete.\r
477 @param[in] Handle The device to look on.\r
478\r
479 @retval EFI_SUCCESS The delete was successful.\r
480 @retval EFI_NOT_FOUND Name was not a map on Handle.\r
481**/\r
a405b86d 482EFI_STATUS\r
47d20b54
MK
483PerformSingleMappingDelete (\r
484 IN CONST CHAR16 *Specific,\r
485 IN CONST EFI_HANDLE Handle\r
a405b86d 486 )\r
487{\r
488 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
489 EFI_DEVICE_PATH_PROTOCOL *DevPathCopy;\r
490 CONST CHAR16 *MapList;\r
491 CHAR16 *CurrentName;\r
492\r
47d20b54 493 DevPath = DevicePathFromHandle (Handle);\r
a405b86d 494 DevPathCopy = DevPath;\r
47d20b54 495 MapList = gEfiShellProtocol->GetMapFromDevicePath (&DevPathCopy);\r
a405b86d 496 CurrentName = NULL;\r
497\r
498 if (MapList == NULL) {\r
499 return (EFI_NOT_FOUND);\r
500 }\r
47d20b54 501\r
a405b86d 502 //\r
503 // if there is a specific and its not on the list...\r
504 //\r
47d20b54 505 if (!SearchList (MapList, Specific, &CurrentName, TRUE, FALSE, L";")) {\r
a405b86d 506 return (EFI_NOT_FOUND);\r
507 }\r
47d20b54
MK
508\r
509 return (gEfiShellProtocol->SetMap (NULL, CurrentName));\r
a405b86d 510}\r
511\r
47d20b54
MK
512CONST CHAR16 Cd[] = L"cd*";\r
513CONST CHAR16 Hd[] = L"hd*";\r
514CONST CHAR16 Fp[] = L"fp*";\r
515CONST CHAR16 AnyF[] = L"F*";\r
516\r
a405b86d 517/**\r
518 Function to display mapping information to the user.\r
519\r
a1d4bfcc 520 If Specific is specified then Consist and Normal will be ignored since information will\r
a405b86d 521 be printed for the specific item only.\r
522\r
a1d4bfcc 523 @param[in] Verbose TRUE to display (extra) verbose information.\r
524 @param[in] Consist TRUE to display consistent mappings.\r
525 @param[in] Normal TRUE to display normal (not consist) mappings.\r
526 @param[in] TypeString Pointer to string of filter types.\r
527 @param[in] SFO TRUE to display output in Standard Output Format.\r
528 @param[in] Specific Pointer to string for specific map to display.\r
529 @param[in] Header TRUE to print the header block.\r
a405b86d 530\r
a1d4bfcc 531 @retval SHELL_SUCCESS The display was printed.\r
532 @retval SHELL_INVALID_PARAMETER One of Consist or Normal must be TRUE if no Specific.\r
a405b86d 533\r
534**/\r
a405b86d 535SHELL_STATUS\r
47d20b54
MK
536PerformMappingDisplay (\r
537 IN CONST BOOLEAN Verbose,\r
538 IN CONST BOOLEAN Consist,\r
539 IN CONST BOOLEAN Normal,\r
540 IN CONST CHAR16 *TypeString,\r
541 IN CONST BOOLEAN SFO,\r
542 IN CONST CHAR16 *Specific OPTIONAL,\r
543 IN CONST BOOLEAN Header\r
a405b86d 544 )\r
545{\r
47d20b54
MK
546 EFI_STATUS Status;\r
547 EFI_HANDLE *HandleBuffer;\r
548 UINTN BufferSize;\r
549 UINTN LoopVar;\r
550 CHAR16 *Test;\r
551 BOOLEAN Found;\r
552\r
553 if (!Consist && !Normal && (Specific == NULL) && (TypeString == NULL)) {\r
554 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");\r
a405b86d 555 return (SHELL_INVALID_PARAMETER);\r
556 }\r
557\r
558 if (TypeString != NULL) {\r
47d20b54
MK
559 Test = (CHAR16 *)Cd;\r
560 if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {\r
561 Test = (CHAR16 *)Hd;\r
562 if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {\r
563 Test = (CHAR16 *)Fp;\r
564 if (StrnCmp (TypeString, Test, StrLen (Test)-1) != 0) {\r
565 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", TypeString);\r
a405b86d 566 return (SHELL_INVALID_PARAMETER);\r
567 }\r
568 } else if (Test == NULL) {\r
47d20b54 569 Test = (CHAR16 *)AnyF;\r
a405b86d 570 }\r
571 }\r
572 } else {\r
573 Test = NULL;\r
574 }\r
575\r
576 if (Header) {\r
577 //\r
578 // Print the header\r
579 //\r
580 if (!SFO) {\r
47d20b54 581 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_HEADER), gShellLevel2HiiHandle);\r
a405b86d 582 } else {\r
47d20b54 583 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellLevel2HiiHandle, L"map");\r
a405b86d 584 }\r
585 }\r
586\r
47d20b54
MK
587 BufferSize = 0;\r
588 HandleBuffer = NULL;\r
a405b86d 589\r
590 //\r
591 // Look up all SimpleFileSystems in the platform\r
592 //\r
47d20b54
MK
593 Status = gBS->LocateHandle (\r
594 ByProtocol,\r
595 &gEfiSimpleFileSystemProtocolGuid,\r
596 NULL,\r
597 &BufferSize,\r
598 HandleBuffer\r
599 );\r
a405b86d 600 if (Status == EFI_BUFFER_TOO_SMALL) {\r
47d20b54 601 HandleBuffer = AllocateZeroPool (BufferSize);\r
9ea69f8a 602 if (HandleBuffer == NULL) {\r
603 return (SHELL_OUT_OF_RESOURCES);\r
604 }\r
47d20b54
MK
605\r
606 Status = gBS->LocateHandle (\r
607 ByProtocol,\r
608 &gEfiSimpleFileSystemProtocolGuid,\r
609 NULL,\r
610 &BufferSize,\r
611 HandleBuffer\r
612 );\r
a405b86d 613 }\r
a405b86d 614\r
615 //\r
616 // Get the map name(s) for each one.\r
617 //\r
b54fd049 618 for ( LoopVar = 0, Found = FALSE\r
47d20b54
MK
619 ; LoopVar < (BufferSize / sizeof (EFI_HANDLE)) && HandleBuffer != NULL\r
620 ; LoopVar++\r
621 )\r
622 {\r
623 Status = PerformSingleMappingDisplay (\r
624 Verbose,\r
625 Consist,\r
626 Normal,\r
627 Test,\r
628 SFO,\r
629 Specific,\r
630 HandleBuffer[LoopVar]\r
631 );\r
632 if (!EFI_ERROR (Status)) {\r
b54fd049 633 Found = TRUE;\r
634 }\r
a405b86d 635 }\r
636\r
637 //\r
638 // Look up all BlockIo in the platform\r
639 //\r
47d20b54
MK
640 Status = gBS->LocateHandle (\r
641 ByProtocol,\r
642 &gEfiBlockIoProtocolGuid,\r
643 NULL,\r
644 &BufferSize,\r
645 HandleBuffer\r
646 );\r
a405b86d 647 if (Status == EFI_BUFFER_TOO_SMALL) {\r
47d20b54
MK
648 SHELL_FREE_NON_NULL (HandleBuffer);\r
649 HandleBuffer = AllocateZeroPool (BufferSize);\r
9ea69f8a 650 if (HandleBuffer == NULL) {\r
651 return (SHELL_OUT_OF_RESOURCES);\r
652 }\r
47d20b54
MK
653\r
654 Status = gBS->LocateHandle (\r
655 ByProtocol,\r
656 &gEfiBlockIoProtocolGuid,\r
657 NULL,\r
658 &BufferSize,\r
659 HandleBuffer\r
660 );\r
a405b86d 661 }\r
47d20b54
MK
662\r
663 if (!EFI_ERROR (Status) && (HandleBuffer != NULL)) {\r
a405b86d 664 //\r
9ea69f8a 665 // Get the map name(s) for each one.\r
a405b86d 666 //\r
9ea69f8a 667 for ( LoopVar = 0\r
47d20b54
MK
668 ; LoopVar < BufferSize / sizeof (EFI_HANDLE)\r
669 ; LoopVar++\r
670 )\r
671 {\r
9ea69f8a 672 //\r
673 // Skip any that were already done...\r
674 //\r
47d20b54
MK
675 if (gBS->OpenProtocol (\r
676 HandleBuffer[LoopVar],\r
677 &gEfiSimpleFileSystemProtocolGuid,\r
678 NULL,\r
679 gImageHandle,\r
680 NULL,\r
681 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
682 ) == EFI_SUCCESS)\r
683 {\r
684 continue;\r
9ea69f8a 685 }\r
47d20b54
MK
686\r
687 Status = PerformSingleMappingDisplay (\r
688 Verbose,\r
689 Consist,\r
690 Normal,\r
691 Test,\r
692 SFO,\r
693 Specific,\r
694 HandleBuffer[LoopVar]\r
695 );\r
696 if (!EFI_ERROR (Status)) {\r
b54fd049 697 Found = TRUE;\r
698 }\r
a405b86d 699 }\r
47d20b54
MK
700\r
701 FreePool (HandleBuffer);\r
a405b86d 702 }\r
47d20b54 703\r
b54fd049 704 if (!Found) {\r
77dd0c81 705 if (Specific != NULL) {\r
47d20b54 706 ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", Specific);\r
77dd0c81 707 } else {\r
47d20b54 708 ShellPrintHiiEx (gST->ConOut->Mode->CursorColumn, gST->ConOut->Mode->CursorRow-1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"map");\r
77dd0c81 709 }\r
b54fd049 710 }\r
47d20b54 711\r
a405b86d 712 return (SHELL_SUCCESS);\r
713}\r
714\r
b54fd049 715/**\r
716 Perform a mapping display and parse for multiple types in the TypeString.\r
717\r
718 @param[in] Verbose TRUE to use verbose output.\r
719 @param[in] Consist TRUE to display consistent names.\r
720 @param[in] Normal TRUE to display normal names.\r
721 @param[in] TypeString An optional comma-delimited list of types.\r
722 @param[in] SFO TRUE to display in SFO format. See Spec.\r
723 @param[in] Specific An optional specific map name to display alone.\r
724\r
725 @retval SHELL_INVALID_PARAMETER A parameter was invalid.\r
726 @retval SHELL_SUCCESS The display was successful.\r
727 @sa PerformMappingDisplay\r
728**/\r
a405b86d 729SHELL_STATUS\r
47d20b54
MK
730PerformMappingDisplay2 (\r
731 IN CONST BOOLEAN Verbose,\r
732 IN CONST BOOLEAN Consist,\r
733 IN CONST BOOLEAN Normal,\r
734 IN CONST CHAR16 *TypeString,\r
735 IN CONST BOOLEAN SFO,\r
736 IN CONST CHAR16 *Specific OPTIONAL\r
a405b86d 737 )\r
738{\r
739 CONST CHAR16 *TypeWalker;\r
740 SHELL_STATUS ShellStatus;\r
741 CHAR16 *Comma;\r
742\r
a405b86d 743 if (TypeString == NULL) {\r
47d20b54 744 return (PerformMappingDisplay (Verbose, Consist, Normal, NULL, SFO, Specific, TRUE));\r
a405b86d 745 }\r
47d20b54 746\r
a405b86d 747 ShellStatus = SHELL_SUCCESS;\r
47d20b54
MK
748 for (TypeWalker = TypeString; TypeWalker != NULL && *TypeWalker != CHAR_NULL;) {\r
749 Comma = StrStr (TypeWalker, L",");\r
a405b86d 750 if (Comma == NULL) {\r
751 if (ShellStatus == SHELL_SUCCESS) {\r
47d20b54 752 ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
a405b86d 753 } else {\r
47d20b54 754 PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
a405b86d 755 }\r
47d20b54 756\r
a405b86d 757 break;\r
758 } else {\r
759 *Comma = CHAR_NULL;\r
760 if (ShellStatus == SHELL_SUCCESS) {\r
47d20b54 761 ShellStatus = PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
a405b86d 762 } else {\r
47d20b54 763 PerformMappingDisplay (Verbose, Consist, Normal, TypeWalker, SFO, Specific, (BOOLEAN)(TypeWalker == TypeString));\r
a405b86d 764 }\r
47d20b54
MK
765\r
766 *Comma = L',';\r
a405b86d 767 TypeWalker = Comma + 1;\r
768 }\r
769 }\r
770\r
771 return (ShellStatus);\r
772}\r
773\r
b54fd049 774/**\r
775 Delete a specific map.\r
776\r
777 @param[in] Specific The pointer to the name of the map to delete.\r
778\r
779 @retval EFI_INVALID_PARAMETER Specific was NULL.\r
780 @retval EFI_SUCCESS The operation was successful.\r
781 @retval EFI_NOT_FOUND Specific could not be found.\r
782**/\r
a405b86d 783EFI_STATUS\r
47d20b54 784PerformMappingDelete (\r
a405b86d 785 IN CONST CHAR16 *Specific\r
786 )\r
787{\r
47d20b54
MK
788 EFI_STATUS Status;\r
789 EFI_HANDLE *HandleBuffer;\r
790 UINTN BufferSize;\r
791 UINTN LoopVar;\r
792 BOOLEAN Deleted;\r
a405b86d 793\r
794 if (Specific == NULL) {\r
795 return (EFI_INVALID_PARAMETER);\r
796 }\r
797\r
47d20b54
MK
798 BufferSize = 0;\r
799 HandleBuffer = NULL;\r
800 Deleted = FALSE;\r
a405b86d 801\r
802 //\r
803 // Look up all SimpleFileSystems in the platform\r
804 //\r
47d20b54
MK
805 Status = gBS->LocateHandle (\r
806 ByProtocol,\r
807 &gEfiDevicePathProtocolGuid,\r
808 NULL,\r
809 &BufferSize,\r
810 HandleBuffer\r
811 );\r
a405b86d 812 if (Status == EFI_BUFFER_TOO_SMALL) {\r
47d20b54 813 HandleBuffer = AllocateZeroPool (BufferSize);\r
3e082d58 814 if (HandleBuffer == NULL) {\r
815 return (EFI_OUT_OF_RESOURCES);\r
816 }\r
47d20b54
MK
817\r
818 Status = gBS->LocateHandle (\r
819 ByProtocol,\r
820 &gEfiDevicePathProtocolGuid,\r
821 NULL,\r
822 &BufferSize,\r
823 HandleBuffer\r
824 );\r
a405b86d 825 }\r
47d20b54
MK
826\r
827 if (EFI_ERROR (Status)) {\r
828 SHELL_FREE_NON_NULL (HandleBuffer);\r
3e082d58 829 return (Status);\r
830 }\r
a405b86d 831\r
c154b997 832 if (HandleBuffer != NULL) {\r
833 //\r
834 // Get the map name(s) for each one.\r
835 //\r
836 for ( LoopVar = 0\r
47d20b54
MK
837 ; LoopVar < BufferSize / sizeof (EFI_HANDLE)\r
838 ; LoopVar++\r
839 )\r
840 {\r
841 if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) {\r
842 Deleted = TRUE;\r
c154b997 843 }\r
a405b86d 844 }\r
845 }\r
47d20b54 846\r
a405b86d 847 //\r
848 // Look up all BlockIo in the platform\r
849 //\r
47d20b54
MK
850 Status = gBS->LocateHandle (\r
851 ByProtocol,\r
852 &gEfiBlockIoProtocolGuid,\r
853 NULL,\r
854 &BufferSize,\r
855 HandleBuffer\r
856 );\r
a405b86d 857 if (Status == EFI_BUFFER_TOO_SMALL) {\r
47d20b54
MK
858 FreePool (HandleBuffer);\r
859 HandleBuffer = AllocateZeroPool (BufferSize);\r
3e082d58 860 if (HandleBuffer == NULL) {\r
861 return (EFI_OUT_OF_RESOURCES);\r
862 }\r
47d20b54
MK
863\r
864 Status = gBS->LocateHandle (\r
865 ByProtocol,\r
866 &gEfiBlockIoProtocolGuid,\r
867 NULL,\r
868 &BufferSize,\r
869 HandleBuffer\r
870 );\r
a405b86d 871 }\r
47d20b54
MK
872\r
873 if (EFI_ERROR (Status)) {\r
874 SHELL_FREE_NON_NULL (HandleBuffer);\r
3e082d58 875 return (Status);\r
876 }\r
a405b86d 877\r
c154b997 878 if (HandleBuffer != NULL) {\r
a405b86d 879 //\r
c154b997 880 // Get the map name(s) for each one.\r
a405b86d 881 //\r
c154b997 882 for ( LoopVar = 0\r
47d20b54
MK
883 ; LoopVar < BufferSize / sizeof (EFI_HANDLE)\r
884 ; LoopVar++\r
885 )\r
886 {\r
c154b997 887 //\r
888 // Skip any that were already done...\r
889 //\r
47d20b54
MK
890 if (gBS->OpenProtocol (\r
891 HandleBuffer[LoopVar],\r
892 &gEfiDevicePathProtocolGuid,\r
893 NULL,\r
894 gImageHandle,\r
895 NULL,\r
896 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
897 ) == EFI_SUCCESS)\r
898 {\r
899 continue;\r
c154b997 900 }\r
47d20b54
MK
901\r
902 if (PerformSingleMappingDelete (Specific, HandleBuffer[LoopVar]) == SHELL_SUCCESS) {\r
903 Deleted = TRUE;\r
c154b997 904 }\r
a405b86d 905 }\r
906 }\r
47d20b54
MK
907\r
908 SHELL_FREE_NON_NULL (HandleBuffer);\r
a405b86d 909 if (!Deleted) {\r
910 return (EFI_NOT_FOUND);\r
911 }\r
47d20b54 912\r
a405b86d 913 return (EFI_SUCCESS);\r
914}\r
915\r
916/**\r
917 function to add a mapping from mapping.\r
918\r
919 This function will get the device path associated with the mapping and call SetMap.\r
920\r
921 @param[in] Map The Map to add a mapping for\r
922 @param[in] SName The name of the new mapping\r
923\r
924 @retval SHELL_SUCCESS the mapping was added\r
925 @retval SHELL_INVALID_PARAMETER the device path for Map could not be retrieved.\r
926 @return Shell version of a return value from EfiShellProtocol->SetMap\r
927\r
928**/\r
929SHELL_STATUS\r
47d20b54
MK
930AddMappingFromMapping (\r
931 IN CONST CHAR16 *Map,\r
932 IN CONST CHAR16 *SName\r
a405b86d 933 )\r
934{\r
935 CONST EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
936 EFI_STATUS Status;\r
b54fd049 937 CHAR16 *NewSName;\r
db906063 938 RETURN_STATUS StrRetStatus;\r
ba0014b9 939\r
47d20b54 940 NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName);\r
33c031ee 941 if (NewSName == NULL) {\r
942 return (SHELL_OUT_OF_RESOURCES);\r
943 }\r
47d20b54
MK
944\r
945 if (NewSName[StrLen (NewSName)-1] != L':') {\r
946 StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":"));\r
947 if (EFI_ERROR (StrRetStatus)) {\r
948 FreePool (NewSName);\r
949 return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT)));\r
db906063 950 }\r
b54fd049 951 }\r
a405b86d 952\r
47d20b54
MK
953 if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) {\r
954 FreePool (NewSName);\r
a405b86d 955 return (SHELL_INVALID_PARAMETER);\r
956 }\r
957\r
47d20b54 958 DevPath = gEfiShellProtocol->GetDevicePathFromMap (Map);\r
a405b86d 959 if (DevPath == NULL) {\r
47d20b54 960 FreePool (NewSName);\r
a405b86d 961 return (SHELL_INVALID_PARAMETER);\r
962 }\r
963\r
47d20b54
MK
964 Status = gEfiShellProtocol->SetMap (DevPath, NewSName);\r
965 FreePool (NewSName);\r
966 if (EFI_ERROR (Status)) {\r
a405b86d 967 return (SHELL_DEVICE_ERROR);\r
968 }\r
47d20b54 969\r
a405b86d 970 return (SHELL_SUCCESS);\r
971}\r
972\r
a405b86d 973/**\r
974 function to add a mapping from an EFI_HANDLE.\r
975\r
976 This function will get the device path associated with the Handle and call SetMap.\r
977\r
978 @param[in] Handle The handle to add a mapping for\r
979 @param[in] SName The name of the new mapping\r
980\r
981 @retval SHELL_SUCCESS the mapping was added\r
982 @retval SHELL_INVALID_PARAMETER SName was not valid for a map name.\r
983 @return Shell version of a return value from either\r
984 gBS->OpenProtocol or EfiShellProtocol->SetMap\r
985\r
986**/\r
987SHELL_STATUS\r
47d20b54
MK
988AddMappingFromHandle (\r
989 IN CONST EFI_HANDLE Handle,\r
990 IN CONST CHAR16 *SName\r
a405b86d 991 )\r
992{\r
993 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
994 EFI_STATUS Status;\r
b54fd049 995 CHAR16 *NewSName;\r
db906063 996 RETURN_STATUS StrRetStatus;\r
ba0014b9 997\r
47d20b54 998 NewSName = AllocateCopyPool (StrSize (SName) + sizeof (CHAR16), SName);\r
33c031ee 999 if (NewSName == NULL) {\r
1000 return (SHELL_OUT_OF_RESOURCES);\r
1001 }\r
47d20b54
MK
1002\r
1003 if (NewSName[StrLen (NewSName)-1] != L':') {\r
1004 StrRetStatus = StrnCatS (NewSName, (StrSize (SName) + sizeof (CHAR16))/sizeof (CHAR16), L":", StrLen (L":"));\r
1005 if (EFI_ERROR (StrRetStatus)) {\r
1006 FreePool (NewSName);\r
1007 return ((SHELL_STATUS)(StrRetStatus & (~MAX_BIT)));\r
db906063 1008 }\r
b54fd049 1009 }\r
a405b86d 1010\r
47d20b54
MK
1011 if (!IsNumberLetterOnly (NewSName, StrLen (NewSName)-1)) {\r
1012 FreePool (NewSName);\r
a405b86d 1013 return (SHELL_INVALID_PARAMETER);\r
1014 }\r
1015\r
47d20b54
MK
1016 Status = gBS->OpenProtocol (\r
1017 Handle,\r
1018 &gEfiDevicePathProtocolGuid,\r
1019 (VOID **)&DevPath,\r
1020 gImageHandle,\r
1021 NULL,\r
1022 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1023 );\r
1024 if (EFI_ERROR (Status)) {\r
1025 FreePool (NewSName);\r
a405b86d 1026 return (SHELL_DEVICE_ERROR);\r
1027 }\r
47d20b54
MK
1028\r
1029 Status = gEfiShellProtocol->SetMap (DevPath, NewSName);\r
1030 FreePool (NewSName);\r
1031 if (EFI_ERROR (Status)) {\r
a405b86d 1032 return (SHELL_DEVICE_ERROR);\r
1033 }\r
47d20b54 1034\r
a405b86d 1035 return (SHELL_SUCCESS);\r
1036}\r
1037\r
47d20b54
MK
1038STATIC CONST SHELL_PARAM_ITEM MapParamList[] = {\r
1039 { L"-d", TypeValue },\r
1040 { L"-r", TypeFlag },\r
1041 { L"-v", TypeFlag },\r
1042 { L"-c", TypeFlag },\r
1043 { L"-f", TypeFlag },\r
1044 { L"-u", TypeFlag },\r
1045 { L"-t", TypeValue },\r
1046 { L"-sfo", TypeValue },\r
1047 { NULL, TypeMax }\r
1048};\r
a405b86d 1049\r
1ccfe74e
RN
1050/**\r
1051 The routine issues dummy read for every physical block device to cause\r
1052 the BlockIo re-installed if media change happened.\r
1053**/\r
1054VOID\r
1055ProbeForMediaChange (\r
1056 VOID\r
1057 )\r
1058{\r
47d20b54
MK
1059 EFI_STATUS Status;\r
1060 UINTN HandleCount;\r
1061 EFI_HANDLE *Handles;\r
1062 EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
1063 UINTN Index;\r
1ccfe74e
RN
1064\r
1065 gBS->LocateHandleBuffer (\r
1066 ByProtocol,\r
1067 &gEfiBlockIoProtocolGuid,\r
1068 NULL,\r
1069 &HandleCount,\r
1070 &Handles\r
1071 );\r
1072 //\r
1073 // Probe for media change for every physical block io\r
1074 //\r
1075 for (Index = 0; Index < HandleCount; Index++) {\r
1076 Status = gBS->HandleProtocol (\r
1077 Handles[Index],\r
1078 &gEfiBlockIoProtocolGuid,\r
47d20b54 1079 (VOID **)&BlockIo\r
1ccfe74e
RN
1080 );\r
1081 if (!EFI_ERROR (Status)) {\r
1082 if (!BlockIo->Media->LogicalPartition) {\r
1083 //\r
1084 // Per spec:\r
1085 // The function (ReadBlocks) must return EFI_NO_MEDIA or\r
1086 // EFI_MEDIA_CHANGED even if LBA, BufferSize, or Buffer are invalid so the caller can probe\r
1087 // for changes in media state.\r
1088 //\r
1089 BlockIo->ReadBlocks (\r
1090 BlockIo,\r
1091 BlockIo->Media->MediaId,\r
1092 0,\r
1093 0,\r
1094 NULL\r
1095 );\r
1096 }\r
1097 }\r
1098 }\r
1099}\r
1100\r
a405b86d 1101/**\r
1102 Function for 'map' command.\r
1103\r
1104 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
1105 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
1106**/\r
1107SHELL_STATUS\r
1108EFIAPI\r
1109ShellCommandRunMap (\r
1110 IN EFI_HANDLE ImageHandle,\r
1111 IN EFI_SYSTEM_TABLE *SystemTable\r
1112 )\r
1113{\r
1114 EFI_STATUS Status;\r
1115 LIST_ENTRY *Package;\r
1116 CHAR16 *ProblemParam;\r
1117 CONST CHAR16 *SName;\r
1118 CONST CHAR16 *Mapping;\r
b54fd049 1119 EFI_HANDLE MapAsHandle;\r
a405b86d 1120 SHELL_STATUS ShellStatus;\r
1121 BOOLEAN SfoMode;\r
1122 BOOLEAN ConstMode;\r
1123 BOOLEAN NormlMode;\r
1124 CONST CHAR16 *Param1;\r
1125 CONST CHAR16 *TypeString;\r
b54fd049 1126 UINTN TempStringLength;\r
a405b86d 1127\r
47d20b54
MK
1128 ProblemParam = NULL;\r
1129 Mapping = NULL;\r
1130 SName = NULL;\r
1131 ShellStatus = SHELL_SUCCESS;\r
1132 MapAsHandle = NULL;\r
a405b86d 1133\r
1134 //\r
1135 // initialize the shell lib (we must be in non-auto-init...)\r
1136 //\r
47d20b54
MK
1137 Status = ShellInitialize ();\r
1138 ASSERT_EFI_ERROR (Status);\r
a405b86d 1139\r
47d20b54
MK
1140 Status = CommandInit ();\r
1141 ASSERT_EFI_ERROR (Status);\r
a405b86d 1142\r
1143 //\r
1144 // parse the command line\r
1145 //\r
1146 Status = ShellCommandLineParse (MapParamList, &Package, &ProblemParam, TRUE);\r
47d20b54
MK
1147 if (EFI_ERROR (Status)) {\r
1148 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {\r
1149 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"map", ProblemParam);\r
1150 FreePool (ProblemParam);\r
a405b86d 1151 ShellStatus = SHELL_INVALID_PARAMETER;\r
1152 } else {\r
47d20b54 1153 ASSERT (FALSE);\r
a405b86d 1154 }\r
1155 } else {\r
1156 //\r
1157 // check for "-?"\r
1158 //\r
47d20b54
MK
1159 SfoMode = ShellCommandLineGetFlag (Package, L"-sfo");\r
1160 ConstMode = ShellCommandLineGetFlag (Package, L"-c");\r
1161 NormlMode = ShellCommandLineGetFlag (Package, L"-f");\r
1162 if (ShellCommandLineGetFlag (Package, L"-?")) {\r
1163 ASSERT (FALSE);\r
1164 } else if (ShellCommandLineGetRawValue (Package, 3) != NULL) {\r
1165 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"map");\r
a405b86d 1166 ShellStatus = SHELL_INVALID_PARAMETER;\r
1167 } else {\r
1168 //\r
1169 // Deleting a map name...\r
1170 //\r
47d20b54
MK
1171 if (ShellCommandLineGetFlag (Package, L"-d")) {\r
1172 if ( ShellCommandLineGetFlag (Package, L"-r")\r
1173 || ShellCommandLineGetFlag (Package, L"-v")\r
1174 || ConstMode\r
1175 || NormlMode\r
1176 || ShellCommandLineGetFlag (Package, L"-u")\r
1177 || ShellCommandLineGetFlag (Package, L"-t")\r
1178 )\r
1179 {\r
1180 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"map");\r
a405b86d 1181 ShellStatus = SHELL_INVALID_PARAMETER;\r
1182 } else {\r
47d20b54 1183 SName = ShellCommandLineGetValue (Package, L"-d");\r
a405b86d 1184 if (SName != NULL) {\r
47d20b54
MK
1185 Status = PerformMappingDelete (SName);\r
1186 if (EFI_ERROR (Status)) {\r
cbcccd2c 1187 if (Status == EFI_ACCESS_DENIED) {\r
47d20b54 1188 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");\r
cbcccd2c
LG
1189 ShellStatus = SHELL_ACCESS_DENIED;\r
1190 } else if (Status == EFI_NOT_FOUND) {\r
47d20b54 1191 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NF), gShellLevel2HiiHandle, L"map", SName);\r
cbcccd2c
LG
1192 ShellStatus = SHELL_INVALID_PARAMETER;\r
1193 } else {\r
47d20b54 1194 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);\r
cbcccd2c 1195 ShellStatus = SHELL_UNSUPPORTED;\r
a405b86d 1196 }\r
1197 }\r
1198 } else {\r
47d20b54 1199 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"map");\r
a405b86d 1200 ShellStatus = SHELL_INVALID_PARAMETER;\r
1201 }\r
1202 }\r
47d20b54
MK
1203 } else if ( ShellCommandLineGetFlag (Package, L"-r")\r
1204 // || ShellCommandLineGetFlag(Package, L"-v")\r
1205 || ConstMode\r
1206 || NormlMode\r
1207 || ShellCommandLineGetFlag (Package, L"-u")\r
1208 || ShellCommandLineGetFlag (Package, L"-t")\r
1209 )\r
1210 {\r
1ccfe74e 1211 ProbeForMediaChange ();\r
47d20b54 1212 if ( ShellCommandLineGetFlag (Package, L"-r")) {\r
a405b86d 1213 //\r
1214 // Do the reset\r
1215 //\r
47d20b54
MK
1216 Status = ShellCommandCreateInitialMappingsAndPaths ();\r
1217 if (EFI_ERROR (Status)) {\r
1218 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);\r
a405b86d 1219 ShellStatus = SHELL_UNSUPPORTED;\r
1220 }\r
1221 }\r
47d20b54
MK
1222\r
1223 if ((ShellStatus == SHELL_SUCCESS) && ShellCommandLineGetFlag (Package, L"-u")) {\r
a405b86d 1224 //\r
1225 // Do the Update\r
1226 //\r
e71cb452 1227 Status = ShellCommandUpdateMapping ();\r
47d20b54
MK
1228 if (EFI_ERROR (Status)) {\r
1229 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", Status);\r
a405b86d 1230 ShellStatus = SHELL_UNSUPPORTED;\r
1231 }\r
1232 }\r
47d20b54 1233\r
a405b86d 1234 if (ShellStatus == SHELL_SUCCESS) {\r
47d20b54
MK
1235 Param1 = ShellCommandLineGetRawValue (Package, 1);\r
1236 TypeString = ShellCommandLineGetValue (Package, L"-t");\r
1237 if ( !ConstMode\r
1238 && !NormlMode\r
1239 && (TypeString == NULL)\r
1240 )\r
1241 {\r
a405b86d 1242 //\r
1243 // now do the display...\r
1244 //\r
47d20b54
MK
1245 ShellStatus = PerformMappingDisplay (\r
1246 ShellCommandLineGetFlag (Package, L"-v"),\r
1247 TRUE,\r
1248 TRUE,\r
1249 NULL,\r
1250 SfoMode,\r
1251 Param1,\r
1252 TRUE\r
1253 );\r
a405b86d 1254 } else {\r
1255 //\r
1256 // now do the display...\r
1257 //\r
47d20b54
MK
1258 ShellStatus = PerformMappingDisplay2 (\r
1259 ShellCommandLineGetFlag (Package, L"-v"),\r
1260 ConstMode,\r
1261 NormlMode,\r
1262 TypeString,\r
1263 SfoMode,\r
1264 Param1\r
1265 );\r
a405b86d 1266 }\r
1267 }\r
1268 } else {\r
1269 //\r
1270 // adding or displaying (there were no flags)\r
1271 //\r
47d20b54
MK
1272 SName = ShellCommandLineGetRawValue (Package, 1);\r
1273 Mapping = ShellCommandLineGetRawValue (Package, 2);\r
1274 if ( (SName == NULL)\r
1275 && (Mapping == NULL)\r
1276 )\r
1277 {\r
a405b86d 1278 //\r
1279 // display only since no flags\r
1280 //\r
47d20b54
MK
1281 ShellStatus = PerformMappingDisplay (\r
1282 ShellCommandLineGetFlag (Package, L"-v"),\r
1283 TRUE,\r
1284 TRUE,\r
1285 NULL,\r
1286 SfoMode,\r
1287 NULL,\r
1288 TRUE\r
1289 );\r
1290 } else if ( (SName == NULL)\r
1291 || (Mapping == NULL)\r
1292 )\r
1293 {\r
1294 //\r
1295 // Display only the one specified\r
1296 //\r
1297 ShellStatus = PerformMappingDisplay (\r
1298 FALSE,\r
1299 FALSE,\r
1300 FALSE,\r
1301 NULL,\r
1302 SfoMode,\r
1303 SName, // note the variable here...\r
1304 TRUE\r
1305 );\r
a405b86d 1306 } else {\r
47d20b54
MK
1307 if (ShellIsHexOrDecimalNumber (Mapping, TRUE, FALSE)) {\r
1308 MapAsHandle = ConvertHandleIndexToHandle (ShellStrToUintn (Mapping));\r
a405b86d 1309 } else {\r
b54fd049 1310 MapAsHandle = NULL;\r
a405b86d 1311 }\r
47d20b54
MK
1312\r
1313 if ((MapAsHandle == NULL) && (Mapping[StrLen (Mapping)-1] != L':')) {\r
1314 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);\r
a405b86d 1315 ShellStatus = SHELL_INVALID_PARAMETER;\r
1316 } else {\r
47d20b54
MK
1317 TempStringLength = StrLen (SName);\r
1318 if (!IsNumberLetterOnly (SName, TempStringLength-((SName[TempStringLength-1] == L':') ? 1 : 0))) {\r
1319 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", SName);\r
e49ecad0
TS
1320 ShellStatus = SHELL_INVALID_PARAMETER;\r
1321 }\r
1322\r
1323 if (ShellStatus == SHELL_SUCCESS) {\r
1324 if (MapAsHandle != NULL) {\r
47d20b54 1325 ShellStatus = AddMappingFromHandle (MapAsHandle, SName);\r
b54fd049 1326 } else {\r
47d20b54 1327 ShellStatus = AddMappingFromMapping (Mapping, SName);\r
b54fd049 1328 }\r
e49ecad0
TS
1329\r
1330 if (ShellStatus != SHELL_SUCCESS) {\r
1331 switch (ShellStatus) {\r
1332 case SHELL_ACCESS_DENIED:\r
47d20b54 1333 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel2HiiHandle, L"map");\r
e49ecad0
TS
1334 break;\r
1335 case SHELL_INVALID_PARAMETER:\r
47d20b54 1336 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"map", Mapping);\r
e49ecad0
TS
1337 break;\r
1338 case SHELL_DEVICE_ERROR:\r
47d20b54 1339 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MAP_NOF), gShellLevel2HiiHandle, L"map", Mapping);\r
e49ecad0
TS
1340 break;\r
1341 default:\r
47d20b54 1342 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"map", ShellStatus|MAX_BIT);\r
e49ecad0
TS
1343 }\r
1344 } else {\r
1345 //\r
1346 // now do the display...\r
1347 //\r
47d20b54
MK
1348 ShellStatus = PerformMappingDisplay (\r
1349 FALSE,\r
1350 FALSE,\r
1351 FALSE,\r
1352 NULL,\r
1353 SfoMode,\r
1354 SName,\r
1355 TRUE\r
1356 );\r
e49ecad0 1357 } // we were sucessful so do an output\r
a405b86d 1358 }\r
a405b86d 1359 } // got a valid map target\r
1360 } // got 2 variables\r
1361 } // we are adding a mapping\r
1362 } // got valid parameters\r
1363 }\r
1364\r
1365 //\r
1366 // free the command line package\r
1367 //\r
1368 ShellCommandLineFreeVarList (Package);\r
1369\r
1370 return (ShellStatus);\r
1371}\r