]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
Refine comments and two code style.
[mirror_edk2.git] / ShellPkg / Library / UefiShellCommandLib / ConsistMapping.c
1 /** @file
2 Main file for support of shell consist mapping.
3
4 Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 **/
13
14 #include "UefiShellCommandLib.h"
15 #include <Library/DevicePathLib.h>
16 #include <Library/SortLib.h>
17
18 typedef enum {
19 MTDTypeUnknown,
20 MTDTypeFloppy,
21 MTDTypeHardDisk,
22 MTDTypeCDRom,
23 MTDTypeEnd
24 } MTD_TYPE;
25
26 typedef struct {
27 CHAR16 *Str;
28 UINTN Len;
29 } POOL_PRINT;
30
31 typedef struct {
32 UINTN Hi;
33 MTD_TYPE Mtd;
34 POOL_PRINT Csd;
35 BOOLEAN Digital;
36 } DEVICE_CONSIST_MAPPING_INFO;
37
38 typedef struct {
39 MTD_TYPE MTDType;
40 CHAR16 *Name;
41 } MTD_NAME;
42
43 typedef struct {
44 UINT8 Type;
45 UINT8 SubType;
46 VOID (EFIAPI *SerialFun) (EFI_DEVICE_PATH_PROTOCOL *DevPath, DEVICE_CONSIST_MAPPING_INFO *MapInfo);
47 INTN (EFIAPI *CompareFun) (EFI_DEVICE_PATH_PROTOCOL *DevPath, EFI_DEVICE_PATH_PROTOCOL *DevPath2);
48 } DEV_PATH_CONSIST_MAPPING_TABLE;
49
50
51 /**
52 Concatenates a formatted unicode string to allocated pool.
53 The caller must free the resulting buffer.
54
55 @param Str Tracks the allocated pool, size in use, and amount of pool allocated.
56 @param Fmt The format string
57 @param ... The data will be printed.
58
59 @return Allocated buffer with the formatted string printed in it.
60 The caller must free the allocated buffer.
61 The buffer allocation is not packed.
62
63 **/
64 CHAR16 *
65 EFIAPI
66 CatPrint (
67 IN OUT POOL_PRINT *Str,
68 IN CHAR16 *Fmt,
69 ...
70 )
71 {
72 UINT16 *AppendStr;
73 VA_LIST Args;
74 UINTN StringSize;
75
76 AppendStr = AllocateZeroPool (0x1000);
77 if (AppendStr == NULL) {
78 ASSERT(FALSE);
79 return Str->Str;
80 }
81
82 VA_START (Args, Fmt);
83 UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);
84 VA_END (Args);
85 if (NULL == Str->Str) {
86 StringSize = StrSize (AppendStr);
87 Str->Str = AllocateZeroPool (StringSize);
88 ASSERT (Str->Str != NULL);
89 } else {
90 StringSize = StrSize (AppendStr);
91 StringSize += (StrSize (Str->Str) - sizeof (UINT16));
92
93 Str->Str = ReallocatePool (
94 StrSize (Str->Str),
95 StringSize,
96 Str->Str
97 );
98 ASSERT (Str->Str != NULL);
99 }
100
101 StrCat (Str->Str, AppendStr);
102 Str->Len = StringSize;
103
104 FreePool (AppendStr);
105 return Str->Str;
106 }
107
108 MTD_NAME mMTDName[] = {
109 {
110 MTDTypeUnknown,
111 L"F"
112 },
113 {
114 MTDTypeFloppy,
115 L"FP"
116 },
117 {
118 MTDTypeHardDisk,
119 L"HD"
120 },
121 {
122 MTDTypeCDRom,
123 L"CD"
124 },
125 {
126 MTDTypeEnd,
127 NULL
128 }
129 };
130
131 /**
132 Function to append a 64 bit number / 25 onto the string.
133
134 @param[in, out] Str The string so append onto.
135 @param[in] Num The number to divide and append.
136
137 @retval EFI_INVALID_PARAMETER A parameter was NULL.
138 @retval EFI_SUCCESS The appending was successful.
139 **/
140 EFI_STATUS
141 EFIAPI
142 AppendCSDNum2 (
143 IN OUT POOL_PRINT *Str,
144 IN UINT64 Num
145 )
146 {
147 UINT64 Result;
148 UINT32 Rem;
149
150 if (Str == NULL) {
151 return (EFI_INVALID_PARAMETER);
152 }
153
154 Result = DivU64x32Remainder (Num, 25, &Rem);
155 if (Result > 0) {
156 AppendCSDNum2 (Str, Result);
157 }
158
159 CatPrint (Str, L"%c", Rem + 'a');
160 return (EFI_SUCCESS);
161 }
162
163 /**
164 Function to append a 64 bit number onto the mapping info.
165
166 @param[in, out] MappingItem The mapping info object to append onto.
167 @param[in] Num The info to append.
168
169 @retval EFI_INVALID_PARAMETER A parameter was NULL.
170 @retval EFI_SUCCESS The appending was successful.
171 **/
172 EFI_STATUS
173 EFIAPI
174 AppendCSDNum (
175 IN OUT DEVICE_CONSIST_MAPPING_INFO *MappingItem,
176 IN UINT64 Num
177 )
178 {
179 if (MappingItem == NULL) {
180 return EFI_INVALID_PARAMETER;
181 }
182
183 if (MappingItem->Digital) {
184 CatPrint (&MappingItem->Csd, L"%ld", Num);
185 } else {
186 AppendCSDNum2 (&MappingItem->Csd, Num);
187 }
188
189 MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital);
190
191 return (EFI_SUCCESS);
192 }
193
194 /**
195 Function to append string into the mapping info.
196
197 @param[in, out] MappingItem The mapping info object to append onto.
198 @param[in] Str The info to append.
199
200 @retval EFI_INVALID_PARAMETER A parameter was NULL.
201 @retval EFI_SUCCESS The appending was successful.
202 **/
203 EFI_STATUS
204 EFIAPI
205 AppendCSDStr (
206 IN OUT DEVICE_CONSIST_MAPPING_INFO *MappingItem,
207 IN CHAR16 *Str
208 )
209 {
210 CHAR16 *Index;
211
212 if (Str == NULL || MappingItem == NULL) {
213 return (EFI_INVALID_PARAMETER);
214 }
215
216 if (MappingItem->Digital) {
217 //
218 // To aVOID mult-meaning, the mapping is:
219 // 0 1 2 3 4 5 6 7 8 9 a b c d e f
220 // 0 16 2 3 4 5 6 7 8 9 10 11 12 13 14 15
221 //
222 for (Index = Str; *Index != 0; Index++) {
223 switch (*Index) {
224 case '0':
225 case '2':
226 case '3':
227 case '4':
228 case '5':
229 case '6':
230 case '7':
231 case '8':
232 case '9':
233 CatPrint (&MappingItem->Csd, L"%c", *Index);
234 break;
235
236 case '1':
237 CatPrint (&MappingItem->Csd, L"16");
238 break;
239
240 case 'a':
241 case 'b':
242 case 'c':
243 case 'd':
244 case 'e':
245 case 'f':
246 CatPrint (&MappingItem->Csd, L"1%c", *Index - 'a' + '0');
247 break;
248
249 case 'A':
250 case 'B':
251 case 'C':
252 case 'D':
253 case 'E':
254 case 'F':
255 CatPrint (&MappingItem->Csd, L"1%c", *Index - 'A' + '0');
256 break;
257 }
258 }
259 } else {
260 for (Index = Str; *Index != 0; Index++) {
261 //
262 // The mapping is:
263 // 0 1 2 3 4 5 6 7 8 9 a b c d e f
264 // a b c d e f g h i j k l m n o p
265 //
266 if (*Index >= '0' && *Index <= '9') {
267 CatPrint (&MappingItem->Csd, L"%c", *Index - '0' + 'a');
268 } else if (*Index >= 'a' && *Index <= 'f') {
269 CatPrint (&MappingItem->Csd, L"%c", *Index - 'a' + 'k');
270 } else if (*Index >= 'A' && *Index <= 'F') {
271 CatPrint (&MappingItem->Csd, L"%c", *Index - 'A' + 'k');
272 }
273 }
274 }
275
276 MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital);
277
278 return (EFI_SUCCESS);
279 }
280
281 /**
282 Function to append a Guid to the mapping item.
283
284 @param[in, out] MappingItem The item to append onto.
285 @param[in] Guid The guid to append.
286
287 @retval EFI_SUCCESS The appending operation was successful.
288 @retval EFI_INVALID_PARAMETER A parameter was NULL.
289 **/
290 EFI_STATUS
291 EFIAPI
292 AppendCSDGuid (
293 DEVICE_CONSIST_MAPPING_INFO *MappingItem,
294 EFI_GUID *Guid
295 )
296 {
297 CHAR16 Buffer[64];
298
299 if (Guid == NULL || MappingItem == NULL) {
300 return (EFI_INVALID_PARAMETER);
301 }
302
303 UnicodeSPrint (
304 Buffer,
305 0,
306 L"%g",
307 Guid
308 );
309
310 AppendCSDStr (MappingItem, Buffer);
311
312 return (EFI_SUCCESS);
313 }
314
315 /**
316 Function to compare 2 APCI device paths.
317
318 @param[in] DevicePath1 The first device path to compare.
319 @param[in] DevicePath2 The second device path to compare.
320
321 @retval 0 The device paths represent the same device.
322 @return Non zero if the devices are different, zero otherwise.
323 **/
324 INTN
325 EFIAPI
326 DevPathCompareAcpi (
327 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
328 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
329 )
330 {
331 ACPI_HID_DEVICE_PATH *Acpi1;
332 ACPI_HID_DEVICE_PATH *Acpi2;
333
334 if (DevicePath1 == NULL || DevicePath2 == NULL) {
335 return (-2);
336 }
337
338 Acpi1 = (ACPI_HID_DEVICE_PATH *) DevicePath1;
339 Acpi2 = (ACPI_HID_DEVICE_PATH *) DevicePath2;
340 if (Acpi1->HID > Acpi2->HID || (Acpi1->HID == Acpi2->HID && Acpi1->UID > Acpi2->UID)) {
341 return 1;
342 }
343
344 if (Acpi1->HID == Acpi2->HID && Acpi1->UID == Acpi2->UID) {
345 return 0;
346 }
347
348 return -1;
349 }
350
351 /**
352 Function to compare 2 PCI device paths.
353
354 @param[in] DevicePath1 The first device path to compare.
355 @param[in] DevicePath2 The second device path to compare.
356
357 @retval 0 The device paths represent the same device.
358 @return Non zero if the devices are different, zero otherwise.
359 **/
360 INTN
361 EFIAPI
362 DevPathComparePci (
363 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
364 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
365 )
366 {
367 PCI_DEVICE_PATH *Pci1;
368 PCI_DEVICE_PATH *Pci2;
369
370 ASSERT(DevicePath1 != NULL);
371 ASSERT(DevicePath2 != NULL);
372
373 Pci1 = (PCI_DEVICE_PATH *) DevicePath1;
374 Pci2 = (PCI_DEVICE_PATH *) DevicePath2;
375 if (Pci1->Device > Pci2->Device || (Pci1->Device == Pci2->Device && Pci1->Function > Pci2->Function)) {
376 return 1;
377 }
378
379 if (Pci1->Device == Pci2->Device && Pci1->Function == Pci2->Function) {
380 return 0;
381 }
382
383 return -1;
384 }
385
386 /**
387 Do a comparison on 2 device paths.
388
389 @param[in] DevicePath1 The first device path.
390 @param[in] DevicePath2 The second device path.
391
392 @retval 0 The 2 device paths are the same.
393 @retval <0 DevicePath2 is greater than DevicePath1.
394 @retval >0 DevicePath1 is greater than DevicePath2.
395 **/
396 INTN
397 EFIAPI
398 DevPathCompareDefault (
399 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
400 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
401 )
402 {
403 UINTN DevPathSize1;
404 UINTN DevPathSize2;
405
406 ASSERT(DevicePath1 != NULL);
407 ASSERT(DevicePath2 != NULL);
408
409 DevPathSize1 = DevicePathNodeLength (DevicePath1);
410 DevPathSize2 = DevicePathNodeLength (DevicePath2);
411 if (DevPathSize1 > DevPathSize2) {
412 return 1;
413 } else if (DevPathSize1 < DevPathSize2) {
414 return -1;
415 } else {
416 return CompareMem (DevicePath1, DevicePath2, DevPathSize1);
417 }
418 }
419
420 /**
421 DevicePathNode must be SerialHDD Channel type and this will populate the MappingItem.
422
423 @param[in] DevicePathNode The node to get info on.
424 @param[in] MappingItem The info item to populate.
425 **/
426 VOID
427 EFIAPI
428 DevPathSerialHardDrive (
429 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
430 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
431 )
432 {
433 HARDDRIVE_DEVICE_PATH *Hd;
434
435 ASSERT(DevicePathNode != NULL);
436 ASSERT(MappingItem != NULL);
437
438 Hd = (HARDDRIVE_DEVICE_PATH *) DevicePathNode;
439 if (MappingItem->Mtd == MTDTypeUnknown) {
440 MappingItem->Mtd = MTDTypeHardDisk;
441 }
442
443 AppendCSDNum (MappingItem, Hd->PartitionNumber);
444 }
445
446 /**
447 DevicePathNode must be SerialAtapi Channel type and this will populate the MappingItem.
448
449 @param[in] DevicePathNode The node to get info on.
450 @param[in] MappingItem The info item to populate.
451 **/
452 VOID
453 EFIAPI
454 DevPathSerialAtapi (
455 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
456 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
457 )
458 {
459 ATAPI_DEVICE_PATH *Atapi;
460
461 ASSERT(DevicePathNode != NULL);
462 ASSERT(MappingItem != NULL);
463
464 Atapi = (ATAPI_DEVICE_PATH *) DevicePathNode;
465 AppendCSDNum (MappingItem, (Atapi->PrimarySecondary * 2 + Atapi->SlaveMaster));
466 }
467
468 /**
469 DevicePathNode must be SerialCDROM Channel type and this will populate the MappingItem.
470
471 @param[in] DevicePathNode The node to get info on.
472 @param[in] MappingItem The info item to populate.
473 **/
474 VOID
475 EFIAPI
476 DevPathSerialCdRom (
477 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
478 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
479 )
480 {
481 CDROM_DEVICE_PATH *Cd;
482
483 ASSERT(DevicePathNode != NULL);
484 ASSERT(MappingItem != NULL);
485
486 Cd = (CDROM_DEVICE_PATH *) DevicePathNode;
487 MappingItem->Mtd = MTDTypeCDRom;
488 AppendCSDNum (MappingItem, Cd->BootEntry);
489 }
490
491 /**
492 DevicePathNode must be SerialFibre Channel type and this will populate the MappingItem.
493
494 @param[in] DevicePathNode The node to get info on.
495 @param[in] MappingItem The info item to populate.
496 **/
497 VOID
498 EFIAPI
499 DevPathSerialFibre (
500 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
501 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
502 )
503 {
504 FIBRECHANNEL_DEVICE_PATH *Fibre;
505
506 ASSERT(DevicePathNode != NULL);
507 ASSERT(MappingItem != NULL);
508
509 Fibre = (FIBRECHANNEL_DEVICE_PATH *) DevicePathNode;
510 AppendCSDNum (MappingItem, Fibre->WWN);
511 AppendCSDNum (MappingItem, Fibre->Lun);
512 }
513
514 /**
515 DevicePathNode must be SerialUart type and this will populate the MappingItem.
516
517 @param[in] DevicePathNode The node to get info on.
518 @param[in] MappingItem The info item to populate.
519 **/
520 VOID
521 EFIAPI
522 DevPathSerialUart (
523 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
524 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
525 )
526 {
527 UART_DEVICE_PATH *Uart;
528
529 ASSERT(DevicePathNode != NULL);
530 ASSERT(MappingItem != NULL);
531
532 Uart = (UART_DEVICE_PATH *) DevicePathNode;
533 AppendCSDNum (MappingItem, Uart->BaudRate);
534 AppendCSDNum (MappingItem, Uart->DataBits);
535 AppendCSDNum (MappingItem, Uart->Parity);
536 AppendCSDNum (MappingItem, Uart->StopBits);
537 }
538
539 /**
540 DevicePathNode must be SerialUSB type and this will populate the MappingItem.
541
542 @param[in] DevicePathNode The node to get info on.
543 @param[in] MappingItem The info item to populate.
544 **/
545 VOID
546 EFIAPI
547 DevPathSerialUsb (
548 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
549 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
550 )
551 {
552 USB_DEVICE_PATH *Usb;
553
554 ASSERT(DevicePathNode != NULL);
555 ASSERT(MappingItem != NULL);
556
557 Usb = (USB_DEVICE_PATH *) DevicePathNode;
558 AppendCSDNum (MappingItem, Usb->ParentPortNumber);
559 AppendCSDNum (MappingItem, Usb->InterfaceNumber);
560 }
561
562 /**
563 DevicePathNode must be SerialVendor type and this will populate the MappingItem.
564
565 @param[in] DevicePathNode The node to get info on.
566 @param[in] MappingItem The info item to populate.
567
568 **/
569 VOID
570 EFIAPI
571 DevPathSerialVendor (
572 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
573 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
574 )
575 {
576 VENDOR_DEVICE_PATH *Vendor;
577 SAS_DEVICE_PATH *Sas;
578
579 if (DevicePathNode == NULL || MappingItem == NULL) {
580 return;
581 }
582
583 Vendor = (VENDOR_DEVICE_PATH *) DevicePathNode;
584 AppendCSDGuid (MappingItem, &Vendor->Guid);
585
586 if (CompareGuid (&gEfiSasDevicePathGuid, &Vendor->Guid)) {
587 Sas = (SAS_DEVICE_PATH *) Vendor;
588 AppendCSDNum (MappingItem, Sas->SasAddress);
589 AppendCSDNum (MappingItem, Sas->Lun);
590 AppendCSDNum (MappingItem, Sas->DeviceTopology);
591 AppendCSDNum (MappingItem, Sas->RelativeTargetPort);
592 }
593 }
594
595 /**
596 DevicePathNode must be SerialLun type and this will populate the MappingItem.
597
598 @param[in] DevicePathNode The node to get info on.
599 @param[in] MappingItem The info item to populate.
600 **/
601 VOID
602 EFIAPI
603 DevPathSerialLun (
604 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
605 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
606 )
607 {
608 DEVICE_LOGICAL_UNIT_DEVICE_PATH *Lun;
609
610 ASSERT(DevicePathNode != NULL);
611 ASSERT(MappingItem != NULL);
612
613 Lun = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) DevicePathNode;
614 AppendCSDNum (MappingItem, Lun->Lun);
615 }
616
617 /**
618 DevicePathNode must be SerialSata type and this will populate the MappingItem.
619
620 @param[in] DevicePathNode The node to get info on.
621 @param[in] MappingItem The info item to populate.
622 **/
623 VOID
624 EFIAPI
625 DevPathSerialSata (
626 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
627 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
628 )
629 {
630 SATA_DEVICE_PATH *Sata;
631
632 ASSERT(DevicePathNode != NULL);
633 ASSERT(MappingItem != NULL);
634
635 Sata = (SATA_DEVICE_PATH *) DevicePathNode;
636 AppendCSDNum (MappingItem, Sata->HBAPortNumber);
637 AppendCSDNum (MappingItem, Sata->PortMultiplierPortNumber);
638 AppendCSDNum (MappingItem, Sata->Lun);
639 }
640
641 /**
642 DevicePathNode must be SerialSCSI type and this will populate the MappingItem.
643
644 @param[in] DevicePathNode The node to get info on.
645 @param[in] MappingItem The info item to populate.
646 **/
647 VOID
648 EFIAPI
649 DevPathSerialIScsi (
650 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
651 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
652 )
653 {
654 ///@todo make this a PCD
655 //
656 // As Csd of ISCSI node is quite long, we comment
657 // the code below to keep the consistent mapping
658 // short. Uncomment if you really need it.
659 //
660 /*
661 ISCSI_DEVICE_PATH *IScsi;
662 UINT8 *IScsiTargetName;
663 CHAR16 *TargetName;
664 UINTN TargetNameLength;
665 UINTN Index;
666
667 ASSERT(DevicePathNode != NULL);
668 ASSERT(MappingItem != NULL);
669
670 IScsi = (ISCSI_DEVICE_PATH *) DevicePathNode;
671 AppendCSDNum (MappingItem, IScsi->NetworkProtocol);
672 AppendCSDNum (MappingItem, IScsi->LoginOption);
673 AppendCSDNum (MappingItem, IScsi->Lun);
674 AppendCSDNum (MappingItem, IScsi->TargetPortalGroupTag);
675 TargetNameLength = DevicePathNodeLength (DevicePathNode) - sizeof (ISCSI_DEVICE_PATH);
676 if (TargetNameLength > 0) {
677 TargetName = AllocateZeroPool ((TargetNameLength + 1) * sizeof (CHAR16));
678 if (TargetName != NULL) {
679 IScsiTargetName = (UINT8 *) (IScsi + 1);
680 for (Index = 0; Index < TargetNameLength; Index++) {
681 TargetName[Index] = (CHAR16) IScsiTargetName[Index];
682 }
683 AppendCSDStr (MappingItem, TargetName);
684 FreePool (TargetName);
685 }
686 }
687 */
688 }
689
690 /**
691 DevicePathNode must be SerialI20 type and this will populate the MappingItem.
692
693 @param[in] DevicePathNode The node to get info on.
694 @param[in] MappingItem The info item to populate.
695 **/
696 VOID
697 EFIAPI
698 DevPathSerialI2O (
699 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
700 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
701 )
702 {
703 I2O_DEVICE_PATH *DevicePath_I20;
704
705 ASSERT(DevicePathNode != NULL);
706 ASSERT(MappingItem != NULL);
707
708 DevicePath_I20 = (I2O_DEVICE_PATH *) DevicePathNode;
709 AppendCSDNum (MappingItem, DevicePath_I20->Tid);
710 }
711
712 /**
713 DevicePathNode must be Mac Address type and this will populate the MappingItem.
714
715 @param[in] DevicePathNode The node to get info on.
716 @param[in] MappingItem The info item to populate.
717 **/
718 VOID
719 EFIAPI
720 DevPathSerialMacAddr (
721 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
722 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
723 )
724 {
725 MAC_ADDR_DEVICE_PATH *Mac;
726 UINTN HwAddressSize;
727 UINTN Index;
728 CHAR16 Buffer[64];
729 CHAR16 *PBuffer;
730
731 ASSERT(DevicePathNode != NULL);
732 ASSERT(MappingItem != NULL);
733
734 Mac = (MAC_ADDR_DEVICE_PATH *) DevicePathNode;
735
736 HwAddressSize = sizeof (EFI_MAC_ADDRESS);
737 if (Mac->IfType == 0x01 || Mac->IfType == 0x00) {
738 HwAddressSize = 6;
739 }
740
741 for (Index = 0, PBuffer = Buffer; Index < HwAddressSize; Index++, PBuffer += 2) {
742 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Mac->MacAddress.Addr[Index]);
743 }
744
745 AppendCSDStr (MappingItem, Buffer);
746 }
747
748 /**
749 DevicePathNode must be InfiniBand type and this will populate the MappingItem.
750
751 @param[in] DevicePathNode The node to get info on.
752 @param[in] MappingItem The info item to populate.
753 **/
754 VOID
755 EFIAPI
756 DevPathSerialInfiniBand (
757 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
758 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
759 )
760 {
761 INFINIBAND_DEVICE_PATH *InfiniBand;
762 UINTN Index;
763 CHAR16 Buffer[64];
764 CHAR16 *PBuffer;
765
766 ASSERT(DevicePathNode != NULL);
767 ASSERT(MappingItem != NULL);
768
769 InfiniBand = (INFINIBAND_DEVICE_PATH *) DevicePathNode;
770 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
771 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) InfiniBand->PortGid[Index]);
772 }
773
774 AppendCSDStr (MappingItem, Buffer);
775 AppendCSDNum (MappingItem, InfiniBand->ServiceId);
776 AppendCSDNum (MappingItem, InfiniBand->TargetPortId);
777 AppendCSDNum (MappingItem, InfiniBand->DeviceId);
778 }
779
780 /**
781 DevicePathNode must be IPv4 type and this will populate the MappingItem.
782
783 @param[in] DevicePathNode The node to get info on.
784 @param[in] MappingItem The info item to populate.
785 **/
786 VOID
787 EFIAPI
788 DevPathSerialIPv4 (
789 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
790 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
791 )
792 {
793 IPv4_DEVICE_PATH *Ip;
794 CHAR16 Buffer[10];
795
796 ASSERT(DevicePathNode != NULL);
797 ASSERT(MappingItem != NULL);
798
799 Ip = (IPv4_DEVICE_PATH *) DevicePathNode;
800 UnicodeSPrint (
801 Buffer,
802 0,
803 L"%02x%02x%02x%02x",
804 (UINTN) Ip->LocalIpAddress.Addr[0],
805 (UINTN) Ip->LocalIpAddress.Addr[1],
806 (UINTN) Ip->LocalIpAddress.Addr[2],
807 (UINTN) Ip->LocalIpAddress.Addr[3]
808 );
809 AppendCSDStr (MappingItem, Buffer);
810 AppendCSDNum (MappingItem, Ip->LocalPort);
811 UnicodeSPrint (
812 Buffer,
813 0,
814 L"%02x%02x%02x%02x",
815 (UINTN) Ip->RemoteIpAddress.Addr[0],
816 (UINTN) Ip->RemoteIpAddress.Addr[1],
817 (UINTN) Ip->RemoteIpAddress.Addr[2],
818 (UINTN) Ip->RemoteIpAddress.Addr[3]
819 );
820 AppendCSDStr (MappingItem, Buffer);
821 AppendCSDNum (MappingItem, Ip->RemotePort);
822 }
823
824 /**
825 DevicePathNode must be IPv6 type and this will populate the MappingItem.
826
827 @param[in] DevicePathNode The node to get info on.
828 @param[in] MappingItem The info item to populate.
829 **/
830 VOID
831 EFIAPI
832 DevPathSerialIPv6 (
833 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
834 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
835 )
836 {
837 IPv6_DEVICE_PATH *Ip;
838 UINTN Index;
839 CHAR16 Buffer[64];
840 CHAR16 *PBuffer;
841
842 ASSERT(DevicePathNode != NULL);
843 ASSERT(MappingItem != NULL);
844
845 Ip = (IPv6_DEVICE_PATH *) DevicePathNode;
846 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
847 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->LocalIpAddress.Addr[Index]);
848 }
849
850 AppendCSDStr (MappingItem, Buffer);
851 AppendCSDNum (MappingItem, Ip->LocalPort);
852 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
853 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->RemoteIpAddress.Addr[Index]);
854 }
855
856 AppendCSDStr (MappingItem, Buffer);
857 AppendCSDNum (MappingItem, Ip->RemotePort);
858 }
859
860 /**
861 DevicePathNode must be SCSI type and this will populate the MappingItem.
862
863 @param[in] DevicePathNode The node to get info on.
864 @param[in] MappingItem The info item to populate.
865 **/
866 VOID
867 EFIAPI
868 DevPathSerialScsi (
869 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
870 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
871 )
872 {
873 SCSI_DEVICE_PATH *Scsi;
874
875 ASSERT(DevicePathNode != NULL);
876 ASSERT(MappingItem != NULL);
877
878 Scsi = (SCSI_DEVICE_PATH *) DevicePathNode;
879 AppendCSDNum (MappingItem, Scsi->Pun);
880 AppendCSDNum (MappingItem, Scsi->Lun);
881 }
882
883 /**
884 DevicePathNode must be 1394 type and this will populate the MappingItem.
885
886 @param[in] DevicePathNode The node to get info on.
887 @param[in] MappingItem The info item to populate.
888 **/
889 VOID
890 EFIAPI
891 DevPathSerial1394 (
892 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
893 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
894 )
895 {
896 F1394_DEVICE_PATH *DevicePath_F1394;
897 CHAR16 Buffer[20];
898
899 ASSERT(DevicePathNode != NULL);
900 ASSERT(MappingItem != NULL);
901
902 DevicePath_F1394 = (F1394_DEVICE_PATH *) DevicePathNode;
903 UnicodeSPrint (Buffer, 0, L"%lx", DevicePath_F1394->Guid);
904 AppendCSDStr (MappingItem, Buffer);
905 }
906
907 /**
908 If the node is floppy type then populate the MappingItem.
909
910 @param[in] DevicePathNode The node to get info on.
911 @param[in] MappingItem The info item to populate.
912 **/
913 VOID
914 EFIAPI
915 DevPathSerialAcpi (
916 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
917 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
918 )
919 {
920 ACPI_HID_DEVICE_PATH *Acpi;
921
922 ASSERT(DevicePathNode != NULL);
923 ASSERT(MappingItem != NULL);
924
925 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;
926 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
927 if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
928 MappingItem->Mtd = MTDTypeFloppy;
929 AppendCSDNum (MappingItem, Acpi->UID);
930 }
931 }
932 }
933
934 /**
935 Empty function used for unknown devices.
936
937 @param[in] DevicePathNode Ignored.
938 @param[in] MappingItem Ignored.
939
940 Does nothing.
941 **/
942 VOID
943 EFIAPI
944 DevPathSerialDefault (
945 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
946 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
947 )
948 {
949 return;
950 }
951
952 DEV_PATH_CONSIST_MAPPING_TABLE DevPathConsistMappingTable[] = {
953 HARDWARE_DEVICE_PATH,
954 HW_PCI_DP,
955 DevPathSerialDefault,
956 DevPathComparePci,
957 ACPI_DEVICE_PATH,
958 ACPI_DP,
959 DevPathSerialAcpi,
960 DevPathCompareAcpi,
961 MESSAGING_DEVICE_PATH,
962 MSG_ATAPI_DP,
963 DevPathSerialAtapi,
964 DevPathCompareDefault,
965 MESSAGING_DEVICE_PATH,
966 MSG_SCSI_DP,
967 DevPathSerialScsi,
968 DevPathCompareDefault,
969 MESSAGING_DEVICE_PATH,
970 MSG_FIBRECHANNEL_DP,
971 DevPathSerialFibre,
972 DevPathCompareDefault,
973 MESSAGING_DEVICE_PATH,
974 MSG_1394_DP,
975 DevPathSerial1394,
976 DevPathCompareDefault,
977 MESSAGING_DEVICE_PATH,
978 MSG_USB_DP,
979 DevPathSerialUsb,
980 DevPathCompareDefault,
981 MESSAGING_DEVICE_PATH,
982 MSG_I2O_DP,
983 DevPathSerialI2O,
984 DevPathCompareDefault,
985 MESSAGING_DEVICE_PATH,
986 MSG_MAC_ADDR_DP,
987 DevPathSerialMacAddr,
988 DevPathCompareDefault,
989 MESSAGING_DEVICE_PATH,
990 MSG_IPv4_DP,
991 DevPathSerialIPv4,
992 DevPathCompareDefault,
993 MESSAGING_DEVICE_PATH,
994 MSG_IPv6_DP,
995 DevPathSerialIPv6,
996 DevPathCompareDefault,
997 MESSAGING_DEVICE_PATH,
998 MSG_INFINIBAND_DP,
999 DevPathSerialInfiniBand,
1000 DevPathCompareDefault,
1001 MESSAGING_DEVICE_PATH,
1002 MSG_UART_DP,
1003 DevPathSerialUart,
1004 DevPathCompareDefault,
1005 MESSAGING_DEVICE_PATH,
1006 MSG_VENDOR_DP,
1007 DevPathSerialVendor,
1008 DevPathCompareDefault,
1009 MESSAGING_DEVICE_PATH,
1010 MSG_DEVICE_LOGICAL_UNIT_DP,
1011 DevPathSerialLun,
1012 DevPathCompareDefault,
1013 MESSAGING_DEVICE_PATH,
1014 MSG_SATA_DP,
1015 DevPathSerialSata,
1016 DevPathCompareDefault,
1017 MESSAGING_DEVICE_PATH,
1018 MSG_ISCSI_DP,
1019 DevPathSerialIScsi,
1020 DevPathCompareDefault,
1021 MEDIA_DEVICE_PATH,
1022 MEDIA_HARDDRIVE_DP,
1023 DevPathSerialHardDrive,
1024 DevPathCompareDefault,
1025 MEDIA_DEVICE_PATH,
1026 MEDIA_CDROM_DP,
1027 DevPathSerialCdRom,
1028 DevPathCompareDefault,
1029 MEDIA_DEVICE_PATH,
1030 MEDIA_VENDOR_DP,
1031 DevPathSerialVendor,
1032 DevPathCompareDefault,
1033 0,
1034 0,
1035 NULL,
1036 NULL
1037 };
1038
1039 /**
1040 Function to determine if a device path node is Hi or not.
1041
1042 @param[in] DevicePathNode The node to check.
1043
1044 @retval TRUE The node is Hi.
1045 @retval FALSE The node is not Hi.
1046 **/
1047 BOOLEAN
1048 EFIAPI
1049 IsHIDevicePathNode (
1050 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
1051 )
1052 {
1053 ACPI_HID_DEVICE_PATH *Acpi;
1054
1055 ASSERT(DevicePathNode != NULL);
1056
1057 if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) {
1058 return TRUE;
1059 }
1060
1061 if (DevicePathNode->Type == ACPI_DEVICE_PATH) {
1062 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;
1063 switch (EISA_ID_TO_NUM (Acpi->HID)) {
1064 case 0x0301:
1065 case 0x0401:
1066 case 0x0501:
1067 case 0x0604:
1068 return FALSE;
1069 }
1070
1071 return TRUE;
1072 }
1073
1074 return FALSE;
1075 }
1076
1077 /**
1078 Function to convert a standard device path structure into a Hi version.
1079
1080 @param[in] DevicePath The device path to convert.
1081
1082 @return the device path portion that is Hi.
1083 **/
1084 EFI_DEVICE_PATH_PROTOCOL *
1085 EFIAPI
1086 GetHIDevicePath (
1087 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
1088 )
1089 {
1090 UINTN NonHIDevicePathNodeCount;
1091 UINTN Index;
1092 EFI_DEV_PATH Node;
1093 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1094 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
1095
1096 ASSERT(DevicePath != NULL);
1097
1098 NonHIDevicePathNodeCount = 0;
1099
1100 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
1101 SetDevicePathEndNode (HIDevicePath);
1102
1103 Node.DevPath.Type = END_DEVICE_PATH_TYPE;
1104 Node.DevPath.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
1105 Node.DevPath.Length[0] = (UINT8)sizeof (EFI_DEVICE_PATH_PROTOCOL);
1106 Node.DevPath.Length[1] = 0;
1107
1108 while (!IsDevicePathEnd (DevicePath)) {
1109 if (IsHIDevicePathNode (DevicePath)) {
1110 for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) {
1111 TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath);
1112 FreePool (HIDevicePath);
1113 HIDevicePath = TempDevicePath;
1114 }
1115
1116 TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath);
1117 FreePool (HIDevicePath);
1118 HIDevicePath = TempDevicePath;
1119 } else {
1120 NonHIDevicePathNodeCount++;
1121 }
1122 //
1123 // Next device path node
1124 //
1125 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);
1126 }
1127
1128 return HIDevicePath;
1129 }
1130
1131 /**
1132 Function to walk the device path looking for a dumpable node.
1133
1134 @param[in] MappingItem The Item to fill with data.
1135 @param[in] DevicePath The path of the item to get data on.
1136
1137 @return EFI_SUCCESS Always returns success.
1138 **/
1139 EFI_STATUS
1140 EFIAPI
1141 GetDeviceConsistMappingInfo (
1142 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,
1143 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
1144 )
1145 {
1146 VOID (EFIAPI *SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);
1147
1148 UINTN Index;
1149
1150 ASSERT(DevicePath != NULL);
1151 ASSERT(MappingItem != NULL);
1152
1153 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);
1154
1155 while (!IsDevicePathEnd (DevicePath)) {
1156 //
1157 // Find the handler to dump this device path node
1158 //
1159 SerialFun = NULL;
1160 for (Index = 0; DevPathConsistMappingTable[Index].SerialFun != NULL; Index += 1) {
1161
1162 if (DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type &&
1163 DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType
1164 ) {
1165 SerialFun = DevPathConsistMappingTable[Index].SerialFun;
1166 break;
1167 }
1168 }
1169 //
1170 // If not found, use a generic function
1171 //
1172 if (!SerialFun) {
1173 SerialFun = DevPathSerialDefault;
1174 }
1175
1176 SerialFun (DevicePath, MappingItem);
1177
1178 //
1179 // Next device path node
1180 //
1181 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);
1182 }
1183
1184 return EFI_SUCCESS;
1185 }
1186
1187 /**
1188 Function to initialize the table for creating consistent map names.
1189
1190 @param[out] Table The pointer to pointer to pointer to DevicePathProtocol object.
1191
1192 @retval EFI_SUCCESS The table was created successfully.
1193 **/
1194 EFI_STATUS
1195 EFIAPI
1196 ShellCommandConsistMappingInitialize (
1197 OUT EFI_DEVICE_PATH_PROTOCOL ***Table
1198 )
1199 {
1200 EFI_HANDLE *HandleBuffer;
1201 UINTN HandleNum;
1202 UINTN HandleLoop;
1203 EFI_DEVICE_PATH_PROTOCOL **TempTable;
1204 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
1205 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1206 UINTN Index;
1207 EFI_STATUS Status;
1208
1209 HandleBuffer = NULL;
1210
1211 Status = gBS->LocateHandleBuffer (
1212 AllHandles,
1213 NULL,
1214 NULL,
1215 &HandleNum,
1216 &HandleBuffer
1217 );
1218 ASSERT_EFI_ERROR(Status);
1219
1220 TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *));
1221 if (TempTable == NULL) {
1222 return EFI_OUT_OF_RESOURCES;
1223 }
1224
1225 for (HandleLoop = 0 ; HandleLoop < HandleNum ; HandleLoop++) {
1226 DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]);
1227 if (DevicePath == NULL) {
1228 continue;
1229 }
1230
1231 HIDevicePath = GetHIDevicePath (DevicePath);
1232 if (HIDevicePath == NULL) {
1233 continue;
1234 }
1235
1236 for (Index = 0; TempTable[Index] != NULL; Index++) {
1237 if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) {
1238 FreePool (HIDevicePath);
1239 break;
1240 }
1241 }
1242
1243 if (TempTable[Index] == NULL) {
1244 TempTable[Index] = HIDevicePath;
1245 }
1246 }
1247
1248 for (Index = 0; TempTable[Index] != NULL; Index++);
1249 PerformQuickSort(TempTable, Index, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);
1250 *Table = TempTable;
1251
1252 if (HandleBuffer != NULL) {
1253 FreePool (HandleBuffer);
1254 }
1255
1256 return EFI_SUCCESS;
1257 }
1258
1259 /**
1260 Function to uninitialize the table for creating consistent map names.
1261
1262 The parameter must have been received from ShellCommandConsistMappingInitialize.
1263
1264 @param[out] Table The pointer to pointer to DevicePathProtocol object.
1265
1266 @retval EFI_SUCCESS The table was deleted successfully.
1267 **/
1268 EFI_STATUS
1269 EFIAPI
1270 ShellCommandConsistMappingUnInitialize (
1271 EFI_DEVICE_PATH_PROTOCOL **Table
1272 )
1273 {
1274 UINTN Index;
1275
1276 ASSERT(Table != NULL);
1277
1278 for (Index = 0; Table[Index] != NULL; Index++) {
1279 FreePool (Table[Index]);
1280 }
1281
1282 FreePool (Table);
1283 return EFI_SUCCESS;
1284 }
1285
1286 /**
1287 Create a consistent mapped name for the device specified by DevicePath
1288 based on the Table.
1289
1290 This must be called after ShellCommandConsistMappingInitialize() and
1291 before ShellCommandConsistMappingUnInitialize() is called.
1292
1293 @param[in] DevicePath The pointer to the dev path for the device.
1294 @param[in] Table The Table of mapping information.
1295
1296 @retval NULL A consistent mapped name could not be created.
1297 @return A pointer to a string allocated from pool with the device name.
1298 **/
1299 CHAR16 *
1300 EFIAPI
1301 ShellCommandConsistMappingGenMappingName (
1302 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1303 IN EFI_DEVICE_PATH_PROTOCOL **Table
1304 )
1305 {
1306 POOL_PRINT Str;
1307 DEVICE_CONSIST_MAPPING_INFO MappingInfo;
1308 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1309 UINTN Index;
1310 UINTN NewSize;
1311
1312 ASSERT(DevicePath != NULL);
1313 ASSERT(Table != NULL);
1314
1315 HIDevicePath = GetHIDevicePath (DevicePath);
1316 if (HIDevicePath == NULL) {
1317 return NULL;
1318 }
1319
1320 for (Index = 0; Table[Index] != NULL; Index++) {
1321 if (DevicePathCompare (&Table[Index], &HIDevicePath) == 0) {
1322 break;
1323 }
1324 }
1325
1326 FreePool (HIDevicePath);
1327 if (Table[Index] == NULL) {
1328 return NULL;
1329 }
1330
1331 MappingInfo.Hi = Index;
1332 MappingInfo.Mtd = MTDTypeUnknown;
1333 MappingInfo.Digital = FALSE;
1334
1335 GetDeviceConsistMappingInfo (&MappingInfo, DevicePath);
1336
1337 SetMem (&Str, sizeof (Str), 0);
1338 for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) {
1339 if (MappingInfo.Mtd == mMTDName[Index].MTDType) {
1340 break;
1341 }
1342 }
1343
1344 if (mMTDName[Index].MTDType != MTDTypeEnd) {
1345 CatPrint (&Str, L"%s", mMTDName[Index].Name);
1346 }
1347
1348 CatPrint (&Str, L"%d", (UINTN) MappingInfo.Hi);
1349 if (MappingInfo.Csd.Str != NULL) {
1350 CatPrint (&Str, L"%s", MappingInfo.Csd.Str);
1351 FreePool (MappingInfo.Csd.Str);
1352 }
1353
1354 if (Str.Str != NULL) {
1355 CatPrint (&Str, L":");
1356 }
1357
1358 NewSize = (Str.Len + 1) * sizeof (CHAR16);
1359 Str.Str = ReallocatePool (Str.Len, NewSize, Str.Str);
1360 if (Str.Str == NULL) {
1361 return (NULL);
1362 }
1363 Str.Str[Str.Len] = CHAR_NULL;
1364 return Str.Str;
1365 }
1366
1367 /**
1368 Function to search the list of mappings for the node on the list based on the key.
1369
1370 @param[in] MapKey String Key to search for on the map
1371
1372 @return the node on the list.
1373 **/
1374 SHELL_MAP_LIST *
1375 EFIAPI
1376 ShellCommandFindMapItem (
1377 IN CONST CHAR16 *MapKey
1378 )
1379 {
1380 SHELL_MAP_LIST *MapListItem;
1381
1382 for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
1383 ; !IsNull(&gShellMapList.Link, &MapListItem->Link)
1384 ; MapListItem = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &MapListItem->Link)
1385 ){
1386 if (gUnicodeCollation->StriColl(gUnicodeCollation,MapListItem->MapName,(CHAR16*)MapKey) == 0) {
1387 return (MapListItem);
1388 }
1389 }
1390 return (NULL);
1391 }
1392
1393