VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c@ 75265

Last change on this file since 75265 was 58459, checked in by vboxsync, 9 years ago

EFI/Firmware: 'svn merge /vendor/edk2/UDK2010.SR1 /vendor/edk2/current .', reverting and removing files+dirs listed in ReadMe.vbox, resolving conflicts with help from ../UDK2014.SP1/. This is a raw untested merge.

  • Property svn:eol-style set to native
File size: 34.3 KB
Line 
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
18typedef enum {
19 MTDTypeUnknown,
20 MTDTypeFloppy,
21 MTDTypeHardDisk,
22 MTDTypeCDRom,
23 MTDTypeEnd
24} MTD_TYPE;
25
26typedef struct {
27 CHAR16 *Str;
28 UINTN Len;
29} POOL_PRINT;
30
31typedef struct {
32 UINTN Hi;
33 MTD_TYPE Mtd;
34 POOL_PRINT Csd;
35 BOOLEAN Digital;
36} DEVICE_CONSIST_MAPPING_INFO;
37
38typedef struct {
39 MTD_TYPE MTDType;
40 CHAR16 *Name;
41} MTD_NAME;
42
43typedef 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**/
64CHAR16 *
65EFIAPI
66CatPrint (
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
108MTD_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**/
140EFI_STATUS
141EFIAPI
142AppendCSDNum2 (
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**/
172EFI_STATUS
173EFIAPI
174AppendCSDNum (
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**/
203EFI_STATUS
204EFIAPI
205AppendCSDStr (
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**/
290EFI_STATUS
291EFIAPI
292AppendCSDGuid (
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**/
324INTN
325EFIAPI
326DevPathCompareAcpi (
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**/
360INTN
361EFIAPI
362DevPathComparePci (
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**/
396INTN
397EFIAPI
398DevPathCompareDefault (
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**/
426VOID
427EFIAPI
428DevPathSerialHardDrive (
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**/
452VOID
453EFIAPI
454DevPathSerialAtapi (
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**/
474VOID
475EFIAPI
476DevPathSerialCdRom (
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**/
497VOID
498EFIAPI
499DevPathSerialFibre (
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**/
520VOID
521EFIAPI
522DevPathSerialUart (
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**/
545VOID
546EFIAPI
547DevPathSerialUsb (
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**/
569VOID
570EFIAPI
571DevPathSerialVendor (
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**/
601VOID
602EFIAPI
603DevPathSerialLun (
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**/
623VOID
624EFIAPI
625DevPathSerialSata (
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**/
647VOID
648EFIAPI
649DevPathSerialIScsi (
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**/
696VOID
697EFIAPI
698DevPathSerialI2O (
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**/
718VOID
719EFIAPI
720DevPathSerialMacAddr (
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**/
754VOID
755EFIAPI
756DevPathSerialInfiniBand (
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**/
786VOID
787EFIAPI
788DevPathSerialIPv4 (
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**/
830VOID
831EFIAPI
832DevPathSerialIPv6 (
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**/
866VOID
867EFIAPI
868DevPathSerialScsi (
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**/
889VOID
890EFIAPI
891DevPathSerial1394 (
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**/
913VOID
914EFIAPI
915DevPathSerialAcpi (
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**/
942VOID
943EFIAPI
944DevPathSerialDefault (
945 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
946 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem
947 )
948{
949 return;
950}
951
952DEV_PATH_CONSIST_MAPPING_TABLE DevPathConsistMappingTable[] = {
953 {
954 HARDWARE_DEVICE_PATH,
955 HW_PCI_DP,
956 DevPathSerialDefault,
957 DevPathComparePci
958 },
959 {
960 ACPI_DEVICE_PATH,
961 ACPI_DP,
962 DevPathSerialAcpi,
963 DevPathCompareAcpi
964 },
965 {
966 MESSAGING_DEVICE_PATH,
967 MSG_ATAPI_DP,
968 DevPathSerialAtapi,
969 DevPathCompareDefault
970 },
971 {
972 MESSAGING_DEVICE_PATH,
973 MSG_SCSI_DP,
974 DevPathSerialScsi,
975 DevPathCompareDefault
976 },
977 {
978 MESSAGING_DEVICE_PATH,
979 MSG_FIBRECHANNEL_DP,
980 DevPathSerialFibre,
981 DevPathCompareDefault
982 },
983 {
984 MESSAGING_DEVICE_PATH,
985 MSG_1394_DP,
986 DevPathSerial1394,
987 DevPathCompareDefault
988 },
989 {
990 MESSAGING_DEVICE_PATH,
991 MSG_USB_DP,
992 DevPathSerialUsb,
993 DevPathCompareDefault
994 },
995 {
996 MESSAGING_DEVICE_PATH,
997 MSG_I2O_DP,
998 DevPathSerialI2O,
999 DevPathCompareDefault
1000 },
1001 {
1002 MESSAGING_DEVICE_PATH,
1003 MSG_MAC_ADDR_DP,
1004 DevPathSerialMacAddr,
1005 DevPathCompareDefault
1006 },
1007 {
1008 MESSAGING_DEVICE_PATH,
1009 MSG_IPv4_DP,
1010 DevPathSerialIPv4,
1011 DevPathCompareDefault
1012 },
1013 {
1014 MESSAGING_DEVICE_PATH,
1015 MSG_IPv6_DP,
1016 DevPathSerialIPv6,
1017 DevPathCompareDefault
1018 },
1019 {
1020 MESSAGING_DEVICE_PATH,
1021 MSG_INFINIBAND_DP,
1022 DevPathSerialInfiniBand,
1023 DevPathCompareDefault
1024 },
1025 {
1026 MESSAGING_DEVICE_PATH,
1027 MSG_UART_DP,
1028 DevPathSerialUart,
1029 DevPathCompareDefault
1030 },
1031 {
1032 MESSAGING_DEVICE_PATH,
1033 MSG_VENDOR_DP,
1034 DevPathSerialVendor,
1035 DevPathCompareDefault
1036 },
1037 {
1038 MESSAGING_DEVICE_PATH,
1039 MSG_DEVICE_LOGICAL_UNIT_DP,
1040 DevPathSerialLun,
1041 DevPathCompareDefault
1042 },
1043 {
1044 MESSAGING_DEVICE_PATH,
1045 MSG_SATA_DP,
1046 DevPathSerialSata,
1047 DevPathCompareDefault
1048 },
1049 {
1050 MESSAGING_DEVICE_PATH,
1051 MSG_ISCSI_DP,
1052 DevPathSerialIScsi,
1053 DevPathCompareDefault
1054 },
1055 {
1056 MEDIA_DEVICE_PATH,
1057 MEDIA_HARDDRIVE_DP,
1058 DevPathSerialHardDrive,
1059 DevPathCompareDefault
1060 },
1061 {
1062 MEDIA_DEVICE_PATH,
1063 MEDIA_CDROM_DP,
1064 DevPathSerialCdRom,
1065 DevPathCompareDefault
1066 },
1067 {
1068 MEDIA_DEVICE_PATH,
1069 MEDIA_VENDOR_DP,
1070 DevPathSerialVendor,
1071 DevPathCompareDefault
1072 },
1073 {
1074 0,
1075 0,
1076 NULL,
1077 NULL
1078 }
1079};
1080
1081/**
1082 Function to determine if a device path node is Hi or not.
1083
1084 @param[in] DevicePathNode The node to check.
1085
1086 @retval TRUE The node is Hi.
1087 @retval FALSE The node is not Hi.
1088**/
1089BOOLEAN
1090EFIAPI
1091IsHIDevicePathNode (
1092 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
1093 )
1094{
1095 ACPI_HID_DEVICE_PATH *Acpi;
1096
1097 ASSERT(DevicePathNode != NULL);
1098
1099 if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) {
1100 return TRUE;
1101 }
1102
1103 if (DevicePathNode->Type == ACPI_DEVICE_PATH) {
1104 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;
1105 switch (EISA_ID_TO_NUM (Acpi->HID)) {
1106 case 0x0301:
1107 case 0x0401:
1108 case 0x0501:
1109 case 0x0604:
1110 return FALSE;
1111 }
1112
1113 return TRUE;
1114 }
1115
1116 return FALSE;
1117}
1118
1119/**
1120 Function to convert a standard device path structure into a Hi version.
1121
1122 @param[in] DevicePath The device path to convert.
1123
1124 @return the device path portion that is Hi.
1125**/
1126EFI_DEVICE_PATH_PROTOCOL *
1127EFIAPI
1128GetHIDevicePath (
1129 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
1130 )
1131{
1132 UINTN NonHIDevicePathNodeCount;
1133 UINTN Index;
1134 EFI_DEV_PATH Node;
1135 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1136 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
1137
1138 ASSERT(DevicePath != NULL);
1139
1140 NonHIDevicePathNodeCount = 0;
1141
1142 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
1143 SetDevicePathEndNode (HIDevicePath);
1144
1145 Node.DevPath.Type = END_DEVICE_PATH_TYPE;
1146 Node.DevPath.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
1147 Node.DevPath.Length[0] = (UINT8)sizeof (EFI_DEVICE_PATH_PROTOCOL);
1148 Node.DevPath.Length[1] = 0;
1149
1150 while (!IsDevicePathEnd (DevicePath)) {
1151 if (IsHIDevicePathNode (DevicePath)) {
1152 for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) {
1153 TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath);
1154 FreePool (HIDevicePath);
1155 HIDevicePath = TempDevicePath;
1156 }
1157
1158 TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath);
1159 FreePool (HIDevicePath);
1160 HIDevicePath = TempDevicePath;
1161 } else {
1162 NonHIDevicePathNodeCount++;
1163 }
1164 //
1165 // Next device path node
1166 //
1167 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);
1168 }
1169
1170 return HIDevicePath;
1171}
1172
1173/**
1174 Function to walk the device path looking for a dumpable node.
1175
1176 @param[in] MappingItem The Item to fill with data.
1177 @param[in] DevicePath The path of the item to get data on.
1178
1179 @return EFI_SUCCESS Always returns success.
1180**/
1181EFI_STATUS
1182EFIAPI
1183GetDeviceConsistMappingInfo (
1184 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,
1185 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
1186 )
1187{
1188 VOID (EFIAPI *SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);
1189
1190 UINTN Index;
1191
1192 ASSERT(DevicePath != NULL);
1193 ASSERT(MappingItem != NULL);
1194
1195 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);
1196
1197 while (!IsDevicePathEnd (DevicePath)) {
1198 //
1199 // Find the handler to dump this device path node
1200 //
1201 SerialFun = NULL;
1202 for (Index = 0; DevPathConsistMappingTable[Index].SerialFun != NULL; Index += 1) {
1203
1204 if (DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type &&
1205 DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType
1206 ) {
1207 SerialFun = DevPathConsistMappingTable[Index].SerialFun;
1208 break;
1209 }
1210 }
1211 //
1212 // If not found, use a generic function
1213 //
1214 if (!SerialFun) {
1215 SerialFun = DevPathSerialDefault;
1216 }
1217
1218 SerialFun (DevicePath, MappingItem);
1219
1220 //
1221 // Next device path node
1222 //
1223 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);
1224 }
1225
1226 return EFI_SUCCESS;
1227}
1228
1229/**
1230 Function to initialize the table for creating consistent map names.
1231
1232 @param[out] Table The pointer to pointer to pointer to DevicePathProtocol object.
1233
1234 @retval EFI_SUCCESS The table was created successfully.
1235**/
1236EFI_STATUS
1237EFIAPI
1238ShellCommandConsistMappingInitialize (
1239 OUT EFI_DEVICE_PATH_PROTOCOL ***Table
1240 )
1241{
1242 EFI_HANDLE *HandleBuffer;
1243 UINTN HandleNum;
1244 UINTN HandleLoop;
1245 EFI_DEVICE_PATH_PROTOCOL **TempTable;
1246 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
1247 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1248 UINTN Index;
1249 EFI_STATUS Status;
1250
1251 HandleBuffer = NULL;
1252
1253 Status = gBS->LocateHandleBuffer (
1254 AllHandles,
1255 NULL,
1256 NULL,
1257 &HandleNum,
1258 &HandleBuffer
1259 );
1260 ASSERT_EFI_ERROR(Status);
1261
1262 TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *));
1263 if (TempTable == NULL) {
1264 return EFI_OUT_OF_RESOURCES;
1265 }
1266
1267 for (HandleLoop = 0 ; HandleLoop < HandleNum ; HandleLoop++) {
1268 DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]);
1269 if (DevicePath == NULL) {
1270 continue;
1271 }
1272
1273 HIDevicePath = GetHIDevicePath (DevicePath);
1274 if (HIDevicePath == NULL) {
1275 continue;
1276 }
1277
1278 for (Index = 0; TempTable[Index] != NULL; Index++) {
1279 if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) {
1280 FreePool (HIDevicePath);
1281 break;
1282 }
1283 }
1284
1285 if (TempTable[Index] == NULL) {
1286 TempTable[Index] = HIDevicePath;
1287 }
1288 }
1289
1290 for (Index = 0; TempTable[Index] != NULL; Index++);
1291 PerformQuickSort(TempTable, Index, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);
1292 *Table = TempTable;
1293
1294 if (HandleBuffer != NULL) {
1295 FreePool (HandleBuffer);
1296 }
1297
1298 return EFI_SUCCESS;
1299}
1300
1301/**
1302 Function to uninitialize the table for creating consistent map names.
1303
1304 The parameter must have been received from ShellCommandConsistMappingInitialize.
1305
1306 @param[out] Table The pointer to pointer to DevicePathProtocol object.
1307
1308 @retval EFI_SUCCESS The table was deleted successfully.
1309**/
1310EFI_STATUS
1311EFIAPI
1312ShellCommandConsistMappingUnInitialize (
1313 EFI_DEVICE_PATH_PROTOCOL **Table
1314 )
1315{
1316 UINTN Index;
1317
1318 ASSERT(Table != NULL);
1319
1320 for (Index = 0; Table[Index] != NULL; Index++) {
1321 FreePool (Table[Index]);
1322 }
1323
1324 FreePool (Table);
1325 return EFI_SUCCESS;
1326}
1327
1328/**
1329 Create a consistent mapped name for the device specified by DevicePath
1330 based on the Table.
1331
1332 This must be called after ShellCommandConsistMappingInitialize() and
1333 before ShellCommandConsistMappingUnInitialize() is called.
1334
1335 @param[in] DevicePath The pointer to the dev path for the device.
1336 @param[in] Table The Table of mapping information.
1337
1338 @retval NULL A consistent mapped name could not be created.
1339 @return A pointer to a string allocated from pool with the device name.
1340**/
1341CHAR16 *
1342EFIAPI
1343ShellCommandConsistMappingGenMappingName (
1344 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1345 IN EFI_DEVICE_PATH_PROTOCOL **Table
1346 )
1347{
1348 POOL_PRINT Str;
1349 DEVICE_CONSIST_MAPPING_INFO MappingInfo;
1350 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;
1351 UINTN Index;
1352 UINTN NewSize;
1353
1354 ASSERT(DevicePath != NULL);
1355 ASSERT(Table != NULL);
1356
1357 HIDevicePath = GetHIDevicePath (DevicePath);
1358 if (HIDevicePath == NULL) {
1359 return NULL;
1360 }
1361
1362 for (Index = 0; Table[Index] != NULL; Index++) {
1363 if (DevicePathCompare (&Table[Index], &HIDevicePath) == 0) {
1364 break;
1365 }
1366 }
1367
1368 FreePool (HIDevicePath);
1369 if (Table[Index] == NULL) {
1370 return NULL;
1371 }
1372
1373 MappingInfo.Hi = Index;
1374 MappingInfo.Mtd = MTDTypeUnknown;
1375 MappingInfo.Digital = FALSE;
1376
1377 GetDeviceConsistMappingInfo (&MappingInfo, DevicePath);
1378
1379 SetMem (&Str, sizeof (Str), 0);
1380 for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) {
1381 if (MappingInfo.Mtd == mMTDName[Index].MTDType) {
1382 break;
1383 }
1384 }
1385
1386 if (mMTDName[Index].MTDType != MTDTypeEnd) {
1387 CatPrint (&Str, L"%s", mMTDName[Index].Name);
1388 }
1389
1390 CatPrint (&Str, L"%d", (UINTN) MappingInfo.Hi);
1391 if (MappingInfo.Csd.Str != NULL) {
1392 CatPrint (&Str, L"%s", MappingInfo.Csd.Str);
1393 FreePool (MappingInfo.Csd.Str);
1394 }
1395
1396 if (Str.Str != NULL) {
1397 CatPrint (&Str, L":");
1398 }
1399
1400 NewSize = (Str.Len + 1) * sizeof (CHAR16);
1401 Str.Str = ReallocatePool (Str.Len, NewSize, Str.Str);
1402 if (Str.Str == NULL) {
1403 return (NULL);
1404 }
1405 Str.Str[Str.Len] = CHAR_NULL;
1406 return Str.Str;
1407}
1408
1409/**
1410 Function to search the list of mappings for the node on the list based on the key.
1411
1412 @param[in] MapKey String Key to search for on the map
1413
1414 @return the node on the list.
1415**/
1416SHELL_MAP_LIST *
1417EFIAPI
1418ShellCommandFindMapItem (
1419 IN CONST CHAR16 *MapKey
1420 )
1421{
1422 SHELL_MAP_LIST *MapListItem;
1423
1424 for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)
1425 ; !IsNull(&gShellMapList.Link, &MapListItem->Link)
1426 ; MapListItem = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &MapListItem->Link)
1427 ){
1428 if (gUnicodeCollation->StriColl(gUnicodeCollation,MapListItem->MapName,(CHAR16*)MapKey) == 0) {
1429 return (MapListItem);
1430 }
1431 }
1432 return (NULL);
1433}
1434
1435
Note: See TracBrowser for help on using the repository browser.

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