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