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