]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/SecureBootConfigDxe/SecureBootConfigDevicePath.c
ae44626594f223abebfa407ebd0d8b9a2d8ddbd7
[mirror_edk2.git] / OvmfPkg / SecureBootConfigDxe / SecureBootConfigDevicePath.c
1 /** @file
2 Internal function defines the default device path string for SecureBoot configuration module.
3
4 Copyright (c) 2012, 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
15 #include "SecureBootConfigImpl.h"
16
17 /**
18 Concatenates a formatted unicode string to allocated pool.
19 The caller must free the resulting buffer.
20
21 @param[in, out] Str Tracks the allocated pool, size in use, and amount of pool allocated.
22 @param[in] Fmt The format string
23 @param[in] ... The data will be printed.
24
25 @return Allocated buffer with the formatted string printed in it.
26 The caller must free the allocated buffer.
27 The buffer allocation is not packed.
28
29 **/
30 CHAR16 *
31 EFIAPI
32 CatPrint (
33 IN OUT POOL_PRINT *Str,
34 IN CHAR16 *Fmt,
35 ...
36 )
37 {
38 UINT16 *AppendStr;
39 VA_LIST Args;
40 UINTN StringSize;
41
42 AppendStr = AllocateZeroPool (0x1000);
43 if (AppendStr == NULL) {
44 return Str->Str;
45 }
46
47 VA_START (Args, Fmt);
48 UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);
49 VA_END (Args);
50 if (NULL == Str->Str) {
51 StringSize = StrSize (AppendStr);
52 Str->Str = AllocateZeroPool (StringSize);
53 ASSERT (Str->Str != NULL);
54 } else {
55 StringSize = StrSize (AppendStr);
56 StringSize += (StrSize (Str->Str) - sizeof (UINT16));
57
58 Str->Str = ReallocatePool (
59 StrSize (Str->Str),
60 StringSize,
61 Str->Str
62 );
63 ASSERT (Str->Str != NULL);
64 }
65
66 Str->Maxlen = MAX_CHAR * sizeof (UINT16);
67 if (StringSize < Str->Maxlen) {
68 StrCat (Str->Str, AppendStr);
69 Str->Len = StringSize - sizeof (UINT16);
70 }
71
72 FreePool (AppendStr);
73 return Str->Str;
74 }
75
76 /**
77 Convert Device Path to a Unicode string for printing.
78
79 @param[in, out] Str The buffer holding the output string.
80 This buffer contains the length of the string and
81 the maixmum length reserved for the string buffer.
82 @param[in] DevPath The device path.
83
84 **/
85 VOID
86 DevPathPci (
87 IN OUT POOL_PRINT *Str,
88 IN VOID *DevPath
89 )
90 {
91 PCI_DEVICE_PATH *Pci;
92
93 Pci = DevPath;
94 CatPrint (Str, L"Pci(%x|%x)", (UINTN) Pci->Device, (UINTN) Pci->Function);
95 }
96
97 /**
98 Convert Device Path to a Unicode string for printing.
99
100 @param[in, out] Str The buffer holding the output string.
101 This buffer contains the length of the string and
102 the maixmum length reserved for the string buffer.
103 @param[in] DevPath The device path.
104
105 **/
106 VOID
107 DevPathPccard (
108 IN OUT POOL_PRINT *Str,
109 IN VOID *DevPath
110 )
111 {
112 PCCARD_DEVICE_PATH *Pccard;
113
114 Pccard = DevPath;
115 CatPrint (Str, L"Pcmcia(Function%x)", (UINTN) Pccard->FunctionNumber);
116 }
117
118 /**
119 Convert Device Path to a Unicode string for printing.
120
121 @param[in, out] Str The buffer holding the output string.
122 This buffer contains the length of the string and
123 the maixmum length reserved for the string buffer.
124 @param[in] DevPath The device path.
125
126 **/
127 VOID
128 DevPathMemMap (
129 IN OUT POOL_PRINT *Str,
130 IN VOID *DevPath
131 )
132 {
133 MEMMAP_DEVICE_PATH *MemMap;
134
135 MemMap = DevPath;
136 CatPrint (
137 Str,
138 L"MemMap(%d:%lx-%lx)",
139 (UINTN) MemMap->MemoryType,
140 MemMap->StartingAddress,
141 MemMap->EndingAddress
142 );
143 }
144
145 /**
146 Convert Device Path to a Unicode string for printing.
147
148 @param[in, out] Str The buffer holding the output string.
149 This buffer contains the length of the string and
150 the maixmum length reserved for the string buffer.
151 @param[in] DevPath The device path.
152
153 **/
154 VOID
155 DevPathController (
156 IN OUT POOL_PRINT *Str,
157 IN VOID *DevPath
158 )
159 {
160 CONTROLLER_DEVICE_PATH *Controller;
161
162 Controller = DevPath;
163 CatPrint (Str, L"Ctrl(%d)", (UINTN) Controller->ControllerNumber);
164 }
165
166
167 /**
168 Convert Vendor device path to device name.
169
170 @param[in, out] Str The buffer store device name
171 @param[in] DevPath Pointer to vendor device path
172
173 **/
174 VOID
175 DevPathVendor (
176 IN OUT POOL_PRINT *Str,
177 IN VOID *DevPath
178 )
179 {
180 VENDOR_DEVICE_PATH *Vendor;
181 CHAR16 *Type;
182 UINTN DataLength;
183 UINTN Index;
184 UINT32 FlowControlMap;
185
186 UINT16 Info;
187
188 Vendor = DevPath;
189
190 switch (DevicePathType (&Vendor->Header)) {
191 case HARDWARE_DEVICE_PATH:
192 Type = L"Hw";
193 break;
194
195 case MESSAGING_DEVICE_PATH:
196 Type = L"Msg";
197 if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
198 CatPrint (Str, L"VenPcAnsi()");
199 return ;
200 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
201 CatPrint (Str, L"VenVt100()");
202 return ;
203 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
204 CatPrint (Str, L"VenVt100Plus()");
205 return ;
206 } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
207 CatPrint (Str, L"VenUft8()");
208 return ;
209 } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid )) {
210 FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
211 switch (FlowControlMap & 0x00000003) {
212 case 0:
213 CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
214 break;
215
216 case 1:
217 CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
218 break;
219
220 case 2:
221 CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
222 break;
223
224 default:
225 break;
226 }
227
228 return ;
229
230 } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {
231 CatPrint (
232 Str,
233 L"SAS(%lx,%lx,%x,",
234 ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
235 ((SAS_DEVICE_PATH *) Vendor)->Lun,
236 (UINTN) ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
237 );
238 Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
239 if ((Info & 0x0f) == 0) {
240 CatPrint (Str, L"NoTopology,0,0,0,");
241 } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {
242 CatPrint (
243 Str,
244 L"%s,%s,%s,",
245 ((Info & (0x1 << 4)) != 0) ? L"SATA" : L"SAS",
246 ((Info & (0x1 << 5)) != 0) ? L"External" : L"Internal",
247 ((Info & (0x1 << 6)) != 0) ? L"Expanded" : L"Direct"
248 );
249 if ((Info & 0x0f) == 1) {
250 CatPrint (Str, L"0,");
251 } else {
252 CatPrint (Str, L"%x,", (UINTN) ((Info >> 8) & 0xff));
253 }
254 } else {
255 CatPrint (Str, L"0,0,0,0,");
256 }
257
258 CatPrint (Str, L"%x)", (UINTN) ((SAS_DEVICE_PATH *) Vendor)->Reserved);
259 return ;
260
261 } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
262 CatPrint (Str, L"DebugPort()");
263 return ;
264 }
265 break;
266
267 case MEDIA_DEVICE_PATH:
268 Type = L"Media";
269 break;
270
271 default:
272 Type = L"?";
273 break;
274 }
275
276 CatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);
277 DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
278 if (DataLength > 0) {
279 CatPrint (Str, L",");
280 for (Index = 0; Index < DataLength; Index++) {
281 CatPrint (Str, L"%02x", (UINTN) ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
282 }
283 }
284 CatPrint (Str, L")");
285 }
286
287 /**
288 Convert Device Path to a Unicode string for printing.
289
290 @param[in, out] Str The buffer holding the output string.
291 This buffer contains the length of the string and
292 the maixmum length reserved for the string buffer.
293 @param[in] DevPath The device path.
294
295 **/
296 VOID
297 DevPathAcpi (
298 IN OUT POOL_PRINT *Str,
299 IN VOID *DevPath
300 )
301 {
302 ACPI_HID_DEVICE_PATH *Acpi;
303
304 Acpi = DevPath;
305 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
306 CatPrint (Str, L"Acpi(PNP%04x,%x)", (UINTN) EISA_ID_TO_NUM (Acpi->HID), (UINTN) Acpi->UID);
307 } else {
308 CatPrint (Str, L"Acpi(%08x,%x)", (UINTN) Acpi->HID, (UINTN) Acpi->UID);
309 }
310 }
311
312 /**
313 Convert Device Path to a Unicode string for printing.
314
315 @param[in, out] Str The buffer holding the output string.
316 This buffer contains the length of the string and
317 the maixmum length reserved for the string buffer.
318 @param[in] DevPath The device path.
319
320 **/
321 VOID
322 DevPathExtendedAcpi (
323 IN OUT POOL_PRINT *Str,
324 IN VOID *DevPath
325 )
326 {
327 ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
328
329 //
330 // Index for HID, UID and CID strings, 0 for non-exist
331 //
332 UINT16 HIDSTRIdx;
333 UINT16 UIDSTRIdx;
334 UINT16 CIDSTRIdx;
335 UINT16 Index;
336 UINT16 Length;
337 UINT16 Anchor;
338 CHAR8 *AsChar8Array;
339
340 HIDSTRIdx = 0;
341 UIDSTRIdx = 0;
342 CIDSTRIdx = 0;
343 ExtendedAcpi = DevPath;
344 Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) ExtendedAcpi);
345
346 AsChar8Array = (CHAR8 *) ExtendedAcpi;
347
348 //
349 // find HIDSTR
350 //
351 Anchor = 16;
352 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {
353 ;
354 }
355 if (Index > Anchor) {
356 HIDSTRIdx = Anchor;
357 }
358 //
359 // find UIDSTR
360 //
361 Anchor = (UINT16) (Index + 1);
362 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {
363 ;
364 }
365 if (Index > Anchor) {
366 UIDSTRIdx = Anchor;
367 }
368 //
369 // find CIDSTR
370 //
371 Anchor = (UINT16) (Index + 1);
372 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {
373 ;
374 }
375 if (Index > Anchor) {
376 CIDSTRIdx = Anchor;
377 }
378
379 if (HIDSTRIdx == 0 && CIDSTRIdx == 0 && ExtendedAcpi->UID == 0) {
380 CatPrint (Str, L"AcpiExp(");
381 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
382 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));
383 } else {
384 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);
385 }
386 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
387 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));
388 } else {
389 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);
390 }
391 if (UIDSTRIdx != 0) {
392 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
393 } else {
394 CatPrint (Str, L"\"\")");
395 }
396 } else {
397 CatPrint (Str, L"AcpiEx(");
398 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
399 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));
400 } else {
401 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);
402 }
403 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
404 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));
405 } else {
406 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);
407 }
408 CatPrint (Str, L"%x,", (UINTN) ExtendedAcpi->UID);
409
410 if (HIDSTRIdx != 0) {
411 CatPrint (Str, L"%a,", AsChar8Array + HIDSTRIdx);
412 } else {
413 CatPrint (Str, L"\"\",");
414 }
415 if (CIDSTRIdx != 0) {
416 CatPrint (Str, L"%a,", AsChar8Array + CIDSTRIdx);
417 } else {
418 CatPrint (Str, L"\"\",");
419 }
420 if (UIDSTRIdx != 0) {
421 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
422 } else {
423 CatPrint (Str, L"\"\")");
424 }
425 }
426
427 }
428
429 /**
430 Convert Device Path to a Unicode string for printing.
431
432 @param[in, out] Str The buffer holding the output string.
433 This buffer contains the length of the string and
434 the maixmum length reserved for the string buffer.
435 @param[in] DevPath The device path.
436
437 **/
438 VOID
439 DevPathAdrAcpi (
440 IN OUT POOL_PRINT *Str,
441 IN VOID *DevPath
442 )
443 {
444 ACPI_ADR_DEVICE_PATH *AcpiAdr;
445 UINT16 Index;
446 UINT16 Length;
447 UINT16 AdditionalAdrCount;
448
449 AcpiAdr = DevPath;
450 Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
451 AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
452
453 CatPrint (Str, L"AcpiAdr(%x", (UINTN) AcpiAdr->ADR);
454 for (Index = 0; Index < AdditionalAdrCount; Index++) {
455 CatPrint (Str, L",%x", (UINTN) *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));
456 }
457 CatPrint (Str, L")");
458 }
459
460 /**
461 Convert Device Path to a Unicode string for printing.
462
463 @param[in, out] Str The buffer holding the output string.
464 This buffer contains the length of the string and
465 the maixmum length reserved for the string buffer.
466 @param[in] DevPath The device path.
467
468 **/
469 VOID
470 DevPathAtapi (
471 IN OUT POOL_PRINT *Str,
472 IN VOID *DevPath
473 )
474 {
475 ATAPI_DEVICE_PATH *Atapi;
476
477 Atapi = DevPath;
478 CatPrint (
479 Str,
480 L"Ata(%s,%s)",
481 (Atapi->PrimarySecondary != 0)? L"Secondary" : L"Primary",
482 (Atapi->SlaveMaster != 0)? L"Slave" : L"Master"
483 );
484 }
485
486 /**
487 Convert Device Path to a Unicode string for printing.
488
489 @param[in, out] Str The buffer holding the output string.
490 This buffer contains the length of the string and
491 the maixmum length reserved for the string buffer.
492 @param[in] DevPath The device path.
493
494 **/
495 VOID
496 DevPathScsi (
497 IN OUT POOL_PRINT *Str,
498 IN VOID *DevPath
499 )
500 {
501 SCSI_DEVICE_PATH *Scsi;
502
503 Scsi = DevPath;
504 CatPrint (Str, L"Scsi(Pun%x,Lun%x)", (UINTN) Scsi->Pun, (UINTN) Scsi->Lun);
505 }
506
507 /**
508 Convert Device Path to a Unicode string for printing.
509
510 @param[in, out] Str The buffer holding the output string.
511 This buffer contains the length of the string and
512 the maixmum length reserved for the string buffer.
513 @param[in] DevPath The device path.
514
515 **/
516 VOID
517 DevPathFibre (
518 IN OUT POOL_PRINT *Str,
519 IN VOID *DevPath
520 )
521 {
522 FIBRECHANNEL_DEVICE_PATH *Fibre;
523
524 Fibre = DevPath;
525 CatPrint (Str, L"Fibre(Wwn%lx,Lun%x)", Fibre->WWN, Fibre->Lun);
526 }
527
528 /**
529 Convert Device Path to a Unicode string for printing.
530
531 @param[in, out] Str The buffer holding the output string.
532 This buffer contains the length of the string and
533 the maixmum length reserved for the string buffer.
534 @param[in] DevPath The device path.
535
536 **/
537 VOID
538 DevPath1394 (
539 IN OUT POOL_PRINT *Str,
540 IN VOID *DevPath
541 )
542 {
543 F1394_DEVICE_PATH *F1394Path;
544
545 F1394Path = DevPath;
546 CatPrint (Str, L"1394(%lx)", &F1394Path->Guid);
547 }
548
549 /**
550 Convert Device Path to a Unicode string for printing.
551
552 @param[in, out] Str The buffer holding the output string.
553 This buffer contains the length of the string and
554 the maixmum length reserved for the string buffer.
555 @param[in] DevPath The device path.
556
557 **/
558 VOID
559 DevPathUsb (
560 IN OUT POOL_PRINT *Str,
561 IN VOID *DevPath
562 )
563 {
564 USB_DEVICE_PATH *Usb;
565
566 Usb = DevPath;
567 CatPrint (Str, L"Usb(%x,%x)", (UINTN) Usb->ParentPortNumber, (UINTN) Usb->InterfaceNumber);
568 }
569
570 /**
571 Convert Device Path to a Unicode string for printing.
572
573 @param[in, out] Str The buffer holding the output string.
574 This buffer contains the length of the string and
575 the maixmum length reserved for the string buffer.
576 @param[in] DevPath The device path.
577
578 **/
579 VOID
580 DevPathUsbWWID (
581 IN OUT POOL_PRINT *Str,
582 IN VOID *DevPath
583 )
584 {
585 USB_WWID_DEVICE_PATH *UsbWWId;
586
587 UsbWWId = DevPath;
588 CatPrint (
589 Str,
590 L"UsbWwid(%x,%x,%x,\"WWID\")",
591 (UINTN) UsbWWId->VendorId,
592 (UINTN) UsbWWId->ProductId,
593 (UINTN) UsbWWId->InterfaceNumber
594 );
595 }
596
597 /**
598 Convert Device Path to a Unicode string for printing.
599
600 @param[in, out] Str The buffer holding the output string.
601 This buffer contains the length of the string and
602 the maixmum length reserved for the string buffer.
603 @param[in] DevPath The device path.
604
605 **/
606 VOID
607 DevPathLogicalUnit (
608 IN OUT POOL_PRINT *Str,
609 IN VOID *DevPath
610 )
611 {
612 DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
613
614 LogicalUnit = DevPath;
615 CatPrint (Str, L"Unit(%x)", (UINTN) LogicalUnit->Lun);
616 }
617
618 /**
619 Convert Device Path to a Unicode string for printing.
620
621 @param[in, out] Str The buffer holding the output string.
622 This buffer contains the length of the string and
623 the maixmum length reserved for the string buffer.
624 @param[in] DevPath The device path.
625
626 **/
627 VOID
628 DevPathUsbClass (
629 IN OUT POOL_PRINT *Str,
630 IN VOID *DevPath
631 )
632 {
633 USB_CLASS_DEVICE_PATH *UsbClass;
634
635 UsbClass = DevPath;
636 CatPrint (
637 Str,
638 L"Usb Class(%x,%x,%x,%x,%x)",
639 (UINTN) UsbClass->VendorId,
640 (UINTN) UsbClass->ProductId,
641 (UINTN) UsbClass->DeviceClass,
642 (UINTN) UsbClass->DeviceSubClass,
643 (UINTN) UsbClass->DeviceProtocol
644 );
645 }
646
647 /**
648 Convert Device Path to a Unicode string for printing.
649
650 @param[in, out] Str The buffer holding the output string.
651 This buffer contains the length of the string and
652 the maixmum length reserved for the string buffer.
653 @param[in] DevPath The device path.
654
655 **/
656 VOID
657 DevPathSata (
658 IN OUT POOL_PRINT *Str,
659 IN VOID *DevPath
660 )
661 {
662 SATA_DEVICE_PATH *Sata;
663
664 Sata = DevPath;
665 if ((Sata->PortMultiplierPortNumber & SATA_HBA_DIRECT_CONNECT_FLAG) != 0) {
666 CatPrint (
667 Str,
668 L"Sata(%x,%x)",
669 (UINTN) Sata->HBAPortNumber,
670 (UINTN) Sata->Lun
671 );
672 } else {
673 CatPrint (
674 Str,
675 L"Sata(%x,%x,%x)",
676 (UINTN) Sata->HBAPortNumber,
677 (UINTN) Sata->PortMultiplierPortNumber,
678 (UINTN) Sata->Lun
679 );
680 }
681 }
682
683 /**
684 Convert Device Path to a Unicode string for printing.
685
686 @param[in, out] Str The buffer holding the output string.
687 This buffer contains the length of the string and
688 the maixmum length reserved for the string buffer.
689 @param[in] DevPath The device path.
690
691 **/
692 VOID
693 DevPathI2O (
694 IN OUT POOL_PRINT *Str,
695 IN VOID *DevPath
696 )
697 {
698 I2O_DEVICE_PATH *I2OPath;
699
700 I2OPath = DevPath;
701 CatPrint (Str, L"I2O(%x)", (UINTN) I2OPath->Tid);
702 }
703
704 /**
705 Convert Device Path to a Unicode string for printing.
706
707 @param[in, out] Str The buffer holding the output string.
708 This buffer contains the length of the string and
709 the maixmum length reserved for the string buffer.
710 @param[in] DevPath The device path.
711
712 **/
713 VOID
714 DevPathMacAddr (
715 IN OUT POOL_PRINT *Str,
716 IN VOID *DevPath
717 )
718 {
719 MAC_ADDR_DEVICE_PATH *MACDevPath;
720 UINTN HwAddressSize;
721 UINTN Index;
722
723 MACDevPath = DevPath;
724
725 HwAddressSize = sizeof (EFI_MAC_ADDRESS);
726 if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) {
727 HwAddressSize = 6;
728 }
729
730 CatPrint (Str, L"Mac(");
731
732 for (Index = 0; Index < HwAddressSize; Index++) {
733 CatPrint (Str, L"%02x", (UINTN) MACDevPath->MacAddress.Addr[Index]);
734 }
735
736 CatPrint (Str, L")");
737 }
738
739 /**
740 Convert Device Path to a Unicode string for printing.
741
742 @param[in, out] Str The buffer holding the output string.
743 This buffer contains the length of the string and
744 the maixmum length reserved for the string buffer.
745 @param[in] DevPath The device path.
746
747 **/
748 VOID
749 DevPathIPv4 (
750 IN OUT POOL_PRINT *Str,
751 IN VOID *DevPath
752 )
753 {
754 IPv4_DEVICE_PATH *IPDevPath;
755
756 IPDevPath = DevPath;
757 CatPrint (
758 Str,
759 L"IPv4(%d.%d.%d.%d:%d)",
760 (UINTN) IPDevPath->RemoteIpAddress.Addr[0],
761 (UINTN) IPDevPath->RemoteIpAddress.Addr[1],
762 (UINTN) IPDevPath->RemoteIpAddress.Addr[2],
763 (UINTN) IPDevPath->RemoteIpAddress.Addr[3],
764 (UINTN) IPDevPath->RemotePort
765 );
766 }
767
768 /**
769 Convert Device Path to a Unicode string for printing.
770
771 @param[in, out] Str The buffer holding the output string.
772 This buffer contains the length of the string and
773 the maixmum length reserved for the string buffer.
774 @param[in] DevPath The device path.
775
776 **/
777 VOID
778 DevPathIPv6 (
779 IN OUT POOL_PRINT *Str,
780 IN VOID *DevPath
781 )
782 {
783 IPv6_DEVICE_PATH *IPv6DevPath;
784
785 IPv6DevPath = DevPath;
786 CatPrint (
787 Str,
788 L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
789 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[0],
790 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[1],
791 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[2],
792 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[3],
793 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[4],
794 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[5],
795 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[6],
796 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[7],
797 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[8],
798 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[9],
799 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[10],
800 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[11],
801 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[12],
802 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[13],
803 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[14],
804 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[15]
805 );
806 }
807
808 /**
809 Convert Device Path to a Unicode string for printing.
810
811 @param[in, out] Str The buffer holding the output string.
812 This buffer contains the length of the string and
813 the maixmum length reserved for the string buffer.
814 @param[in] DevPath The device path.
815
816 **/
817 VOID
818 DevPathInfiniBand (
819 IN OUT POOL_PRINT *Str,
820 IN VOID *DevPath
821 )
822 {
823 INFINIBAND_DEVICE_PATH *InfiniBand;
824
825 InfiniBand = DevPath;
826 CatPrint (
827 Str,
828 L"Infiniband(%x,%g,%lx,%lx,%lx)",
829 (UINTN) InfiniBand->ResourceFlags,
830 InfiniBand->PortGid,
831 InfiniBand->ServiceId,
832 InfiniBand->TargetPortId,
833 InfiniBand->DeviceId
834 );
835 }
836
837 /**
838 Convert Device Path to a Unicode string for printing.
839
840 @param[in, out] Str The buffer holding the output string.
841 This buffer contains the length of the string and
842 the maixmum length reserved for the string buffer.
843 @param[in] DevPath The device path.
844
845 **/
846 VOID
847 DevPathUart (
848 IN OUT POOL_PRINT *Str,
849 IN VOID *DevPath
850 )
851 {
852 UART_DEVICE_PATH *Uart;
853 CHAR8 Parity;
854
855 Uart = DevPath;
856 switch (Uart->Parity) {
857 case 0:
858 Parity = 'D';
859 break;
860
861 case 1:
862 Parity = 'N';
863 break;
864
865 case 2:
866 Parity = 'E';
867 break;
868
869 case 3:
870 Parity = 'O';
871 break;
872
873 case 4:
874 Parity = 'M';
875 break;
876
877 case 5:
878 Parity = 'S';
879 break;
880
881 default:
882 Parity = 'x';
883 break;
884 }
885
886 if (Uart->BaudRate == 0) {
887 CatPrint (Str, L"Uart(DEFAULT,%c,", Parity);
888 } else {
889 CatPrint (Str, L"Uart(%ld,%c,", Uart->BaudRate, Parity);
890 }
891
892 if (Uart->DataBits == 0) {
893 CatPrint (Str, L"D,");
894 } else {
895 CatPrint (Str, L"%d,", (UINTN) Uart->DataBits);
896 }
897
898 switch (Uart->StopBits) {
899 case 0:
900 CatPrint (Str, L"D)");
901 break;
902
903 case 1:
904 CatPrint (Str, L"1)");
905 break;
906
907 case 2:
908 CatPrint (Str, L"1.5)");
909 break;
910
911 case 3:
912 CatPrint (Str, L"2)");
913 break;
914
915 default:
916 CatPrint (Str, L"x)");
917 break;
918 }
919 }
920
921 /**
922 Convert Device Path to a Unicode string for printing.
923
924 @param[in, out] Str The buffer holding the output string.
925 This buffer contains the length of the string and
926 the maixmum length reserved for the string buffer.
927 @param[in] DevPath The device path.
928
929 **/
930 VOID
931 DevPathiSCSI (
932 IN OUT POOL_PRINT *Str,
933 IN VOID *DevPath
934 )
935 {
936 ISCSI_DEVICE_PATH_WITH_NAME *IScsi;
937 UINT16 Options;
938
939 IScsi = DevPath;
940 CatPrint (
941 Str,
942 L"iSCSI(%a,%x,%lx,",
943 IScsi->TargetName,
944 (UINTN) IScsi->TargetPortalGroupTag,
945 IScsi->Lun
946 );
947
948 Options = IScsi->LoginOption;
949 CatPrint (Str, L"%s,", (((Options >> 1) & 0x0001) != 0) ? L"CRC32C" : L"None");
950 CatPrint (Str, L"%s,", (((Options >> 3) & 0x0001) != 0) ? L"CRC32C" : L"None");
951 if (((Options >> 11) & 0x0001) != 0) {
952 CatPrint (Str, L"%s,", L"None");
953 } else if (((Options >> 12) & 0x0001) != 0) {
954 CatPrint (Str, L"%s,", L"CHAP_UNI");
955 } else {
956 CatPrint (Str, L"%s,", L"CHAP_BI");
957
958 }
959
960 CatPrint (Str, L"%s)", (IScsi->NetworkProtocol == 0) ? L"TCP" : L"reserved");
961 }
962
963 /**
964 Convert Device Path to a Unicode string for printing.
965
966 @param[in, out] Str The buffer holding the output string.
967 This buffer contains the length of the string and
968 the maixmum length reserved for the string buffer.
969 @param[in] DevPath The device path.
970
971 **/
972 VOID
973 DevPathVlan (
974 IN OUT POOL_PRINT *Str,
975 IN VOID *DevPath
976 )
977 {
978 VLAN_DEVICE_PATH *Vlan;
979
980 Vlan = DevPath;
981 CatPrint (Str, L"Vlan(%d)", (UINTN) Vlan->VlanId);
982 }
983
984 /**
985 Convert Device Path to a Unicode string for printing.
986
987 @param[in, out] Str The buffer holding the output string.
988 This buffer contains the length of the string and
989 the maixmum length reserved for the string buffer.
990 @param[in] DevPath The device path.
991
992 **/
993 VOID
994 DevPathHardDrive (
995 IN OUT POOL_PRINT *Str,
996 IN VOID *DevPath
997 )
998 {
999 HARDDRIVE_DEVICE_PATH *Hd;
1000
1001 Hd = DevPath;
1002 switch (Hd->SignatureType) {
1003 case SIGNATURE_TYPE_MBR:
1004 CatPrint (
1005 Str,
1006 L"HD(Part%d,Sig%08x)",
1007 (UINTN) Hd->PartitionNumber,
1008 (UINTN) *((UINT32 *) (&(Hd->Signature[0])))
1009 );
1010 break;
1011
1012 case SIGNATURE_TYPE_GUID:
1013 CatPrint (
1014 Str,
1015 L"HD(Part%d,Sig%g)",
1016 (UINTN) Hd->PartitionNumber,
1017 (EFI_GUID *) &(Hd->Signature[0])
1018 );
1019 break;
1020
1021 default:
1022 CatPrint (
1023 Str,
1024 L"HD(Part%d,MBRType=%02x,SigType=%02x)",
1025 (UINTN) Hd->PartitionNumber,
1026 (UINTN) Hd->MBRType,
1027 (UINTN) Hd->SignatureType
1028 );
1029 break;
1030 }
1031 }
1032
1033 /**
1034 Convert Device Path to a Unicode string for printing.
1035
1036 @param[in, out] Str The buffer holding the output string.
1037 This buffer contains the length of the string and
1038 the maixmum length reserved for the string buffer.
1039 @param[in] DevPath The device path.
1040
1041 **/
1042 VOID
1043 DevPathCDROM (
1044 IN OUT POOL_PRINT *Str,
1045 IN VOID *DevPath
1046 )
1047 {
1048 CDROM_DEVICE_PATH *Cd;
1049
1050 Cd = DevPath;
1051 CatPrint (Str, L"CDROM(Entry%x)", (UINTN) Cd->BootEntry);
1052 }
1053
1054 /**
1055 Convert Device Path to a Unicode string for printing.
1056
1057 @param[in, out] Str The buffer holding the output string.
1058 This buffer contains the length of the string and
1059 the maixmum length reserved for the string buffer.
1060 @param[in] DevPath The device path.
1061
1062 **/
1063 VOID
1064 DevPathFilePath (
1065 IN OUT POOL_PRINT *Str,
1066 IN VOID *DevPath
1067 )
1068 {
1069 FILEPATH_DEVICE_PATH *Fp;
1070
1071 Fp = DevPath;
1072 CatPrint (Str, L"%s", Fp->PathName);
1073 }
1074
1075 /**
1076 Convert Device Path to a Unicode string for printing.
1077
1078 @param[in, out] Str The buffer holding the output string.
1079 This buffer contains the length of the string and
1080 the maixmum length reserved for the string buffer.
1081 @param[in] DevPath The device path.
1082
1083 **/
1084 VOID
1085 DevPathMediaProtocol (
1086 IN OUT POOL_PRINT *Str,
1087 IN VOID *DevPath
1088 )
1089 {
1090 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
1091
1092 MediaProt = DevPath;
1093 CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
1094 }
1095
1096 /**
1097 Convert Device Path to a Unicode string for printing.
1098
1099 @param[in, out] Str The buffer holding the output string.
1100 This buffer contains the length of the string and
1101 the maixmum length reserved for the string buffer.
1102 @param[in] DevPath The device path.
1103
1104 **/
1105 VOID
1106 DevPathFvFilePath (
1107 IN OUT POOL_PRINT *Str,
1108 IN VOID *DevPath
1109 )
1110 {
1111 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
1112
1113 FvFilePath = DevPath;
1114 CatPrint (Str, L"%g", &FvFilePath->FvFileName);
1115 }
1116
1117 /**
1118 Convert Device Path to a Unicode string for printing.
1119
1120 @param[in, out] Str The buffer holding the output string.
1121 This buffer contains the length of the string and
1122 the maixmum length reserved for the string buffer.
1123 @param[in] DevPath The device path.
1124
1125 **/
1126 VOID
1127 DevPathRelativeOffsetRange (
1128 IN OUT POOL_PRINT *Str,
1129 IN VOID *DevPath
1130 )
1131 {
1132 MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
1133
1134 Offset = DevPath;
1135 CatPrint (
1136 Str,
1137 L"Offset(%lx,%lx)",
1138 Offset->StartingOffset,
1139 Offset->EndingOffset
1140 );
1141 }
1142
1143 /**
1144 Convert Device Path to a Unicode string for printing.
1145
1146 @param[in, out] Str The buffer holding the output string.
1147 This buffer contains the length of the string and
1148 the maixmum length reserved for the string buffer.
1149 @param[in] DevPath The device path.
1150
1151 **/
1152 VOID
1153 DevPathBssBss (
1154 IN OUT POOL_PRINT *Str,
1155 IN VOID *DevPath
1156 )
1157 {
1158 BBS_BBS_DEVICE_PATH *Bbs;
1159 CHAR16 *Type;
1160
1161 Bbs = DevPath;
1162 switch (Bbs->DeviceType) {
1163 case BBS_TYPE_FLOPPY:
1164 Type = L"Floppy";
1165 break;
1166
1167 case BBS_TYPE_HARDDRIVE:
1168 Type = L"Harddrive";
1169 break;
1170
1171 case BBS_TYPE_CDROM:
1172 Type = L"CDROM";
1173 break;
1174
1175 case BBS_TYPE_PCMCIA:
1176 Type = L"PCMCIA";
1177 break;
1178
1179 case BBS_TYPE_USB:
1180 Type = L"Usb";
1181 break;
1182
1183 case BBS_TYPE_EMBEDDED_NETWORK:
1184 Type = L"Net";
1185 break;
1186
1187 case BBS_TYPE_BEV:
1188 Type = L"BEV";
1189 break;
1190
1191 default:
1192 Type = L"?";
1193 break;
1194 }
1195 CatPrint (Str, L"Legacy-%s", Type);
1196 }
1197
1198 /**
1199 Convert Device Path to a Unicode string for printing.
1200
1201 @param[in, out] Str The buffer holding the output string.
1202 This buffer contains the length of the string and
1203 the maixmum length reserved for the string buffer.
1204 @param[in] DevPath The device path.
1205
1206 **/
1207 VOID
1208 DevPathEndInstance (
1209 IN OUT POOL_PRINT *Str,
1210 IN VOID *DevPath
1211 )
1212 {
1213 CatPrint (Str, L",");
1214 }
1215
1216 /**
1217 Convert Device Path to a Unicode string for printing.
1218
1219 @param[in, out] Str The buffer holding the output string.
1220 This buffer contains the length of the string and
1221 the maixmum length reserved for the string buffer.
1222 @param[in] DevPath The device path.
1223
1224 **/
1225 VOID
1226 DevPathNodeUnknown (
1227 IN OUT POOL_PRINT *Str,
1228 IN VOID *DevPath
1229 )
1230 {
1231 CatPrint (Str, L"?");
1232 }
1233 /**
1234 Convert Device Path to a Unicode string for printing.
1235
1236 @param[in, out] Str The buffer holding the output string.
1237 This buffer contains the length of the string and
1238 the maixmum length reserved for the string buffer.
1239 @param[in] DevPath The device path.
1240
1241 **/
1242 VOID
1243 DevPathFvPath (
1244 IN OUT POOL_PRINT *Str,
1245 IN VOID *DevPath
1246 )
1247 {
1248 MEDIA_FW_VOL_DEVICE_PATH *FvPath;
1249
1250 FvPath = DevPath;
1251 CatPrint (Str, L"Fv(%g)", &FvPath->FvName);
1252 }
1253
1254 DEVICE_PATH_STRING_TABLE DevPathTable[] = {
1255 {
1256 HARDWARE_DEVICE_PATH,
1257 HW_PCI_DP,
1258 DevPathPci
1259 },
1260 {
1261 HARDWARE_DEVICE_PATH,
1262 HW_PCCARD_DP,
1263 DevPathPccard
1264 },
1265 {
1266 HARDWARE_DEVICE_PATH,
1267 HW_MEMMAP_DP,
1268 DevPathMemMap
1269 },
1270 {
1271 HARDWARE_DEVICE_PATH,
1272 HW_VENDOR_DP,
1273 DevPathVendor
1274 },
1275 {
1276 HARDWARE_DEVICE_PATH,
1277 HW_CONTROLLER_DP,
1278 DevPathController
1279 },
1280 {
1281 ACPI_DEVICE_PATH,
1282 ACPI_DP,
1283 DevPathAcpi
1284 },
1285 {
1286 ACPI_DEVICE_PATH,
1287 ACPI_EXTENDED_DP,
1288 DevPathExtendedAcpi
1289 },
1290 {
1291 ACPI_DEVICE_PATH,
1292 ACPI_ADR_DP,
1293 DevPathAdrAcpi
1294 },
1295 {
1296 MESSAGING_DEVICE_PATH,
1297 MSG_ATAPI_DP,
1298 DevPathAtapi
1299 },
1300 {
1301 MESSAGING_DEVICE_PATH,
1302 MSG_SCSI_DP,
1303 DevPathScsi
1304 },
1305 {
1306 MESSAGING_DEVICE_PATH,
1307 MSG_FIBRECHANNEL_DP,
1308 DevPathFibre
1309 },
1310 {
1311 MESSAGING_DEVICE_PATH,
1312 MSG_1394_DP,
1313 DevPath1394
1314 },
1315 {
1316 MESSAGING_DEVICE_PATH,
1317 MSG_USB_DP,
1318 DevPathUsb
1319 },
1320 {
1321 MESSAGING_DEVICE_PATH,
1322 MSG_USB_WWID_DP,
1323 DevPathUsbWWID
1324 },
1325 {
1326 MESSAGING_DEVICE_PATH,
1327 MSG_DEVICE_LOGICAL_UNIT_DP,
1328 DevPathLogicalUnit
1329 },
1330 {
1331 MESSAGING_DEVICE_PATH,
1332 MSG_USB_CLASS_DP,
1333 DevPathUsbClass
1334 },
1335 {
1336 MESSAGING_DEVICE_PATH,
1337 MSG_SATA_DP,
1338 DevPathSata
1339 },
1340 {
1341 MESSAGING_DEVICE_PATH,
1342 MSG_I2O_DP,
1343 DevPathI2O
1344 },
1345 {
1346 MESSAGING_DEVICE_PATH,
1347 MSG_MAC_ADDR_DP,
1348 DevPathMacAddr
1349 },
1350 {
1351 MESSAGING_DEVICE_PATH,
1352 MSG_IPv4_DP,
1353 DevPathIPv4
1354 },
1355 {
1356 MESSAGING_DEVICE_PATH,
1357 MSG_IPv6_DP,
1358 DevPathIPv6
1359 },
1360 {
1361 MESSAGING_DEVICE_PATH,
1362 MSG_INFINIBAND_DP,
1363 DevPathInfiniBand
1364 },
1365 {
1366 MESSAGING_DEVICE_PATH,
1367 MSG_UART_DP,
1368 DevPathUart
1369 },
1370 {
1371 MESSAGING_DEVICE_PATH,
1372 MSG_VENDOR_DP,
1373 DevPathVendor
1374 },
1375 {
1376 MESSAGING_DEVICE_PATH,
1377 MSG_ISCSI_DP,
1378 DevPathiSCSI
1379 },
1380 {
1381 MESSAGING_DEVICE_PATH,
1382 MSG_VLAN_DP,
1383 DevPathVlan
1384 },
1385 {
1386 MEDIA_DEVICE_PATH,
1387 MEDIA_HARDDRIVE_DP,
1388 DevPathHardDrive
1389 },
1390 {
1391 MEDIA_DEVICE_PATH,
1392 MEDIA_CDROM_DP,
1393 DevPathCDROM
1394 },
1395 {
1396 MEDIA_DEVICE_PATH,
1397 MEDIA_VENDOR_DP,
1398 DevPathVendor
1399 },
1400 {
1401 MEDIA_DEVICE_PATH,
1402 MEDIA_FILEPATH_DP,
1403 DevPathFilePath
1404 },
1405 {
1406 MEDIA_DEVICE_PATH,
1407 MEDIA_PROTOCOL_DP,
1408 DevPathMediaProtocol
1409 },
1410 {
1411 MEDIA_DEVICE_PATH,
1412 MEDIA_PIWG_FW_VOL_DP,
1413 DevPathFvPath,
1414 },
1415 {
1416 MEDIA_DEVICE_PATH,
1417 MEDIA_PIWG_FW_FILE_DP,
1418 DevPathFvFilePath
1419 },
1420 {
1421 MEDIA_DEVICE_PATH,
1422 MEDIA_RELATIVE_OFFSET_RANGE_DP,
1423 DevPathRelativeOffsetRange,
1424 },
1425 {
1426 BBS_DEVICE_PATH,
1427 BBS_BBS_DP,
1428 DevPathBssBss
1429 },
1430 {
1431 END_DEVICE_PATH_TYPE,
1432 END_INSTANCE_DEVICE_PATH_SUBTYPE,
1433 DevPathEndInstance
1434 },
1435 {
1436 0,
1437 0,
1438 NULL
1439 }
1440 };
1441
1442
1443 /**
1444 This function converts an input device structure to a Unicode string.
1445
1446 @param[in] DevPath A pointer to the device path structure.
1447
1448 @return A new allocated Unicode string that represents the device path.
1449
1450 **/
1451 CHAR16 *
1452 EFIAPI
1453 DevicePathToStr (
1454 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
1455 )
1456 {
1457 POOL_PRINT Str;
1458 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
1459 VOID (*DumpNode) (POOL_PRINT *, VOID *);
1460
1461 UINTN Index;
1462 UINTN NewSize;
1463
1464 EFI_STATUS Status;
1465 CHAR16 *ToText;
1466 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
1467
1468 ZeroMem (&Str, sizeof (Str));
1469
1470 if (DevPath == NULL) {
1471 goto Done;
1472 }
1473
1474 Status = gBS->LocateProtocol (
1475 &gEfiDevicePathToTextProtocolGuid,
1476 NULL,
1477 (VOID **) &DevPathToText
1478 );
1479 if (!EFI_ERROR (Status)) {
1480 ToText = DevPathToText->ConvertDevicePathToText (
1481 DevPath,
1482 FALSE,
1483 TRUE
1484 );
1485 ASSERT (ToText != NULL);
1486 return ToText;
1487 }
1488
1489 //
1490 // Process each device path node
1491 //
1492 DevPathNode = DevPath;
1493 while (!IsDevicePathEnd (DevPathNode)) {
1494 //
1495 // Find the handler to dump this device path node
1496 //
1497 DumpNode = NULL;
1498 for (Index = 0; DevPathTable[Index].Function != NULL; Index += 1) {
1499
1500 if (DevicePathType (DevPathNode) == DevPathTable[Index].Type &&
1501 DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType
1502 ) {
1503 DumpNode = DevPathTable[Index].Function;
1504 break;
1505 }
1506 }
1507 //
1508 // If not found, use a generic function
1509 //
1510 if (!DumpNode) {
1511 DumpNode = DevPathNodeUnknown;
1512 }
1513 //
1514 // Put a path seperator in if needed
1515 //
1516 if ((Str.Len != 0) && (DumpNode != DevPathEndInstance)) {
1517 CatPrint (&Str, L"/");
1518 }
1519 //
1520 // Print this node of the device path
1521 //
1522 DumpNode (&Str, DevPathNode);
1523
1524 //
1525 // Next device path node
1526 //
1527 DevPathNode = NextDevicePathNode (DevPathNode);
1528 }
1529
1530 Done:
1531 NewSize = (Str.Len + 1) * sizeof (CHAR16);
1532 Str.Str = ReallocatePool (NewSize, NewSize, Str.Str);
1533 ASSERT (Str.Str != NULL);
1534 Str.Str[Str.Len] = 0;
1535 return Str.Str;
1536 }
1537