VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c@ 108794

Last change on this file since 108794 was 108794, checked in by vboxsync, 2 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette