]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
[PATHC] ShellPkg: control code flow with a PCD
[mirror_edk2.git] / ShellPkg / Library / UefiShellCommandLib / ConsistMapping.c
1 /** @file
2 Main file for support of shell consist mapping.
3
4 Copyright (c) 2005 - 2014, 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 StrnCat (Str->Str, AppendStr, StringSize/sizeof(CHAR16) - 1 - StrLen(Str->Str));
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 ISCSI_DEVICE_PATH *IScsi;
655 UINT8 *IScsiTargetName;
656 CHAR16 *TargetName;
657 UINTN TargetNameLength;
658 UINTN Index;
659
660 ASSERT(DevicePathNode != NULL);
661 ASSERT(MappingItem != NULL);
662
663 if (PcdGetBool(PcdShellDecodeIScsiMapNames)) {
664 IScsi = (ISCSI_DEVICE_PATH *) DevicePathNode;
665 AppendCSDNum (MappingItem, IScsi->NetworkProtocol);
666 AppendCSDNum (MappingItem, IScsi->LoginOption);
667 AppendCSDNum (MappingItem, IScsi->Lun);
668 AppendCSDNum (MappingItem, IScsi->TargetPortalGroupTag);
669 TargetNameLength = DevicePathNodeLength (DevicePathNode) - sizeof (ISCSI_DEVICE_PATH);
670 if (TargetNameLength > 0) {
671 TargetName = AllocateZeroPool ((TargetNameLength + 1) * sizeof (CHAR16));
672 if (TargetName != NULL) {
673 IScsiTargetName = (UINT8 *) (IScsi + 1);
674 for (Index = 0; Index < TargetNameLength; Index++) {
675 TargetName[Index] = (CHAR16) IScsiTargetName[Index];
676 }
677 AppendCSDStr (MappingItem, TargetName);
678 FreePool (TargetName);
679 }
680 }
681 }
682 }
683
684 /**
685 DevicePathNode must be SerialI20 type and this will populate the MappingItem.
686
687 @param[in] DevicePathNode The node to get info on.
688 @param[in] MappingItem The info item to populate.
689 **/
690 VOID
691 EFIAPI
692 DevPathSerialI2O (
693 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
694 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
695 )
696 {
697 I2O_DEVICE_PATH *DevicePath_I20;
698
699 ASSERT(DevicePathNode != NULL);
700 ASSERT(MappingItem != NULL);
701
702 DevicePath_I20 = (I2O_DEVICE_PATH *) DevicePathNode;
703 AppendCSDNum (MappingItem, DevicePath_I20->Tid);
704 }
705
706 /**
707 DevicePathNode must be Mac Address type and this will populate the MappingItem.
708
709 @param[in] DevicePathNode The node to get info on.
710 @param[in] MappingItem The info item to populate.
711 **/
712 VOID
713 EFIAPI
714 DevPathSerialMacAddr (
715 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
716 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
717 )
718 {
719 MAC_ADDR_DEVICE_PATH *Mac;
720 UINTN HwAddressSize;
721 UINTN Index;
722 CHAR16 Buffer[64];
723 CHAR16 *PBuffer;
724
725 ASSERT(DevicePathNode != NULL);
726 ASSERT(MappingItem != NULL);
727
728 Mac = (MAC_ADDR_DEVICE_PATH *) DevicePathNode;
729
730 HwAddressSize = sizeof (EFI_MAC_ADDRESS);
731 if (Mac->IfType == 0x01 || Mac->IfType == 0x00) {
732 HwAddressSize = 6;
733 }
734
735 for (Index = 0, PBuffer = Buffer; Index < HwAddressSize; Index++, PBuffer += 2) {
736 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Mac->MacAddress.Addr[Index]);
737 }
738
739 AppendCSDStr (MappingItem, Buffer);
740 }
741
742 /**
743 DevicePathNode must be InfiniBand type and this will populate the MappingItem.
744
745 @param[in] DevicePathNode The node to get info on.
746 @param[in] MappingItem The info item to populate.
747 **/
748 VOID
749 EFIAPI
750 DevPathSerialInfiniBand (
751 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
752 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
753 )
754 {
755 INFINIBAND_DEVICE_PATH *InfiniBand;
756 UINTN Index;
757 CHAR16 Buffer[64];
758 CHAR16 *PBuffer;
759
760 ASSERT(DevicePathNode != NULL);
761 ASSERT(MappingItem != NULL);
762
763 InfiniBand = (INFINIBAND_DEVICE_PATH *) DevicePathNode;
764 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
765 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) InfiniBand->PortGid[Index]);
766 }
767
768 AppendCSDStr (MappingItem, Buffer);
769 AppendCSDNum (MappingItem, InfiniBand->ServiceId);
770 AppendCSDNum (MappingItem, InfiniBand->TargetPortId);
771 AppendCSDNum (MappingItem, InfiniBand->DeviceId);
772 }
773
774 /**
775 DevicePathNode must be IPv4 type and this will populate the MappingItem.
776
777 @param[in] DevicePathNode The node to get info on.
778 @param[in] MappingItem The info item to populate.
779 **/
780 VOID
781 EFIAPI
782 DevPathSerialIPv4 (
783 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
784 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
785 )
786 {
787 IPv4_DEVICE_PATH *Ip;
788 CHAR16 Buffer[10];
789
790 ASSERT(DevicePathNode != NULL);
791 ASSERT(MappingItem != NULL);
792
793 Ip = (IPv4_DEVICE_PATH *) DevicePathNode;
794 UnicodeSPrint (
795 Buffer,
796 0,
797 L"%02x%02x%02x%02x",
798 (UINTN) Ip->LocalIpAddress.Addr[0],
799 (UINTN) Ip->LocalIpAddress.Addr[1],
800 (UINTN) Ip->LocalIpAddress.Addr[2],
801 (UINTN) Ip->LocalIpAddress.Addr[3]
802 );
803 AppendCSDStr (MappingItem, Buffer);
804 AppendCSDNum (MappingItem, Ip->LocalPort);
805 UnicodeSPrint (
806 Buffer,
807 0,
808 L"%02x%02x%02x%02x",
809 (UINTN) Ip->RemoteIpAddress.Addr[0],
810 (UINTN) Ip->RemoteIpAddress.Addr[1],
811 (UINTN) Ip->RemoteIpAddress.Addr[2],
812 (UINTN) Ip->RemoteIpAddress.Addr[3]
813 );
814 AppendCSDStr (MappingItem, Buffer);
815 AppendCSDNum (MappingItem, Ip->RemotePort);
816 }
817
818 /**
819 DevicePathNode must be IPv6 type and this will populate the MappingItem.
820
821 @param[in] DevicePathNode The node to get info on.
822 @param[in] MappingItem The info item to populate.
823 **/
824 VOID
825 EFIAPI
826 DevPathSerialIPv6 (
827 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
828 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
829 )
830 {
831 IPv6_DEVICE_PATH *Ip;
832 UINTN Index;
833 CHAR16 Buffer[64];
834 CHAR16 *PBuffer;
835
836 ASSERT(DevicePathNode != NULL);
837 ASSERT(MappingItem != NULL);
838
839 Ip = (IPv6_DEVICE_PATH *) DevicePathNode;
840 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
841 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->LocalIpAddress.Addr[Index]);
842 }
843
844 AppendCSDStr (MappingItem, Buffer);
845 AppendCSDNum (MappingItem, Ip->LocalPort);
846 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
847 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->RemoteIpAddress.Addr[Index]);
848 }
849
850 AppendCSDStr (MappingItem, Buffer);
851 AppendCSDNum (MappingItem, Ip->RemotePort);
852 }
853
854 /**
855 DevicePathNode must be SCSI type and this will populate the MappingItem.
856
857 @param[in] DevicePathNode The node to get info on.
858 @param[in] MappingItem The info item to populate.
859 **/
860 VOID
861 EFIAPI
862 DevPathSerialScsi (
863 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
864 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
865 )
866 {
867 SCSI_DEVICE_PATH *Scsi;
868
869 ASSERT(DevicePathNode != NULL);
870 ASSERT(MappingItem != NULL);
871
872 Scsi = (SCSI_DEVICE_PATH *) DevicePathNode;
873 AppendCSDNum (MappingItem, Scsi->Pun);
874 AppendCSDNum (MappingItem, Scsi->Lun);
875 }
876
877 /**
878 DevicePathNode must be 1394 type and this will populate the MappingItem.
879
880 @param[in] DevicePathNode The node to get info on.
881 @param[in] MappingItem The info item to populate.
882 **/
883 VOID
884 EFIAPI
885 DevPathSerial1394 (
886 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
887 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
888 )
889 {
890 F1394_DEVICE_PATH *DevicePath_F1394;
891 CHAR16 Buffer[20];
892
893 ASSERT(DevicePathNode != NULL);
894 ASSERT(MappingItem != NULL);
895
896 DevicePath_F1394 = (F1394_DEVICE_PATH *) DevicePathNode;
897 UnicodeSPrint (Buffer, 0, L"%lx", DevicePath_F1394->Guid);
898 AppendCSDStr (MappingItem, Buffer);
899 }
900
901 /**
902 If the node is floppy type then populate the MappingItem.
903
904 @param[in] DevicePathNode The node to get info on.
905 @param[in] MappingItem The info item to populate.
906 **/
907 VOID
908 EFIAPI
909 DevPathSerialAcpi (
910 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
911 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
912 )
913 {
914 ACPI_HID_DEVICE_PATH *Acpi;
915
916 ASSERT(DevicePathNode != NULL);
917 ASSERT(MappingItem != NULL);
918
919 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;
920 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
921 if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
922 MappingItem->Mtd = MTDTypeFloppy;
923 AppendCSDNum (MappingItem, Acpi->UID);
924 }
925 }
926 }
927
928 /**
929 Empty function used for unknown devices.
930
931 @param[in] DevicePathNode Ignored.
932 @param[in] MappingItem Ignored.
933
934 Does nothing.
935 **/
936 VOID
937 EFIAPI
938 DevPathSerialDefault (
939 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
940 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
941 )
942 {
943 return;
944 }
945
946 DEV_PATH_CONSIST_MAPPING_TABLE DevPathConsistMappingTable[] = {
947 {
948 HARDWARE_DEVICE_PATH,
949 HW_PCI_DP,
950 DevPathSerialDefault,
951 DevPathComparePci
952 },
953 {
954 ACPI_DEVICE_PATH,
955 ACPI_DP,
956 DevPathSerialAcpi,
957 DevPathCompareAcpi
958 },
959 {
960 MESSAGING_DEVICE_PATH,
961 MSG_ATAPI_DP,
962 DevPathSerialAtapi,
963 DevPathCompareDefault
964 },
965 {
966 MESSAGING_DEVICE_PATH,
967 MSG_SCSI_DP,
968 DevPathSerialScsi,
969 DevPathCompareDefault
970 },
971 {
972 MESSAGING_DEVICE_PATH,
973 MSG_FIBRECHANNEL_DP,
974 DevPathSerialFibre,
975 DevPathCompareDefault
976 },
977 {
978 MESSAGING_DEVICE_PATH,
979 MSG_1394_DP,
980 DevPathSerial1394,
981 DevPathCompareDefault
982 },
983 {
984 MESSAGING_DEVICE_PATH,
985 MSG_USB_DP,
986 DevPathSerialUsb,
987 DevPathCompareDefault
988 },
989 {
990 MESSAGING_DEVICE_PATH,
991 MSG_I2O_DP,
992 DevPathSerialI2O,
993 DevPathCompareDefault
994 },
995 {
996 MESSAGING_DEVICE_PATH,
997 MSG_MAC_ADDR_DP,
998 DevPathSerialMacAddr,
999 DevPathCompareDefault
1000 },
1001 {
1002 MESSAGING_DEVICE_PATH,
1003 MSG_IPv4_DP,
1004 DevPathSerialIPv4,
1005 DevPathCompareDefault
1006 },
1007 {
1008 MESSAGING_DEVICE_PATH,
1009 MSG_IPv6_DP,
1010 DevPathSerialIPv6,
1011 DevPathCompareDefault
1012 },
1013 {
1014 MESSAGING_DEVICE_PATH,
1015 MSG_INFINIBAND_DP,
1016 DevPathSerialInfiniBand,
1017 DevPathCompareDefault
1018 },
1019 {
1020 MESSAGING_DEVICE_PATH,
1021 MSG_UART_DP,
1022 DevPathSerialUart,
1023 DevPathCompareDefault
1024 },
1025 {
1026 MESSAGING_DEVICE_PATH,
1027 MSG_VENDOR_DP,
1028 DevPathSerialVendor,
1029 DevPathCompareDefault
1030 },
1031 {
1032 MESSAGING_DEVICE_PATH,
1033 MSG_DEVICE_LOGICAL_UNIT_DP,
1034 DevPathSerialLun,
1035 DevPathCompareDefault
1036 },
1037 {
1038 MESSAGING_DEVICE_PATH,
1039 MSG_SATA_DP,
1040 DevPathSerialSata,
1041 DevPathCompareDefault
1042 },
1043 {
1044 MESSAGING_DEVICE_PATH,
1045 MSG_ISCSI_DP,
1046 DevPathSerialIScsi,
1047 DevPathCompareDefault
1048 },
1049 {
1050 MEDIA_DEVICE_PATH,
1051 MEDIA_HARDDRIVE_DP,
1052 DevPathSerialHardDrive,
1053 DevPathCompareDefault
1054 },
1055 {
1056 MEDIA_DEVICE_PATH,
1057 MEDIA_CDROM_DP,
1058 DevPathSerialCdRom,
1059 DevPathCompareDefault
1060 },
1061 {
1062 MEDIA_DEVICE_PATH,
1063 MEDIA_VENDOR_DP,
1064 DevPathSerialVendor,
1065 DevPathCompareDefault
1066 },
1067 {
1068 0,
1069 0,
1070 NULL,
1071 NULL
1072 }
1073 };
1074
1075 /**
1076 Function to determine if a device path node is Hi or not.
1077
1078 @param[in] DevicePathNode The node to check.
1079
1080 @retval TRUE The node is Hi.
1081 @retval FALSE The node is not Hi.
1082 **/
1083 BOOLEAN
1084 EFIAPI
1085 IsHIDevicePathNode (
1086 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
1087 )
1088 {
1089 ACPI_HID_DEVICE_PATH *Acpi;
1090
1091 ASSERT(DevicePathNode != NULL);
1092
1093 if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) {
1094 return TRUE;
1095 }
1096
1097 if (DevicePathNode->Type == ACPI_DEVICE_PATH) {
1098 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;
1099 switch (EISA_ID_TO_NUM (Acpi->HID)) {
1100 case 0x0301:
1101 case 0x0401:
1102 case 0x0501:
1103 case 0x0604:
1104 return FALSE;
1105 }
1106
1107 return TRUE;
1108 }
1109
1110 return FALSE;
1111 }
1112
1113 /**
1114 Function to convert a standard device path structure into a Hi version.
1115
1116 @param[in] DevicePath The device path to convert.
1117
1118 @return the device path portion that is Hi.
1119 **/
1120 EFI_DEVICE_PATH_PROTOCOL *
1121 EFIAPI
1122 GetHIDevicePath (
1123 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
1124 )
1125 {
1126 UINTN NonHIDevicePathNodeCount;
1127 UINTN Index;
1128 EFI_DEV_PATH Node;
1129 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1130 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
1131
1132 ASSERT(DevicePath != NULL);
1133
1134 NonHIDevicePathNodeCount = 0;
1135
1136 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
1137 SetDevicePathEndNode (HIDevicePath);
1138
1139 Node.DevPath.Type = END_DEVICE_PATH_TYPE;
1140 Node.DevPath.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
1141 Node.DevPath.Length[0] = (UINT8)sizeof (EFI_DEVICE_PATH_PROTOCOL);
1142 Node.DevPath.Length[1] = 0;
1143
1144 while (!IsDevicePathEnd (DevicePath)) {
1145 if (IsHIDevicePathNode (DevicePath)) {
1146 for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) {
1147 TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath);
1148 FreePool (HIDevicePath);
1149 HIDevicePath = TempDevicePath;
1150 }
1151
1152 TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath);
1153 FreePool (HIDevicePath);
1154 HIDevicePath = TempDevicePath;
1155 } else {
1156 NonHIDevicePathNodeCount++;
1157 }
1158 //
1159 // Next device path node
1160 //
1161 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);
1162 }
1163
1164 return HIDevicePath;
1165 }
1166
1167 /**
1168 Function to walk the device path looking for a dumpable node.
1169
1170 @param[in] MappingItem The Item to fill with data.
1171 @param[in] DevicePath The path of the item to get data on.
1172
1173 @return EFI_SUCCESS Always returns success.
1174 **/
1175 EFI_STATUS
1176 EFIAPI
1177 GetDeviceConsistMappingInfo (
1178 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,
1179 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
1180 )
1181 {
1182 VOID (EFIAPI *SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);
1183
1184 UINTN Index;
1185
1186 ASSERT(DevicePath != NULL);
1187 ASSERT(MappingItem != NULL);
1188
1189 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);
1190
1191 while (!IsDevicePathEnd (DevicePath)) {
1192 //
1193 // Find the handler to dump this device path node
1194 //
1195 SerialFun = NULL;
1196 for (Index = 0; DevPathConsistMappingTable[Index].SerialFun != NULL; Index += 1) {
1197
1198 if (DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type &&
1199 DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType
1200 ) {
1201 SerialFun = DevPathConsistMappingTable[Index].SerialFun;
1202 break;
1203 }
1204 }
1205 //
1206 // If not found, use a generic function
1207 //
1208 if (!SerialFun) {
1209 SerialFun = DevPathSerialDefault;
1210 }
1211
1212 SerialFun (DevicePath, MappingItem);
1213
1214 //
1215 // Next device path node
1216 //
1217 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);
1218 }
1219
1220 return EFI_SUCCESS;
1221 }
1222
1223 /**
1224 Function to initialize the table for creating consistent map names.
1225
1226 @param[out] Table The pointer to pointer to pointer to DevicePathProtocol object.
1227
1228 @retval EFI_SUCCESS The table was created successfully.
1229 **/
1230 EFI_STATUS
1231 EFIAPI
1232 ShellCommandConsistMappingInitialize (
1233 OUT EFI_DEVICE_PATH_PROTOCOL ***Table
1234 )
1235 {
1236 EFI_HANDLE *HandleBuffer;
1237 UINTN HandleNum;
1238 UINTN HandleLoop;
1239 EFI_DEVICE_PATH_PROTOCOL **TempTable;
1240 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
1241 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1242 UINTN Index;
1243 EFI_STATUS Status;
1244
1245 HandleBuffer = NULL;
1246
1247 Status = gBS->LocateHandleBuffer (
1248 AllHandles,
1249 NULL,
1250 NULL,
1251 &HandleNum,
1252 &HandleBuffer
1253 );
1254 ASSERT_EFI_ERROR(Status);
1255
1256 TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *));
1257 if (TempTable == NULL) {
1258 return EFI_OUT_OF_RESOURCES;
1259 }
1260
1261 for (HandleLoop = 0 ; HandleLoop < HandleNum ; HandleLoop++) {
1262 DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]);
1263 if (DevicePath == NULL) {
1264 continue;
1265 }
1266
1267 HIDevicePath = GetHIDevicePath (DevicePath);
1268 if (HIDevicePath == NULL) {
1269 continue;
1270 }
1271
1272 for (Index = 0; TempTable[Index] != NULL; Index++) {
1273 if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) {
1274 FreePool (HIDevicePath);
1275 break;
1276 }
1277 }
1278
1279 if (TempTable[Index] == NULL) {
1280 TempTable[Index] = HIDevicePath;
1281 }
1282 }
1283
1284 for (Index = 0; TempTable[Index] != NULL; Index++);
1285 PerformQuickSort(TempTable, Index, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);
1286 *Table = TempTable;
1287
1288 if (HandleBuffer != NULL) {
1289 FreePool (HandleBuffer);
1290 }
1291
1292 return EFI_SUCCESS;
1293 }
1294
1295 /**
1296 Function to uninitialize the table for creating consistent map names.
1297
1298 The parameter must have been received from ShellCommandConsistMappingInitialize.
1299
1300 @param[out] Table The pointer to pointer to DevicePathProtocol object.
1301
1302 @retval EFI_SUCCESS The table was deleted successfully.
1303 **/
1304 EFI_STATUS
1305 EFIAPI
1306 ShellCommandConsistMappingUnInitialize (
1307 EFI_DEVICE_PATH_PROTOCOL **Table
1308 )
1309 {
1310 UINTN Index;
1311
1312 ASSERT(Table != NULL);
1313
1314 for (Index = 0; Table[Index] != NULL; Index++) {
1315 FreePool (Table[Index]);
1316 }
1317
1318 FreePool (Table);
1319 return EFI_SUCCESS;
1320 }
1321
1322 /**
1323 Create a consistent mapped name for the device specified by DevicePath
1324 based on the Table.
1325
1326 This must be called after ShellCommandConsistMappingInitialize() and
1327 before ShellCommandConsistMappingUnInitialize() is called.
1328
1329 @param[in] DevicePath The pointer to the dev path for the device.
1330 @param[in] Table The Table of mapping information.
1331
1332 @retval NULL A consistent mapped name could not be created.
1333 @return A pointer to a string allocated from pool with the device name.
1334 **/
1335 CHAR16 *
1336 EFIAPI
1337 ShellCommandConsistMappingGenMappingName (
1338 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1339 IN EFI_DEVICE_PATH_PROTOCOL **Table
1340 )
1341 {
1342 POOL_PRINT Str;
1343 DEVICE_CONSIST_MAPPING_INFO MappingInfo;
1344 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1345 UINTN Index;
1346 UINTN NewSize;
1347
1348 ASSERT(DevicePath != NULL);
1349 ASSERT(Table != NULL);
1350
1351 HIDevicePath = GetHIDevicePath (DevicePath);
1352 if (HIDevicePath == NULL) {
1353 return NULL;
1354 }
1355
1356 for (Index = 0; Table[Index] != NULL; Index++) {
1357 if (DevicePathCompare (&Table[Index], &HIDevicePath) == 0) {
1358 break;
1359 }
1360 }
1361
1362 FreePool (HIDevicePath);
1363 if (Table[Index] == NULL) {
1364 return NULL;
1365 }
1366
1367 MappingInfo.Hi = Index;
1368 MappingInfo.Mtd = MTDTypeUnknown;
1369 MappingInfo.Digital = FALSE;
1370
1371 GetDeviceConsistMappingInfo (&MappingInfo, DevicePath);
1372
1373 SetMem (&Str, sizeof (Str), 0);
1374 for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) {
1375 if (MappingInfo.Mtd == mMTDName[Index].MTDType) {
1376 break;
1377 }
1378 }
1379
1380 if (mMTDName[Index].MTDType != MTDTypeEnd) {
1381 CatPrint (&Str, L"%s", mMTDName[Index].Name);
1382 }
1383
1384 CatPrint (&Str, L"%d", (UINTN) MappingInfo.Hi);
1385 if (MappingInfo.Csd.Str != NULL) {
1386 CatPrint (&Str, L"%s", MappingInfo.Csd.Str);
1387 FreePool (MappingInfo.Csd.Str);
1388 }
1389
1390 if (Str.Str != NULL) {
1391 CatPrint (&Str, L":");
1392 }
1393
1394 NewSize = (Str.Len + 1) * sizeof (CHAR16);
1395 Str.Str = ReallocatePool (Str.Len, NewSize, Str.Str);
1396 if (Str.Str == NULL) {
1397 return (NULL);
1398 }
1399 Str.Str[Str.Len] = CHAR_NULL;
1400 return Str.Str;
1401 }
1402
1403 /**
1404 Function to search the list of mappings for the node on the list based on the key.
1405
1406 @param[in] MapKey String Key to search for on the map
1407
1408 @return the node on the list.
1409 **/
1410 SHELL_MAP_LIST *
1411 EFIAPI
1412 ShellCommandFindMapItem (
1413 IN CONST CHAR16 *MapKey
1414 )
1415 {
1416 SHELL_MAP_LIST *MapListItem;
1417
1418 for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
1419 ; !IsNull(&gShellMapList.Link, &MapListItem->Link)
1420 ; MapListItem = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &MapListItem->Link)
1421 ){
1422 if (gUnicodeCollation->StriColl(gUnicodeCollation,MapListItem->MapName,(CHAR16*)MapKey) == 0) {
1423 return (MapListItem);
1424 }
1425 }
1426 return (NULL);
1427 }
1428
1429