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