1 /*-
2 * Copyright (c) 2017 Netflix, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 /*
27 * Routines to format EFI_DEVICE_PATHs from the UEFI standard. Much of
28 * this file is taken from EDK2 and rototilled.
29 */
30
31 #include <sys/cdefs.h>
32 #include <efivar.h>
33 #include <stdio.h>
34 #include <string.h>
35
36 #include "efichar.h"
37
38 #include "efi-osdep.h"
39 #include "efivar-dp.h"
40
41 #include "uefi-dplib.h"
42
43 /*
44 * This is a lie, but since we have converted everything
45 * from wide to narrow, it's the right lie now.
46 */
47 #define UnicodeSPrint snprintf
48
49 /*
50 * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
51 * heavily modified:
52 * wide strings converted to narrow
53 * Low level printing code redone for narrow strings
54 * Routines made static
55 * %s -> %S in spots (where it is still UCS-2)
56 * %a (ascii) -> %s
57 * %g -> %36s hack to print guid (see above for caveat)
58 * some tidying up of const and deconsting. It's evil, but const
59 * poisoning the whole file was too much.
60 */
61
62 /** @file
63 DevicePathToText protocol as defined in the UEFI 2.0 specification.
64
65 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
66 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
67 SPDX-License-Identifier: BSD-2-Clause-Patent
68
69 **/
70
71 // #include "UefiDevicePathLib.h"
72
73 /**
74 Concatenates a formatted unicode string to allocated pool. The caller must
75 free the resulting buffer.
76
77 @param Str Tracks the allocated pool, size in use, and
78 amount of pool allocated.
79 @param Fmt The format string
80 @param ... Variable arguments based on the format string.
81
82 @return Allocated buffer with the formatted string printed in it.
83 The caller must free the allocated buffer. The buffer
84 allocation is not packed.
85
86 **/
87 static char *
88 EFIAPI
UefiDevicePathLibCatPrint(IN OUT POOL_PRINT * Str,IN const char * Fmt,...)89 UefiDevicePathLibCatPrint (
90 IN OUT POOL_PRINT *Str,
91 IN const char *Fmt,
92 ...
93 )
94 {
95 UINTN Count;
96 VA_LIST Args;
97
98 VA_START (Args, Fmt);
99 Count = vsnprintf (NULL, 0, Fmt, Args);
100 VA_END (Args);
101
102 if ((Str->Count + (Count + 1)) > Str->Capacity) {
103 Str->Capacity = (Str->Count + (Count + 1) * 2);
104 Str->Str = reallocf (
105 Str->Str,
106 Str->Capacity
107 );
108 ASSERT (Str->Str != NULL);
109 }
110
111 VA_START (Args, Fmt);
112 vsnprintf (Str->Str + Str->Count, Str->Capacity - Str->Count, Fmt, Args);
113 Str->Count += Count;
114
115 VA_END (Args);
116 return Str->Str;
117 }
118
119 /**
120 Converts a PCI device path structure to its string representative.
121
122 @param Str The string representative of input device.
123 @param DevPath The input device path structure.
124 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
125 of the display node is used, where applicable. If DisplayOnly
126 is FALSE, then the longer text representation of the display node
127 is used.
128 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
129 representation for a device node can be used, where applicable.
130
131 **/
132 static VOID
DevPathToTextPci(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)133 DevPathToTextPci (
134 IN OUT POOL_PRINT *Str,
135 IN VOID *DevPath,
136 IN BOOLEAN DisplayOnly,
137 IN BOOLEAN AllowShortcuts
138 )
139 {
140 PCI_DEVICE_PATH *Pci;
141
142 Pci = DevPath;
143 UefiDevicePathLibCatPrint (Str, "Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
144 }
145
146 /**
147 Converts a PC Card device path structure to its string representative.
148
149 @param Str The string representative of input device.
150 @param DevPath The input device path structure.
151 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
152 of the display node is used, where applicable. If DisplayOnly
153 is FALSE, then the longer text representation of the display node
154 is used.
155 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
156 representation for a device node can be used, where applicable.
157
158 **/
159 static VOID
DevPathToTextPccard(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)160 DevPathToTextPccard (
161 IN OUT POOL_PRINT *Str,
162 IN VOID *DevPath,
163 IN BOOLEAN DisplayOnly,
164 IN BOOLEAN AllowShortcuts
165 )
166 {
167 PCCARD_DEVICE_PATH *Pccard;
168
169 Pccard = DevPath;
170 UefiDevicePathLibCatPrint (Str, "PcCard(0x%x)", Pccard->FunctionNumber);
171 }
172
173 /**
174 Converts a Memory Map device path structure to its string representative.
175
176 @param Str The string representative of input device.
177 @param DevPath The input device path structure.
178 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
179 of the display node is used, where applicable. If DisplayOnly
180 is FALSE, then the longer text representation of the display node
181 is used.
182 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
183 representation for a device node can be used, where applicable.
184
185 **/
186 static VOID
DevPathToTextMemMap(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)187 DevPathToTextMemMap (
188 IN OUT POOL_PRINT *Str,
189 IN VOID *DevPath,
190 IN BOOLEAN DisplayOnly,
191 IN BOOLEAN AllowShortcuts
192 )
193 {
194 MEMMAP_DEVICE_PATH *MemMap;
195
196 MemMap = DevPath;
197 UefiDevicePathLibCatPrint (
198 Str,
199 "MemoryMapped(0x%x,0x%lx,0x%lx)",
200 MemMap->MemoryType,
201 MemMap->StartingAddress,
202 MemMap->EndingAddress
203 );
204 }
205
206 /**
207 Converts a Vendor device path structure to its string representative.
208
209 @param Str The string representative of input device.
210 @param DevPath The input device path structure.
211 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
212 of the display node is used, where applicable. If DisplayOnly
213 is FALSE, then the longer text representation of the display node
214 is used.
215 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
216 representation for a device node can be used, where applicable.
217
218 **/
219 static VOID
DevPathToTextVendor(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)220 DevPathToTextVendor (
221 IN OUT POOL_PRINT *Str,
222 IN VOID *DevPath,
223 IN BOOLEAN DisplayOnly,
224 IN BOOLEAN AllowShortcuts
225 )
226 {
227 VENDOR_DEVICE_PATH *Vendor;
228 const char *Type;
229 UINTN Index;
230 UINTN DataLength;
231 UINT32 FlowControlMap;
232 UINT16 Info;
233
234 Vendor = (VENDOR_DEVICE_PATH *)DevPath;
235 switch (DevicePathType (&Vendor->Header)) {
236 case HARDWARE_DEVICE_PATH:
237 Type = "Hw";
238 break;
239
240 case MESSAGING_DEVICE_PATH:
241 Type = "Msg";
242 if (AllowShortcuts) {
243 if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
244 UefiDevicePathLibCatPrint (Str, "VenPcAnsi()");
245 return;
246 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
247 UefiDevicePathLibCatPrint (Str, "VenVt100()");
248 return;
249 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
250 UefiDevicePathLibCatPrint (Str, "VenVt100Plus()");
251 return;
252 } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
253 UefiDevicePathLibCatPrint (Str, "VenUtf8()");
254 return;
255 } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {
256 FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *)Vendor)->FlowControlMap);
257 switch (FlowControlMap & 0x00000003) {
258 case 0:
259 UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "None");
260 break;
261
262 case 1:
263 UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "Hardware");
264 break;
265
266 case 2:
267 UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "XonXoff");
268 break;
269
270 default:
271 break;
272 }
273
274 return;
275 } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {
276 UefiDevicePathLibCatPrint (
277 Str,
278 "SAS(0x%lx,0x%lx,0x%x,",
279 ((SAS_DEVICE_PATH *)Vendor)->SasAddress,
280 ((SAS_DEVICE_PATH *)Vendor)->Lun,
281 ((SAS_DEVICE_PATH *)Vendor)->RelativeTargetPort
282 );
283 Info = (((SAS_DEVICE_PATH *)Vendor)->DeviceTopology);
284 if (((Info & 0x0f) == 0) && ((Info & BIT7) == 0)) {
285 UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0,");
286 } else if (((Info & 0x0f) <= 2) && ((Info & BIT7) == 0)) {
287 UefiDevicePathLibCatPrint (
288 Str,
289 "%s,%s,%s,",
290 ((Info & BIT4) != 0) ? "SATA" : "SAS",
291 ((Info & BIT5) != 0) ? "External" : "Internal",
292 ((Info & BIT6) != 0) ? "Expanded" : "Direct"
293 );
294 if ((Info & 0x0f) == 1) {
295 UefiDevicePathLibCatPrint (Str, "0,");
296 } else {
297 //
298 // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
299 //
300 UefiDevicePathLibCatPrint (Str, "0x%x,", ((Info >> 8) & 0xff) + 1);
301 }
302 } else {
303 UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0,", Info);
304 }
305
306 UefiDevicePathLibCatPrint (Str, "0x%x)", ((SAS_DEVICE_PATH *)Vendor)->Reserved);
307 return;
308 } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
309 UefiDevicePathLibCatPrint (Str, "DebugPort()");
310 return;
311 }
312 }
313
314 break;
315
316 case MEDIA_DEVICE_PATH:
317 Type = "Media";
318 break;
319
320 default:
321 Type = "?";
322 break;
323 }
324
325 DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
326 UefiDevicePathLibCatPrint (Str, "Ven%s(%36s", Type, G(&Vendor->Guid));
327 if (DataLength != 0) {
328 UefiDevicePathLibCatPrint (Str, ",");
329 for (Index = 0; Index < DataLength; Index++) {
330 UefiDevicePathLibCatPrint (Str, "%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *)Vendor)->VendorDefinedData[Index]);
331 }
332 }
333
334 UefiDevicePathLibCatPrint (Str, ")");
335 }
336
337 /**
338 Converts a Controller device path structure to its string representative.
339
340 @param Str The string representative of input device.
341 @param DevPath The input device path structure.
342 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
343 of the display node is used, where applicable. If DisplayOnly
344 is FALSE, then the longer text representation of the display node
345 is used.
346 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
347 representation for a device node can be used, where applicable.
348
349 **/
350 static VOID
DevPathToTextController(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)351 DevPathToTextController (
352 IN OUT POOL_PRINT *Str,
353 IN VOID *DevPath,
354 IN BOOLEAN DisplayOnly,
355 IN BOOLEAN AllowShortcuts
356 )
357 {
358 CONTROLLER_DEVICE_PATH *Controller;
359
360 Controller = DevPath;
361 UefiDevicePathLibCatPrint (
362 Str,
363 "Ctrl(0x%x)",
364 Controller->ControllerNumber
365 );
366 }
367
368 /**
369 Converts a BMC device path structure to its string representative.
370
371 @param Str The string representative of input device.
372 @param DevPath The input device path structure.
373 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
374 of the display node is used, where applicable. If DisplayOnly
375 is FALSE, then the longer text representation of the display node
376 is used.
377 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
378 representation for a device node can be used, where applicable.
379
380 **/
381 static VOID
DevPathToTextBmc(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)382 DevPathToTextBmc (
383 IN OUT POOL_PRINT *Str,
384 IN VOID *DevPath,
385 IN BOOLEAN DisplayOnly,
386 IN BOOLEAN AllowShortcuts
387 )
388 {
389 BMC_DEVICE_PATH *Bmc;
390
391 Bmc = DevPath;
392 UefiDevicePathLibCatPrint (
393 Str,
394 "BMC(0x%x,0x%lx)",
395 Bmc->InterfaceType,
396 ReadUnaligned64 ((&Bmc->BaseAddress))
397 );
398 }
399
400 /**
401 Converts a ACPI device path structure to its string representative.
402
403 @param Str The string representative of input device.
404 @param DevPath The input device path structure.
405 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
406 of the display node is used, where applicable. If DisplayOnly
407 is FALSE, then the longer text representation of the display node
408 is used.
409 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
410 representation for a device node can be used, where applicable.
411
412 **/
413 static VOID
DevPathToTextAcpi(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)414 DevPathToTextAcpi (
415 IN OUT POOL_PRINT *Str,
416 IN VOID *DevPath,
417 IN BOOLEAN DisplayOnly,
418 IN BOOLEAN AllowShortcuts
419 )
420 {
421 ACPI_HID_DEVICE_PATH *Acpi;
422
423 Acpi = DevPath;
424 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
425 switch (EISA_ID_TO_NUM (Acpi->HID)) {
426 case 0x0a03:
427 UefiDevicePathLibCatPrint (Str, "PciRoot(0x%x)", Acpi->UID);
428 break;
429
430 case 0x0a08:
431 UefiDevicePathLibCatPrint (Str, "PcieRoot(0x%x)", Acpi->UID);
432 break;
433
434 case 0x0604:
435 UefiDevicePathLibCatPrint (Str, "Floppy(0x%x)", Acpi->UID);
436 break;
437
438 case 0x0301:
439 UefiDevicePathLibCatPrint (Str, "Keyboard(0x%x)", Acpi->UID);
440 break;
441
442 case 0x0501:
443 UefiDevicePathLibCatPrint (Str, "Serial(0x%x)", Acpi->UID);
444 break;
445
446 case 0x0401:
447 UefiDevicePathLibCatPrint (Str, "ParallelPort(0x%x)", Acpi->UID);
448 break;
449
450 default:
451 UefiDevicePathLibCatPrint (Str, "Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
452 break;
453 }
454 } else {
455 UefiDevicePathLibCatPrint (Str, "Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID);
456 }
457 }
458
459 /**
460 Converts a ACPI extended HID device path structure to its string representative.
461
462 @param Str The string representative of input device.
463 @param DevPath The input device path structure.
464 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
465 of the display node is used, where applicable. If DisplayOnly
466 is FALSE, then the longer text representation of the display node
467 is used.
468 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
469 representation for a device node can be used, where applicable.
470
471 **/
472 static VOID
DevPathToTextAcpiEx(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)473 DevPathToTextAcpiEx (
474 IN OUT POOL_PRINT *Str,
475 IN VOID *DevPath,
476 IN BOOLEAN DisplayOnly,
477 IN BOOLEAN AllowShortcuts
478 )
479 {
480 ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
481 char HIDText[11];
482 char CIDText[11];
483 UINTN CurrentLength;
484 CHAR8 *CurrentPos;
485 UINTN NextStringOffset;
486 CHAR8 *Strings[3];
487 UINT8 HidStrIndex;
488 UINT8 UidStrIndex;
489 UINT8 CidStrIndex;
490 UINT8 StrIndex;
491
492 HidStrIndex = 0;
493 UidStrIndex = 1;
494 CidStrIndex = 2;
495 AcpiEx = DevPath;
496 Strings[HidStrIndex] = NULL;
497 Strings[UidStrIndex] = NULL;
498 Strings[CidStrIndex] = NULL;
499 CurrentLength = sizeof (ACPI_EXTENDED_HID_DEVICE_PATH);
500 CurrentPos = (CHAR8 *)(((UINT8 *)AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
501 StrIndex = 0;
502 while (CurrentLength < AcpiEx->Header.Length[0] && StrIndex < ARRAY_SIZE (Strings)) {
503 Strings[StrIndex] = CurrentPos;
504 NextStringOffset = AsciiStrLen (CurrentPos) + 1;
505 CurrentLength += NextStringOffset;
506 CurrentPos += NextStringOffset;
507 StrIndex++;
508 }
509
510 if (DisplayOnly) {
511 if ((EISA_ID_TO_NUM (AcpiEx->HID) == 0x0A03) ||
512 ((EISA_ID_TO_NUM (AcpiEx->CID) == 0x0A03) && (EISA_ID_TO_NUM (AcpiEx->HID) != 0x0A08)))
513 {
514 if (Strings[UidStrIndex] != NULL) {
515 UefiDevicePathLibCatPrint (Str, "PciRoot(%s)", Strings[UidStrIndex]);
516 } else {
517 UefiDevicePathLibCatPrint (Str, "PciRoot(0x%x)", AcpiEx->UID);
518 }
519
520 return;
521 }
522
523 if ((EISA_ID_TO_NUM (AcpiEx->HID) == 0x0A08) || (EISA_ID_TO_NUM (AcpiEx->CID) == 0x0A08)) {
524 if (Strings[UidStrIndex] != NULL) {
525 UefiDevicePathLibCatPrint (Str, "PcieRoot(%s)", Strings[UidStrIndex]);
526 } else {
527 UefiDevicePathLibCatPrint (Str, "PcieRoot(0x%x)", AcpiEx->UID);
528 }
529
530 return;
531 }
532 }
533
534 //
535 // Converts EISA identification to string.
536 //
537 UnicodeSPrint (
538 HIDText,
539 sizeof (HIDText),
540 "%c%c%c%04X",
541 ((AcpiEx->HID >> 10) & 0x1f) + 'A' - 1,
542 ((AcpiEx->HID >> 5) & 0x1f) + 'A' - 1,
543 ((AcpiEx->HID >> 0) & 0x1f) + 'A' - 1,
544 (AcpiEx->HID >> 16) & 0xFFFF
545 );
546 UnicodeSPrint (
547 CIDText,
548 sizeof (CIDText),
549 "%c%c%c%04X",
550 ((AcpiEx->CID >> 10) & 0x1f) + 'A' - 1,
551 ((AcpiEx->CID >> 5) & 0x1f) + 'A' - 1,
552 ((AcpiEx->CID >> 0) & 0x1f) + 'A' - 1,
553 (AcpiEx->CID >> 16) & 0xFFFF
554 );
555
556 if (((Strings[HidStrIndex] != NULL) && (*Strings[HidStrIndex] == '\0')) &&
557 ((Strings[CidStrIndex] != NULL) && (*Strings[CidStrIndex] == '\0')) &&
558 ((Strings[UidStrIndex] != NULL) && (*Strings[UidStrIndex] != '\0')))
559 {
560 //
561 // use AcpiExp()
562 //
563 if (AcpiEx->CID == 0) {
564 UefiDevicePathLibCatPrint (
565 Str,
566 "AcpiExp(%s,0,%s)",
567 HIDText,
568 Strings[UidStrIndex]
569 );
570 } else {
571 UefiDevicePathLibCatPrint (
572 Str,
573 "AcpiExp(%s,%s,%s)",
574 HIDText,
575 CIDText,
576 Strings[UidStrIndex]
577 );
578 }
579 } else {
580 if (DisplayOnly) {
581 if (Strings[HidStrIndex] != NULL) {
582 UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", Strings[HidStrIndex]);
583 } else {
584 UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDText);
585 }
586
587 if (Strings[CidStrIndex] != NULL) {
588 UefiDevicePathLibCatPrint (Str, "%s,", Strings[CidStrIndex]);
589 } else {
590 UefiDevicePathLibCatPrint (Str, "%s,", CIDText);
591 }
592
593 if (Strings[UidStrIndex] != NULL) {
594 UefiDevicePathLibCatPrint (Str, "%s)", Strings[UidStrIndex]);
595 } else {
596 UefiDevicePathLibCatPrint (Str, "0x%x)", AcpiEx->UID);
597 }
598 } else {
599 UefiDevicePathLibCatPrint (
600 Str,
601 "AcpiEx(%s,%s,0x%x,%s,%s,%s)",
602 HIDText,
603 CIDText,
604 AcpiEx->UID,
605 Strings[HidStrIndex] != NULL ? Strings[HidStrIndex] : '\0',
606 Strings[CidStrIndex] != NULL ? Strings[CidStrIndex] : '\0',
607 Strings[UidStrIndex] != NULL ? Strings[UidStrIndex] : '\0'
608 );
609 }
610 }
611 }
612
613 /**
614 Converts a ACPI address device path structure to its string representative.
615
616 @param Str The string representative of input device.
617 @param DevPath The input device path structure.
618 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
619 of the display node is used, where applicable. If DisplayOnly
620 is FALSE, then the longer text representation of the display node
621 is used.
622 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
623 representation for a device node can be used, where applicable.
624
625 **/
626 static VOID
DevPathToTextAcpiAdr(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)627 DevPathToTextAcpiAdr (
628 IN OUT POOL_PRINT *Str,
629 IN VOID *DevPath,
630 IN BOOLEAN DisplayOnly,
631 IN BOOLEAN AllowShortcuts
632 )
633 {
634 ACPI_ADR_DEVICE_PATH *AcpiAdr;
635 UINT32 *Addr;
636 UINT16 Index;
637 UINT16 Length;
638 UINT16 AdditionalAdrCount;
639
640 AcpiAdr = DevPath;
641 Length = (UINT16)DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *)AcpiAdr);
642 AdditionalAdrCount = (UINT16)((Length - 8) / 4);
643
644 UefiDevicePathLibCatPrint (Str, "AcpiAdr(0x%x", AcpiAdr->ADR);
645 Addr = &AcpiAdr->ADR + 1;
646 for (Index = 0; Index < AdditionalAdrCount; Index++) {
647 UefiDevicePathLibCatPrint (Str, ",0x%x", Addr[Index]);
648 }
649
650 UefiDevicePathLibCatPrint (Str, ")");
651 }
652
653 /**
654 Converts a ATAPI device path structure to its string representative.
655
656 @param Str The string representative of input device.
657 @param DevPath The input device path structure.
658 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
659 of the display node is used, where applicable. If DisplayOnly
660 is FALSE, then the longer text representation of the display node
661 is used.
662 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
663 representation for a device node can be used, where applicable.
664
665 **/
666 static VOID
DevPathToTextAtapi(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)667 DevPathToTextAtapi (
668 IN OUT POOL_PRINT *Str,
669 IN VOID *DevPath,
670 IN BOOLEAN DisplayOnly,
671 IN BOOLEAN AllowShortcuts
672 )
673 {
674 ATAPI_DEVICE_PATH *Atapi;
675
676 Atapi = DevPath;
677
678 if (DisplayOnly) {
679 UefiDevicePathLibCatPrint (Str, "Ata(0x%x)", Atapi->Lun);
680 } else {
681 UefiDevicePathLibCatPrint (
682 Str,
683 "Ata(%s,%s,0x%x)",
684 (Atapi->PrimarySecondary == 1) ? "Secondary" : "Primary",
685 (Atapi->SlaveMaster == 1) ? "Slave" : "Master",
686 Atapi->Lun
687 );
688 }
689 }
690
691 /**
692 Converts a SCSI device path structure to its string representative.
693
694 @param Str The string representative of input device.
695 @param DevPath The input device path structure.
696 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
697 of the display node is used, where applicable. If DisplayOnly
698 is FALSE, then the longer text representation of the display node
699 is used.
700 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
701 representation for a device node can be used, where applicable.
702
703 **/
704 static VOID
DevPathToTextScsi(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)705 DevPathToTextScsi (
706 IN OUT POOL_PRINT *Str,
707 IN VOID *DevPath,
708 IN BOOLEAN DisplayOnly,
709 IN BOOLEAN AllowShortcuts
710 )
711 {
712 SCSI_DEVICE_PATH *Scsi;
713
714 Scsi = DevPath;
715 UefiDevicePathLibCatPrint (Str, "Scsi(0x%x,0x%x)", Scsi->Pun, Scsi->Lun);
716 }
717
718 /**
719 Converts a Fibre device path structure to its string representative.
720
721 @param Str The string representative of input device.
722 @param DevPath The input device path structure.
723 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
724 of the display node is used, where applicable. If DisplayOnly
725 is FALSE, then the longer text representation of the display node
726 is used.
727 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
728 representation for a device node can be used, where applicable.
729
730 **/
731 static VOID
DevPathToTextFibre(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)732 DevPathToTextFibre (
733 IN OUT POOL_PRINT *Str,
734 IN VOID *DevPath,
735 IN BOOLEAN DisplayOnly,
736 IN BOOLEAN AllowShortcuts
737 )
738 {
739 FIBRECHANNEL_DEVICE_PATH *Fibre;
740
741 Fibre = DevPath;
742 UefiDevicePathLibCatPrint (Str, "Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);
743 }
744
745 /**
746 Converts a FibreEx device path structure to its string representative.
747
748 @param Str The string representative of input device.
749 @param DevPath The input device path structure.
750 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
751 of the display node is used, where applicable. If DisplayOnly
752 is FALSE, then the longer text representation of the display node
753 is used.
754 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
755 representation for a device node can be used, where applicable.
756
757 **/
758 static VOID
DevPathToTextFibreEx(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)759 DevPathToTextFibreEx (
760 IN OUT POOL_PRINT *Str,
761 IN VOID *DevPath,
762 IN BOOLEAN DisplayOnly,
763 IN BOOLEAN AllowShortcuts
764 )
765 {
766 FIBRECHANNELEX_DEVICE_PATH *FibreEx;
767 UINTN Index;
768
769 FibreEx = DevPath;
770 UefiDevicePathLibCatPrint (Str, "FibreEx(0x");
771 for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {
772 UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->WWN[Index]);
773 }
774
775 UefiDevicePathLibCatPrint (Str, ",0x");
776 for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {
777 UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->Lun[Index]);
778 }
779
780 UefiDevicePathLibCatPrint (Str, ")");
781 }
782
783 /**
784 Converts a Sas Ex device path structure to its string representative.
785
786 @param Str The string representative of input device.
787 @param DevPath The input device path structure.
788 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
789 of the display node is used, where applicable. If DisplayOnly
790 is FALSE, then the longer text representation of the display node
791 is used.
792 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
793 representation for a device node can be used, where applicable.
794
795 **/
796 static VOID
DevPathToTextSasEx(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)797 DevPathToTextSasEx (
798 IN OUT POOL_PRINT *Str,
799 IN VOID *DevPath,
800 IN BOOLEAN DisplayOnly,
801 IN BOOLEAN AllowShortcuts
802 )
803 {
804 SASEX_DEVICE_PATH *SasEx;
805 UINTN Index;
806
807 SasEx = DevPath;
808 UefiDevicePathLibCatPrint (Str, "SasEx(0x");
809
810 for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {
811 UefiDevicePathLibCatPrint (Str, "%02x", SasEx->SasAddress[Index]);
812 }
813
814 UefiDevicePathLibCatPrint (Str, ",0x");
815 for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {
816 UefiDevicePathLibCatPrint (Str, "%02x", SasEx->Lun[Index]);
817 }
818
819 UefiDevicePathLibCatPrint (Str, ",0x%x,", SasEx->RelativeTargetPort);
820
821 if (((SasEx->DeviceTopology & 0x0f) == 0) && ((SasEx->DeviceTopology & BIT7) == 0)) {
822 UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0");
823 } else if (((SasEx->DeviceTopology & 0x0f) <= 2) && ((SasEx->DeviceTopology & BIT7) == 0)) {
824 UefiDevicePathLibCatPrint (
825 Str,
826 "%s,%s,%s,",
827 ((SasEx->DeviceTopology & BIT4) != 0) ? "SATA" : "SAS",
828 ((SasEx->DeviceTopology & BIT5) != 0) ? "External" : "Internal",
829 ((SasEx->DeviceTopology & BIT6) != 0) ? "Expanded" : "Direct"
830 );
831 if ((SasEx->DeviceTopology & 0x0f) == 1) {
832 UefiDevicePathLibCatPrint (Str, "0");
833 } else {
834 //
835 // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
836 //
837 UefiDevicePathLibCatPrint (Str, "0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);
838 }
839 } else {
840 UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0", SasEx->DeviceTopology);
841 }
842
843 UefiDevicePathLibCatPrint (Str, ")");
844 return;
845 }
846
847 /**
848 Converts a NVM Express Namespace device path structure to its string representative.
849
850 @param Str The string representative of input device.
851 @param DevPath The input device path structure.
852 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
853 of the display node is used, where applicable. If DisplayOnly
854 is FALSE, then the longer text representation of the display node
855 is used.
856 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
857 representation for a device node can be used, where applicable.
858
859 **/
860 static VOID
DevPathToTextNVMe(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)861 DevPathToTextNVMe (
862 IN OUT POOL_PRINT *Str,
863 IN VOID *DevPath,
864 IN BOOLEAN DisplayOnly,
865 IN BOOLEAN AllowShortcuts
866 )
867 {
868 NVME_NAMESPACE_DEVICE_PATH *Nvme;
869 UINT8 *Uuid;
870
871 Nvme = DevPath;
872 Uuid = (UINT8 *)&Nvme->NamespaceUuid;
873 UefiDevicePathLibCatPrint (
874 Str,
875 "NVMe(0x%x,%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)",
876 Nvme->NamespaceId,
877 Uuid[7],
878 Uuid[6],
879 Uuid[5],
880 Uuid[4],
881 Uuid[3],
882 Uuid[2],
883 Uuid[1],
884 Uuid[0]
885 );
886 }
887
888 /**
889 Converts a UFS device path structure to its string representative.
890
891 @param Str The string representative of input device.
892 @param DevPath The input device path structure.
893 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
894 of the display node is used, where applicable. If DisplayOnly
895 is FALSE, then the longer text representation of the display node
896 is used.
897 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
898 representation for a device node can be used, where applicable.
899
900 **/
901 static VOID
DevPathToTextUfs(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)902 DevPathToTextUfs (
903 IN OUT POOL_PRINT *Str,
904 IN VOID *DevPath,
905 IN BOOLEAN DisplayOnly,
906 IN BOOLEAN AllowShortcuts
907 )
908 {
909 UFS_DEVICE_PATH *Ufs;
910
911 Ufs = DevPath;
912 UefiDevicePathLibCatPrint (Str, "UFS(0x%x,0x%x)", Ufs->Pun, Ufs->Lun);
913 }
914
915 /**
916 Converts a SD (Secure Digital) device path structure to its string representative.
917
918 @param Str The string representative of input device.
919 @param DevPath The input device path structure.
920 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
921 of the display node is used, where applicable. If DisplayOnly
922 is FALSE, then the longer text representation of the display node
923 is used.
924 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
925 representation for a device node can be used, where applicable.
926
927 **/
928 static VOID
DevPathToTextSd(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)929 DevPathToTextSd (
930 IN OUT POOL_PRINT *Str,
931 IN VOID *DevPath,
932 IN BOOLEAN DisplayOnly,
933 IN BOOLEAN AllowShortcuts
934 )
935 {
936 SD_DEVICE_PATH *Sd;
937
938 Sd = DevPath;
939 UefiDevicePathLibCatPrint (
940 Str,
941 "SD(0x%x)",
942 Sd->SlotNumber
943 );
944 }
945
946 /**
947 Converts a EMMC (Embedded MMC) device path structure to its string representative.
948
949 @param Str The string representative of input device.
950 @param DevPath The input device path structure.
951 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
952 of the display node is used, where applicable. If DisplayOnly
953 is FALSE, then the longer text representation of the display node
954 is used.
955 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
956 representation for a device node can be used, where applicable.
957
958 **/
959 static VOID
DevPathToTextEmmc(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)960 DevPathToTextEmmc (
961 IN OUT POOL_PRINT *Str,
962 IN VOID *DevPath,
963 IN BOOLEAN DisplayOnly,
964 IN BOOLEAN AllowShortcuts
965 )
966 {
967 EMMC_DEVICE_PATH *Emmc;
968
969 Emmc = DevPath;
970 UefiDevicePathLibCatPrint (
971 Str,
972 "eMMC(0x%x)",
973 Emmc->SlotNumber
974 );
975 }
976
977 /**
978 Converts a 1394 device path structure to its string representative.
979
980 @param Str The string representative of input device.
981 @param DevPath The input device path structure.
982 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
983 of the display node is used, where applicable. If DisplayOnly
984 is FALSE, then the longer text representation of the display node
985 is used.
986 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
987 representation for a device node can be used, where applicable.
988
989 **/
990 static VOID
DevPathToText1394(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)991 DevPathToText1394 (
992 IN OUT POOL_PRINT *Str,
993 IN VOID *DevPath,
994 IN BOOLEAN DisplayOnly,
995 IN BOOLEAN AllowShortcuts
996 )
997 {
998 F1394_DEVICE_PATH *F1394DevPath;
999
1000 F1394DevPath = DevPath;
1001 //
1002 // Guid has format of IEEE-EUI64
1003 //
1004 UefiDevicePathLibCatPrint (Str, "I1394(%016lx)", F1394DevPath->Guid);
1005 }
1006
1007 /**
1008 Converts a USB device path structure to its string representative.
1009
1010 @param Str The string representative of input device.
1011 @param DevPath The input device path structure.
1012 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1013 of the display node is used, where applicable. If DisplayOnly
1014 is FALSE, then the longer text representation of the display node
1015 is used.
1016 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1017 representation for a device node can be used, where applicable.
1018
1019 **/
1020 static VOID
DevPathToTextUsb(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1021 DevPathToTextUsb (
1022 IN OUT POOL_PRINT *Str,
1023 IN VOID *DevPath,
1024 IN BOOLEAN DisplayOnly,
1025 IN BOOLEAN AllowShortcuts
1026 )
1027 {
1028 USB_DEVICE_PATH *Usb;
1029
1030 Usb = DevPath;
1031 UefiDevicePathLibCatPrint (Str, "USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
1032 }
1033
1034 /**
1035 Converts a USB WWID device path structure to its string representative.
1036
1037 @param Str The string representative of input device.
1038 @param DevPath The input device path structure.
1039 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1040 of the display node is used, where applicable. If DisplayOnly
1041 is FALSE, then the longer text representation of the display node
1042 is used.
1043 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1044 representation for a device node can be used, where applicable.
1045
1046 **/
1047 static VOID
DevPathToTextUsbWWID(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1048 DevPathToTextUsbWWID (
1049 IN OUT POOL_PRINT *Str,
1050 IN VOID *DevPath,
1051 IN BOOLEAN DisplayOnly,
1052 IN BOOLEAN AllowShortcuts
1053 )
1054 {
1055 USB_WWID_DEVICE_PATH *UsbWWId;
1056 CHAR16 *SerialNumberStr;
1057 CHAR16 *NewStr;
1058 UINT16 Length;
1059
1060 UsbWWId = DevPath;
1061
1062 SerialNumberStr = (CHAR16 *)(&UsbWWId + 1);
1063 Length = (UINT16)((DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *)UsbWWId) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16));
1064 if ((Length >= 1) && (SerialNumberStr[Length - 1] != 0)) {
1065 //
1066 // In case no NULL terminator in SerialNumber, create a new one with NULL terminator
1067 //
1068 NewStr = AllocatePool ((Length + 1) * sizeof (CHAR16));
1069 ASSERT (NewStr != NULL);
1070 CopyMem (NewStr, SerialNumberStr, Length * sizeof (CHAR16));
1071 NewStr[Length] = 0;
1072 SerialNumberStr = NewStr;
1073 }
1074
1075 UefiDevicePathLibCatPrint (
1076 Str,
1077 "UsbWwid(0x%x,0x%x,0x%x,\"%S\")",
1078 UsbWWId->VendorId,
1079 UsbWWId->ProductId,
1080 UsbWWId->InterfaceNumber,
1081 SerialNumberStr
1082 );
1083 }
1084
1085 /**
1086 Converts a Logic Unit device path structure to its string representative.
1087
1088 @param Str The string representative of input device.
1089 @param DevPath The input device path structure.
1090 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1091 of the display node is used, where applicable. If DisplayOnly
1092 is FALSE, then the longer text representation of the display node
1093 is used.
1094 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1095 representation for a device node can be used, where applicable.
1096
1097 **/
1098 static VOID
DevPathToTextLogicalUnit(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1099 DevPathToTextLogicalUnit (
1100 IN OUT POOL_PRINT *Str,
1101 IN VOID *DevPath,
1102 IN BOOLEAN DisplayOnly,
1103 IN BOOLEAN AllowShortcuts
1104 )
1105 {
1106 DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
1107
1108 LogicalUnit = DevPath;
1109 UefiDevicePathLibCatPrint (Str, "Unit(0x%x)", LogicalUnit->Lun);
1110 }
1111
1112 /**
1113 Converts a USB class device path structure to its string representative.
1114
1115 @param Str The string representative of input device.
1116 @param DevPath The input device path structure.
1117 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1118 of the display node is used, where applicable. If DisplayOnly
1119 is FALSE, then the longer text representation of the display node
1120 is used.
1121 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1122 representation for a device node can be used, where applicable.
1123
1124 **/
1125 static VOID
DevPathToTextUsbClass(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1126 DevPathToTextUsbClass (
1127 IN OUT POOL_PRINT *Str,
1128 IN VOID *DevPath,
1129 IN BOOLEAN DisplayOnly,
1130 IN BOOLEAN AllowShortcuts
1131 )
1132 {
1133 USB_CLASS_DEVICE_PATH *UsbClass;
1134 BOOLEAN IsKnownSubClass;
1135
1136 UsbClass = DevPath;
1137
1138 IsKnownSubClass = TRUE;
1139 switch (UsbClass->DeviceClass) {
1140 case USB_CLASS_AUDIO:
1141 UefiDevicePathLibCatPrint (Str, "UsbAudio");
1142 break;
1143
1144 case USB_CLASS_CDCCONTROL:
1145 UefiDevicePathLibCatPrint (Str, "UsbCDCControl");
1146 break;
1147
1148 case USB_CLASS_HID:
1149 UefiDevicePathLibCatPrint (Str, "UsbHID");
1150 break;
1151
1152 case USB_CLASS_IMAGE:
1153 UefiDevicePathLibCatPrint (Str, "UsbImage");
1154 break;
1155
1156 case USB_CLASS_PRINTER:
1157 UefiDevicePathLibCatPrint (Str, "UsbPrinter");
1158 break;
1159
1160 case USB_CLASS_MASS_STORAGE:
1161 UefiDevicePathLibCatPrint (Str, "UsbMassStorage");
1162 break;
1163
1164 case USB_CLASS_HUB:
1165 UefiDevicePathLibCatPrint (Str, "UsbHub");
1166 break;
1167
1168 case USB_CLASS_CDCDATA:
1169 UefiDevicePathLibCatPrint (Str, "UsbCDCData");
1170 break;
1171
1172 case USB_CLASS_SMART_CARD:
1173 UefiDevicePathLibCatPrint (Str, "UsbSmartCard");
1174 break;
1175
1176 case USB_CLASS_VIDEO:
1177 UefiDevicePathLibCatPrint (Str, "UsbVideo");
1178 break;
1179
1180 case USB_CLASS_DIAGNOSTIC:
1181 UefiDevicePathLibCatPrint (Str, "UsbDiagnostic");
1182 break;
1183
1184 case USB_CLASS_WIRELESS:
1185 UefiDevicePathLibCatPrint (Str, "UsbWireless");
1186 break;
1187
1188 default:
1189 IsKnownSubClass = FALSE;
1190 break;
1191 }
1192
1193 if (IsKnownSubClass) {
1194 UefiDevicePathLibCatPrint (
1195 Str,
1196 "(0x%x,0x%x,0x%x,0x%x)",
1197 UsbClass->VendorId,
1198 UsbClass->ProductId,
1199 UsbClass->DeviceSubClass,
1200 UsbClass->DeviceProtocol
1201 );
1202 return;
1203 }
1204
1205 if (UsbClass->DeviceClass == USB_CLASS_RESERVE) {
1206 if (UsbClass->DeviceSubClass == USB_SUBCLASS_FW_UPDATE) {
1207 UefiDevicePathLibCatPrint (
1208 Str,
1209 "UsbDeviceFirmwareUpdate(0x%x,0x%x,0x%x)",
1210 UsbClass->VendorId,
1211 UsbClass->ProductId,
1212 UsbClass->DeviceProtocol
1213 );
1214 return;
1215 } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_IRDA_BRIDGE) {
1216 UefiDevicePathLibCatPrint (
1217 Str,
1218 "UsbIrdaBridge(0x%x,0x%x,0x%x)",
1219 UsbClass->VendorId,
1220 UsbClass->ProductId,
1221 UsbClass->DeviceProtocol
1222 );
1223 return;
1224 } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_TEST) {
1225 UefiDevicePathLibCatPrint (
1226 Str,
1227 "UsbTestAndMeasurement(0x%x,0x%x,0x%x)",
1228 UsbClass->VendorId,
1229 UsbClass->ProductId,
1230 UsbClass->DeviceProtocol
1231 );
1232 return;
1233 }
1234 }
1235
1236 UefiDevicePathLibCatPrint (
1237 Str,
1238 "UsbClass(0x%x,0x%x,0x%x,0x%x,0x%x)",
1239 UsbClass->VendorId,
1240 UsbClass->ProductId,
1241 UsbClass->DeviceClass,
1242 UsbClass->DeviceSubClass,
1243 UsbClass->DeviceProtocol
1244 );
1245 }
1246
1247 /**
1248 Converts a SATA device path structure to its string representative.
1249
1250 @param Str The string representative of input device.
1251 @param DevPath The input device path structure.
1252 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1253 of the display node is used, where applicable. If DisplayOnly
1254 is FALSE, then the longer text representation of the display node
1255 is used.
1256 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1257 representation for a device node can be used, where applicable.
1258
1259 **/
1260 static VOID
DevPathToTextSata(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1261 DevPathToTextSata (
1262 IN OUT POOL_PRINT *Str,
1263 IN VOID *DevPath,
1264 IN BOOLEAN DisplayOnly,
1265 IN BOOLEAN AllowShortcuts
1266 )
1267 {
1268 SATA_DEVICE_PATH *Sata;
1269
1270 Sata = DevPath;
1271 UefiDevicePathLibCatPrint (
1272 Str,
1273 "Sata(0x%x,0x%x,0x%x)",
1274 Sata->HBAPortNumber,
1275 Sata->PortMultiplierPortNumber,
1276 Sata->Lun
1277 );
1278 }
1279
1280 /**
1281 Converts a I20 device path structure to its string representative.
1282
1283 @param Str The string representative of input device.
1284 @param DevPath The input device path structure.
1285 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1286 of the display node is used, where applicable. If DisplayOnly
1287 is FALSE, then the longer text representation of the display node
1288 is used.
1289 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1290 representation for a device node can be used, where applicable.
1291
1292 **/
1293 static VOID
DevPathToTextI2O(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1294 DevPathToTextI2O (
1295 IN OUT POOL_PRINT *Str,
1296 IN VOID *DevPath,
1297 IN BOOLEAN DisplayOnly,
1298 IN BOOLEAN AllowShortcuts
1299 )
1300 {
1301 I2O_DEVICE_PATH *I2ODevPath;
1302
1303 I2ODevPath = DevPath;
1304 UefiDevicePathLibCatPrint (Str, "I2O(0x%x)", I2ODevPath->Tid);
1305 }
1306
1307 /**
1308 Converts a MAC address device path structure to its string representative.
1309
1310 @param Str The string representative of input device.
1311 @param DevPath The input device path structure.
1312 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1313 of the display node is used, where applicable. If DisplayOnly
1314 is FALSE, then the longer text representation of the display node
1315 is used.
1316 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1317 representation for a device node can be used, where applicable.
1318
1319 **/
1320 static VOID
DevPathToTextMacAddr(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1321 DevPathToTextMacAddr (
1322 IN OUT POOL_PRINT *Str,
1323 IN VOID *DevPath,
1324 IN BOOLEAN DisplayOnly,
1325 IN BOOLEAN AllowShortcuts
1326 )
1327 {
1328 MAC_ADDR_DEVICE_PATH *MacDevPath;
1329 UINTN HwAddressSize;
1330 UINTN Index;
1331
1332 MacDevPath = DevPath;
1333
1334 HwAddressSize = sizeof (EFI_MAC_ADDRESS);
1335 if ((MacDevPath->IfType == 0x01) || (MacDevPath->IfType == 0x00)) {
1336 HwAddressSize = 6;
1337 }
1338
1339 UefiDevicePathLibCatPrint (Str, "MAC(");
1340
1341 for (Index = 0; Index < HwAddressSize; Index++) {
1342 UefiDevicePathLibCatPrint (Str, "%02x", MacDevPath->MacAddress.Addr[Index]);
1343 }
1344
1345 UefiDevicePathLibCatPrint (Str, ",0x%x)", MacDevPath->IfType);
1346 }
1347
1348 /**
1349 Converts network protocol string to its text representation.
1350
1351 @param Str The string representative of input device.
1352 @param Protocol The network protocol ID.
1353
1354 **/
1355 static VOID
CatNetworkProtocol(IN OUT POOL_PRINT * Str,IN UINT16 Protocol)1356 CatNetworkProtocol (
1357 IN OUT POOL_PRINT *Str,
1358 IN UINT16 Protocol
1359 )
1360 {
1361 if (Protocol == RFC_1700_TCP_PROTOCOL) {
1362 UefiDevicePathLibCatPrint (Str, "TCP");
1363 } else if (Protocol == RFC_1700_UDP_PROTOCOL) {
1364 UefiDevicePathLibCatPrint (Str, "UDP");
1365 } else {
1366 UefiDevicePathLibCatPrint (Str, "0x%x", Protocol);
1367 }
1368 }
1369
1370 /**
1371 Converts IP v4 address to its text representation.
1372
1373 @param Str The string representative of input device.
1374 @param Address The IP v4 address.
1375 **/
1376 static VOID
CatIPv4Address(IN OUT POOL_PRINT * Str,IN EFI_IPv4_ADDRESS * Address)1377 CatIPv4Address (
1378 IN OUT POOL_PRINT *Str,
1379 IN EFI_IPv4_ADDRESS *Address
1380 )
1381 {
1382 UefiDevicePathLibCatPrint (Str, "%d.%d.%d.%d", Address->Addr[0], Address->Addr[1], Address->Addr[2], Address->Addr[3]);
1383 }
1384
1385 /**
1386 Converts IP v6 address to its text representation.
1387
1388 @param Str The string representative of input device.
1389 @param Address The IP v6 address.
1390 **/
1391 static VOID
CatIPv6Address(IN OUT POOL_PRINT * Str,IN EFI_IPv6_ADDRESS * Address)1392 CatIPv6Address (
1393 IN OUT POOL_PRINT *Str,
1394 IN EFI_IPv6_ADDRESS *Address
1395 )
1396 {
1397 UefiDevicePathLibCatPrint (
1398 Str,
1399 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
1400 Address->Addr[0],
1401 Address->Addr[1],
1402 Address->Addr[2],
1403 Address->Addr[3],
1404 Address->Addr[4],
1405 Address->Addr[5],
1406 Address->Addr[6],
1407 Address->Addr[7],
1408 Address->Addr[8],
1409 Address->Addr[9],
1410 Address->Addr[10],
1411 Address->Addr[11],
1412 Address->Addr[12],
1413 Address->Addr[13],
1414 Address->Addr[14],
1415 Address->Addr[15]
1416 );
1417 }
1418
1419 /**
1420 Converts a IPv4 device path structure to its string representative.
1421
1422 @param Str The string representative of input device.
1423 @param DevPath The input device path structure.
1424 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1425 of the display node is used, where applicable. If DisplayOnly
1426 is FALSE, then the longer text representation of the display node
1427 is used.
1428 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1429 representation for a device node can be used, where applicable.
1430
1431 **/
1432 static VOID
DevPathToTextIPv4(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1433 DevPathToTextIPv4 (
1434 IN OUT POOL_PRINT *Str,
1435 IN VOID *DevPath,
1436 IN BOOLEAN DisplayOnly,
1437 IN BOOLEAN AllowShortcuts
1438 )
1439 {
1440 IPv4_DEVICE_PATH *IPDevPath;
1441
1442 IPDevPath = DevPath;
1443 UefiDevicePathLibCatPrint (Str, "IPv4(");
1444 CatIPv4Address (Str, &IPDevPath->RemoteIpAddress);
1445
1446 if (DisplayOnly) {
1447 UefiDevicePathLibCatPrint (Str, ")");
1448 return;
1449 }
1450
1451 UefiDevicePathLibCatPrint (Str, ",");
1452 CatNetworkProtocol (Str, IPDevPath->Protocol);
1453
1454 UefiDevicePathLibCatPrint (Str, ",%s,", IPDevPath->StaticIpAddress ? "Static" : "DHCP");
1455 CatIPv4Address (Str, &IPDevPath->LocalIpAddress);
1456 if (DevicePathNodeLength (IPDevPath) == sizeof (IPv4_DEVICE_PATH)) {
1457 UefiDevicePathLibCatPrint (Str, ",");
1458 CatIPv4Address (Str, &IPDevPath->GatewayIpAddress);
1459 UefiDevicePathLibCatPrint (Str, ",");
1460 CatIPv4Address (Str, &IPDevPath->SubnetMask);
1461 }
1462
1463 UefiDevicePathLibCatPrint (Str, ")");
1464 }
1465
1466 /**
1467 Converts a IPv6 device path structure to its string representative.
1468
1469 @param Str The string representative of input device.
1470 @param DevPath The input device path structure.
1471 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1472 of the display node is used, where applicable. If DisplayOnly
1473 is FALSE, then the longer text representation of the display node
1474 is used.
1475 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1476 representation for a device node can be used, where applicable.
1477
1478 **/
1479 static VOID
DevPathToTextIPv6(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1480 DevPathToTextIPv6 (
1481 IN OUT POOL_PRINT *Str,
1482 IN VOID *DevPath,
1483 IN BOOLEAN DisplayOnly,
1484 IN BOOLEAN AllowShortcuts
1485 )
1486 {
1487 IPv6_DEVICE_PATH *IPDevPath;
1488
1489 IPDevPath = DevPath;
1490 UefiDevicePathLibCatPrint (Str, "IPv6(");
1491 CatIPv6Address (Str, &IPDevPath->RemoteIpAddress);
1492 if (DisplayOnly) {
1493 UefiDevicePathLibCatPrint (Str, ")");
1494 return;
1495 }
1496
1497 UefiDevicePathLibCatPrint (Str, ",");
1498 CatNetworkProtocol (Str, IPDevPath->Protocol);
1499
1500 switch (IPDevPath->IpAddressOrigin) {
1501 case 0:
1502 UefiDevicePathLibCatPrint (Str, ",Static,");
1503 break;
1504 case 1:
1505 UefiDevicePathLibCatPrint (Str, ",StatelessAutoConfigure,");
1506 break;
1507 default:
1508 UefiDevicePathLibCatPrint (Str, ",StatefulAutoConfigure,");
1509 break;
1510 }
1511
1512 CatIPv6Address (Str, &IPDevPath->LocalIpAddress);
1513
1514 if (DevicePathNodeLength (IPDevPath) == sizeof (IPv6_DEVICE_PATH)) {
1515 UefiDevicePathLibCatPrint (Str, ",0x%x,", IPDevPath->PrefixLength);
1516 CatIPv6Address (Str, &IPDevPath->GatewayIpAddress);
1517 }
1518
1519 UefiDevicePathLibCatPrint (Str, ")");
1520 }
1521
1522 /**
1523 Converts an Infini Band device path structure to its string representative.
1524
1525 @param Str The string representative of input device.
1526 @param DevPath The input device path structure.
1527 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1528 of the display node is used, where applicable. If DisplayOnly
1529 is FALSE, then the longer text representation of the display node
1530 is used.
1531 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1532 representation for a device node can be used, where applicable.
1533
1534 **/
1535 static VOID
DevPathToTextInfiniBand(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1536 DevPathToTextInfiniBand (
1537 IN OUT POOL_PRINT *Str,
1538 IN VOID *DevPath,
1539 IN BOOLEAN DisplayOnly,
1540 IN BOOLEAN AllowShortcuts
1541 )
1542 {
1543 INFINIBAND_DEVICE_PATH *InfiniBand;
1544
1545 InfiniBand = DevPath;
1546 UefiDevicePathLibCatPrint (
1547 Str,
1548 "Infiniband(0x%x,%36s,0x%lx,0x%lx,0x%lx)",
1549 InfiniBand->ResourceFlags,
1550 G(InfiniBand->PortGid),
1551 InfiniBand->ServiceId,
1552 InfiniBand->TargetPortId,
1553 InfiniBand->DeviceId
1554 );
1555 }
1556
1557 /**
1558 Converts a UART device path structure to its string representative.
1559
1560 @param Str The string representative of input device.
1561 @param DevPath The input device path structure.
1562 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1563 of the display node is used, where applicable. If DisplayOnly
1564 is FALSE, then the longer text representation of the display node
1565 is used.
1566 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1567 representation for a device node can be used, where applicable.
1568
1569 **/
1570 static VOID
DevPathToTextUart(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1571 DevPathToTextUart (
1572 IN OUT POOL_PRINT *Str,
1573 IN VOID *DevPath,
1574 IN BOOLEAN DisplayOnly,
1575 IN BOOLEAN AllowShortcuts
1576 )
1577 {
1578 UART_DEVICE_PATH *Uart;
1579 CHAR8 Parity;
1580
1581 Uart = DevPath;
1582 switch (Uart->Parity) {
1583 case 0:
1584 Parity = 'D';
1585 break;
1586
1587 case 1:
1588 Parity = 'N';
1589 break;
1590
1591 case 2:
1592 Parity = 'E';
1593 break;
1594
1595 case 3:
1596 Parity = 'O';
1597 break;
1598
1599 case 4:
1600 Parity = 'M';
1601 break;
1602
1603 case 5:
1604 Parity = 'S';
1605 break;
1606
1607 default:
1608 Parity = 'x';
1609 break;
1610 }
1611
1612 if (Uart->BaudRate == 0) {
1613 UefiDevicePathLibCatPrint (Str, "Uart(DEFAULT,");
1614 } else {
1615 UefiDevicePathLibCatPrint (Str, "Uart(%ld,", Uart->BaudRate);
1616 }
1617
1618 if (Uart->DataBits == 0) {
1619 UefiDevicePathLibCatPrint (Str, "DEFAULT,");
1620 } else {
1621 UefiDevicePathLibCatPrint (Str, "%d,", Uart->DataBits);
1622 }
1623
1624 UefiDevicePathLibCatPrint (Str, "%c,", Parity);
1625
1626 switch (Uart->StopBits) {
1627 case 0:
1628 UefiDevicePathLibCatPrint (Str, "D)");
1629 break;
1630
1631 case 1:
1632 UefiDevicePathLibCatPrint (Str, "1)");
1633 break;
1634
1635 case 2:
1636 UefiDevicePathLibCatPrint (Str, "1.5)");
1637 break;
1638
1639 case 3:
1640 UefiDevicePathLibCatPrint (Str, "2)");
1641 break;
1642
1643 default:
1644 UefiDevicePathLibCatPrint (Str, "x)");
1645 break;
1646 }
1647 }
1648
1649 /**
1650 Converts an iSCSI device path structure to its string representative.
1651
1652 @param Str The string representative of input device.
1653 @param DevPath The input device path structure.
1654 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1655 of the display node is used, where applicable. If DisplayOnly
1656 is FALSE, then the longer text representation of the display node
1657 is used.
1658 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1659 representation for a device node can be used, where applicable.
1660
1661 **/
1662 static VOID
DevPathToTextiSCSI(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1663 DevPathToTextiSCSI (
1664 IN OUT POOL_PRINT *Str,
1665 IN VOID *DevPath,
1666 IN BOOLEAN DisplayOnly,
1667 IN BOOLEAN AllowShortcuts
1668 )
1669 {
1670 ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
1671 UINT16 Options;
1672 UINTN Index;
1673
1674 ISCSIDevPath = DevPath;
1675 UefiDevicePathLibCatPrint (
1676 Str,
1677 "iSCSI(%s,0x%x,0x",
1678 ISCSIDevPath->TargetName,
1679 ISCSIDevPath->TargetPortalGroupTag
1680 );
1681 for (Index = 0; Index < sizeof (ISCSIDevPath->Lun) / sizeof (UINT8); Index++) {
1682 UefiDevicePathLibCatPrint (Str, "%02x", ((UINT8 *)&ISCSIDevPath->Lun)[Index]);
1683 }
1684
1685 Options = ISCSIDevPath->LoginOption;
1686 UefiDevicePathLibCatPrint (Str, ",%s,", (((Options >> 1) & 0x0001) != 0) ? "CRC32C" : "None");
1687 UefiDevicePathLibCatPrint (Str, "%s,", (((Options >> 3) & 0x0001) != 0) ? "CRC32C" : "None");
1688 if (((Options >> 11) & 0x0001) != 0) {
1689 UefiDevicePathLibCatPrint (Str, "%s,", "None");
1690 } else if (((Options >> 12) & 0x0001) != 0) {
1691 UefiDevicePathLibCatPrint (Str, "%s,", "CHAP_UNI");
1692 } else {
1693 UefiDevicePathLibCatPrint (Str, "%s,", "CHAP_BI");
1694 }
1695
1696 UefiDevicePathLibCatPrint (Str, "%s)", (ISCSIDevPath->NetworkProtocol == 0) ? "TCP" : "reserved");
1697 }
1698
1699 /**
1700 Converts a VLAN device path structure to its string representative.
1701
1702 @param Str The string representative of input device.
1703 @param DevPath The input device path structure.
1704 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1705 of the display node is used, where applicable. If DisplayOnly
1706 is FALSE, then the longer text representation of the display node
1707 is used.
1708 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1709 representation for a device node can be used, where applicable.
1710
1711 **/
1712 static VOID
DevPathToTextVlan(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1713 DevPathToTextVlan (
1714 IN OUT POOL_PRINT *Str,
1715 IN VOID *DevPath,
1716 IN BOOLEAN DisplayOnly,
1717 IN BOOLEAN AllowShortcuts
1718 )
1719 {
1720 VLAN_DEVICE_PATH *Vlan;
1721
1722 Vlan = DevPath;
1723 UefiDevicePathLibCatPrint (Str, "Vlan(%d)", Vlan->VlanId);
1724 }
1725
1726 /**
1727 Converts a Bluetooth device path structure to its string representative.
1728
1729 @param Str The string representative of input device.
1730 @param DevPath The input device path structure.
1731 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1732 of the display node is used, where applicable. If DisplayOnly
1733 is FALSE, then the longer text representation of the display node
1734 is used.
1735 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1736 representation for a device node can be used, where applicable.
1737
1738 **/
1739 static VOID
DevPathToTextBluetooth(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1740 DevPathToTextBluetooth (
1741 IN OUT POOL_PRINT *Str,
1742 IN VOID *DevPath,
1743 IN BOOLEAN DisplayOnly,
1744 IN BOOLEAN AllowShortcuts
1745 )
1746 {
1747 BLUETOOTH_DEVICE_PATH *Bluetooth;
1748
1749 Bluetooth = DevPath;
1750 UefiDevicePathLibCatPrint (
1751 Str,
1752 "Bluetooth(%02x%02x%02x%02x%02x%02x)",
1753 Bluetooth->BD_ADDR.Address[0],
1754 Bluetooth->BD_ADDR.Address[1],
1755 Bluetooth->BD_ADDR.Address[2],
1756 Bluetooth->BD_ADDR.Address[3],
1757 Bluetooth->BD_ADDR.Address[4],
1758 Bluetooth->BD_ADDR.Address[5]
1759 );
1760 }
1761
1762 /**
1763 Converts a Wi-Fi device path structure to its string representative.
1764
1765 @param Str The string representative of input device.
1766 @param DevPath The input device path structure.
1767 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1768 of the display node is used, where applicable. If DisplayOnly
1769 is FALSE, then the longer text representation of the display node
1770 is used.
1771 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1772 representation for a device node can be used, where applicable.
1773
1774 **/
1775 static VOID
DevPathToTextWiFi(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1776 DevPathToTextWiFi (
1777 IN OUT POOL_PRINT *Str,
1778 IN VOID *DevPath,
1779 IN BOOLEAN DisplayOnly,
1780 IN BOOLEAN AllowShortcuts
1781 )
1782 {
1783 WIFI_DEVICE_PATH *WiFi;
1784 UINT8 SSId[33];
1785
1786 WiFi = DevPath;
1787
1788 SSId[32] = '\0';
1789 CopyMem (SSId, WiFi->SSId, 32);
1790
1791 UefiDevicePathLibCatPrint (Str, "Wi-Fi(%s)", SSId);
1792 }
1793
1794 /**
1795 Converts a Bluetooth device path structure to its string representative.
1796
1797 @param Str The string representative of input device.
1798 @param DevPath The input device path structure.
1799 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1800 of the display node is used, where applicable. If DisplayOnly
1801 is FALSE, then the longer text representation of the display node
1802 is used.
1803 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1804 representation for a device node can be used, where applicable.
1805
1806 **/
1807 static VOID
DevPathToTextBluetoothLE(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1808 DevPathToTextBluetoothLE (
1809 IN OUT POOL_PRINT *Str,
1810 IN VOID *DevPath,
1811 IN BOOLEAN DisplayOnly,
1812 IN BOOLEAN AllowShortcuts
1813 )
1814 {
1815 BLUETOOTH_LE_DEVICE_PATH *BluetoothLE;
1816
1817 BluetoothLE = DevPath;
1818 UefiDevicePathLibCatPrint (
1819 Str,
1820 "BluetoothLE(%02x%02x%02x%02x%02x%02x,0x%02x)",
1821 BluetoothLE->Address.Address[0],
1822 BluetoothLE->Address.Address[1],
1823 BluetoothLE->Address.Address[2],
1824 BluetoothLE->Address.Address[3],
1825 BluetoothLE->Address.Address[4],
1826 BluetoothLE->Address.Address[5],
1827 BluetoothLE->Address.Type
1828 );
1829 }
1830
1831 /**
1832 Converts a DNS device path structure to its string representative.
1833
1834 @param Str The string representative of input device.
1835 @param DevPath The input device path structure.
1836 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1837 of the display node is used, where applicable. If DisplayOnly
1838 is FALSE, then the longer text representation of the display node
1839 is used.
1840 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1841 representation for a device node can be used, where applicable.
1842
1843 **/
1844 static VOID
DevPathToTextDns(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1845 DevPathToTextDns (
1846 IN OUT POOL_PRINT *Str,
1847 IN VOID *DevPath,
1848 IN BOOLEAN DisplayOnly,
1849 IN BOOLEAN AllowShortcuts
1850 )
1851 {
1852 DNS_DEVICE_PATH *DnsDevPath;
1853 UINT32 DnsServerIpCount;
1854 UINT32 DnsServerIpIndex;
1855
1856 DnsDevPath = DevPath;
1857 DnsServerIpCount = (UINT32)(DevicePathNodeLength (DnsDevPath) - sizeof (EFI_DEVICE_PATH_PROTOCOL) - sizeof (DnsDevPath->IsIPv6)) / sizeof (EFI_IP_ADDRESS);
1858
1859 UefiDevicePathLibCatPrint (Str, "Dns(");
1860
1861 for (DnsServerIpIndex = 0; DnsServerIpIndex < DnsServerIpCount; DnsServerIpIndex++) {
1862 if (DnsDevPath->IsIPv6 == 0x00) {
1863 CatIPv4Address (Str, &(DnsDevPath->DnsServerIp[DnsServerIpIndex].v4));
1864 } else {
1865 CatIPv6Address (Str, &(DnsDevPath->DnsServerIp[DnsServerIpIndex].v6));
1866 }
1867
1868 if (DnsServerIpIndex < DnsServerIpCount - 1) {
1869 UefiDevicePathLibCatPrint (Str, ",");
1870 }
1871 }
1872
1873 UefiDevicePathLibCatPrint (Str, ")");
1874 }
1875
1876 /**
1877 Converts a URI device path structure to its string representative.
1878
1879 @param Str The string representative of input device.
1880 @param DevPath The input device path structure.
1881 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1882 of the display node is used, where applicable. If DisplayOnly
1883 is FALSE, then the longer text representation of the display node
1884 is used.
1885 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1886 representation for a device node can be used, where applicable.
1887
1888 **/
1889 static VOID
DevPathToTextUri(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1890 DevPathToTextUri (
1891 IN OUT POOL_PRINT *Str,
1892 IN VOID *DevPath,
1893 IN BOOLEAN DisplayOnly,
1894 IN BOOLEAN AllowShortcuts
1895 )
1896 {
1897 URI_DEVICE_PATH *Uri;
1898 UINTN UriLength;
1899 CHAR8 *UriStr;
1900
1901 //
1902 // Uri in the device path may not be null terminated.
1903 //
1904 Uri = DevPath;
1905 UriLength = DevicePathNodeLength (Uri) - sizeof (URI_DEVICE_PATH);
1906 UriStr = AllocatePool (UriLength + 1);
1907
1908 if (UriStr == NULL) {
1909 ASSERT (UriStr != NULL);
1910 return;
1911 }
1912
1913 CopyMem (UriStr, Uri->Uri, UriLength);
1914 UriStr[UriLength] = '\0';
1915 UefiDevicePathLibCatPrint (Str, "Uri(%s)", UriStr);
1916 FreePool (UriStr);
1917 }
1918
1919 /**
1920 Converts a Hard drive device path structure to its string representative.
1921
1922 @param Str The string representative of input device.
1923 @param DevPath The input device path structure.
1924 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1925 of the display node is used, where applicable. If DisplayOnly
1926 is FALSE, then the longer text representation of the display node
1927 is used.
1928 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1929 representation for a device node can be used, where applicable.
1930
1931 **/
1932 static VOID
DevPathToTextHardDrive(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1933 DevPathToTextHardDrive (
1934 IN OUT POOL_PRINT *Str,
1935 IN VOID *DevPath,
1936 IN BOOLEAN DisplayOnly,
1937 IN BOOLEAN AllowShortcuts
1938 )
1939 {
1940 HARDDRIVE_DEVICE_PATH *Hd;
1941
1942 Hd = DevPath;
1943 switch (Hd->SignatureType) {
1944 case SIGNATURE_TYPE_MBR:
1945 UefiDevicePathLibCatPrint (
1946 Str,
1947 "HD(%d,%s,0x%08x",
1948 Hd->PartitionNumber,
1949 "MBR",
1950 // *((UINT32 *)(&(Hd->Signature[0])))
1951 le32dec(&(Hd->Signature[0]))
1952 );
1953 break;
1954
1955 case SIGNATURE_TYPE_GUID:
1956 UefiDevicePathLibCatPrint (
1957 Str,
1958 "HD(%d,%s,%36s",
1959 Hd->PartitionNumber,
1960 "GPT",
1961 G(&(Hd->Signature[0]))
1962 );
1963 break;
1964
1965 default:
1966 UefiDevicePathLibCatPrint (
1967 Str,
1968 "HD(%d,%d,0",
1969 Hd->PartitionNumber,
1970 Hd->SignatureType
1971 );
1972 break;
1973 }
1974
1975 if (DisplayOnly) {
1976 UefiDevicePathLibCatPrint (Str, ")");
1977 } else {
1978 UefiDevicePathLibCatPrint (Str, ",0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
1979 }
1980 }
1981
1982 /**
1983 Converts a CDROM device path structure to its string representative.
1984
1985 @param Str The string representative of input device.
1986 @param DevPath The input device path structure.
1987 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
1988 of the display node is used, where applicable. If DisplayOnly
1989 is FALSE, then the longer text representation of the display node
1990 is used.
1991 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
1992 representation for a device node can be used, where applicable.
1993
1994 **/
1995 static VOID
DevPathToTextCDROM(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)1996 DevPathToTextCDROM (
1997 IN OUT POOL_PRINT *Str,
1998 IN VOID *DevPath,
1999 IN BOOLEAN DisplayOnly,
2000 IN BOOLEAN AllowShortcuts
2001 )
2002 {
2003 CDROM_DEVICE_PATH *Cd;
2004
2005 Cd = DevPath;
2006 if (DisplayOnly) {
2007 UefiDevicePathLibCatPrint (Str, "CDROM(0x%x)", Cd->BootEntry);
2008 return;
2009 }
2010
2011 UefiDevicePathLibCatPrint (Str, "CDROM(0x%x,0x%lx,0x%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
2012 }
2013
2014 /**
2015 Converts a File device path structure to its string representative.
2016
2017 @param Str The string representative of input device.
2018 @param DevPath The input device path structure.
2019 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2020 of the display node is used, where applicable. If DisplayOnly
2021 is FALSE, then the longer text representation of the display node
2022 is used.
2023 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2024 representation for a device node can be used, where applicable.
2025
2026 **/
2027 static VOID
DevPathToTextFilePath(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2028 DevPathToTextFilePath (
2029 IN OUT POOL_PRINT *Str,
2030 IN VOID *DevPath,
2031 IN BOOLEAN DisplayOnly,
2032 IN BOOLEAN AllowShortcuts
2033 )
2034 {
2035 FILEPATH_DEVICE_PATH *Fp;
2036 char *name = NULL;
2037
2038 Fp = DevPath;
2039 ucs2_to_utf8(Fp->PathName, &name);
2040 UefiDevicePathLibCatPrint (Str, "File(%s)", name);
2041 free(name);
2042 }
2043
2044 /**
2045 Converts a Media protocol device path structure to its string representative.
2046
2047 @param Str The string representative of input device.
2048 @param DevPath The input device path structure.
2049 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2050 of the display node is used, where applicable. If DisplayOnly
2051 is FALSE, then the longer text representation of the display node
2052 is used.
2053 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2054 representation for a device node can be used, where applicable.
2055
2056 **/
2057 static VOID
DevPathToTextMediaProtocol(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2058 DevPathToTextMediaProtocol (
2059 IN OUT POOL_PRINT *Str,
2060 IN VOID *DevPath,
2061 IN BOOLEAN DisplayOnly,
2062 IN BOOLEAN AllowShortcuts
2063 )
2064 {
2065 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
2066
2067 MediaProt = DevPath;
2068 UefiDevicePathLibCatPrint (Str, "Media(%36s)", G(&MediaProt->Protocol));
2069 }
2070
2071 /**
2072 Converts a Firmware Volume device path structure to its string representative.
2073
2074 @param Str The string representative of input device.
2075 @param DevPath The input device path structure.
2076 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2077 of the display node is used, where applicable. If DisplayOnly
2078 is FALSE, then the longer text representation of the display node
2079 is used.
2080 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2081 representation for a device node can be used, where applicable.
2082
2083 **/
2084 static VOID
DevPathToTextFv(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2085 DevPathToTextFv (
2086 IN OUT POOL_PRINT *Str,
2087 IN VOID *DevPath,
2088 IN BOOLEAN DisplayOnly,
2089 IN BOOLEAN AllowShortcuts
2090 )
2091 {
2092 MEDIA_FW_VOL_DEVICE_PATH *Fv;
2093
2094 Fv = DevPath;
2095 UefiDevicePathLibCatPrint (Str, "Fv(%36s)", G(&Fv->FvName));
2096 }
2097
2098 /**
2099 Converts a Firmware Volume File device path structure to its string representative.
2100
2101 @param Str The string representative of input device.
2102 @param DevPath The input device path structure.
2103 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2104 of the display node is used, where applicable. If DisplayOnly
2105 is FALSE, then the longer text representation of the display node
2106 is used.
2107 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2108 representation for a device node can be used, where applicable.
2109
2110 **/
2111 static VOID
DevPathToTextFvFile(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2112 DevPathToTextFvFile (
2113 IN OUT POOL_PRINT *Str,
2114 IN VOID *DevPath,
2115 IN BOOLEAN DisplayOnly,
2116 IN BOOLEAN AllowShortcuts
2117 )
2118 {
2119 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile;
2120
2121 FvFile = DevPath;
2122 UefiDevicePathLibCatPrint (Str, "FvFile(%36s)", G(&FvFile->FvFileName));
2123 }
2124
2125 /**
2126 Converts a Relative Offset device path structure to its string representative.
2127
2128 @param Str The string representative of input device.
2129 @param DevPath The input device path structure.
2130 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2131 of the display node is used, where applicable. If DisplayOnly
2132 is FALSE, then the longer text representation of the display node
2133 is used.
2134 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2135 representation for a device node can be used, where applicable.
2136
2137 **/
2138 static VOID
DevPathRelativeOffsetRange(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2139 DevPathRelativeOffsetRange (
2140 IN OUT POOL_PRINT *Str,
2141 IN VOID *DevPath,
2142 IN BOOLEAN DisplayOnly,
2143 IN BOOLEAN AllowShortcuts
2144 )
2145 {
2146 MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
2147
2148 Offset = DevPath;
2149 UefiDevicePathLibCatPrint (
2150 Str,
2151 "Offset(0x%lx,0x%lx)",
2152 Offset->StartingOffset,
2153 Offset->EndingOffset
2154 );
2155 }
2156
2157 /**
2158 Converts a Ram Disk device path structure to its string representative.
2159
2160 @param Str The string representative of input device.
2161 @param DevPath The input device path structure.
2162 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2163 of the display node is used, where applicable. If DisplayOnly
2164 is FALSE, then the longer text representation of the display node
2165 is used.
2166 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2167 representation for a device node can be used, where applicable.
2168
2169 **/
2170 static VOID
DevPathToTextRamDisk(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2171 DevPathToTextRamDisk (
2172 IN OUT POOL_PRINT *Str,
2173 IN VOID *DevPath,
2174 IN BOOLEAN DisplayOnly,
2175 IN BOOLEAN AllowShortcuts
2176 )
2177 {
2178 MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
2179
2180 RamDisk = DevPath;
2181
2182 if (CompareGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid)) {
2183 UefiDevicePathLibCatPrint (
2184 Str,
2185 "VirtualDisk(0x%lx,0x%lx,%d)",
2186 LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2187 LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2188 RamDisk->Instance
2189 );
2190 } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid)) {
2191 UefiDevicePathLibCatPrint (
2192 Str,
2193 "VirtualCD(0x%lx,0x%lx,%d)",
2194 LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2195 LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2196 RamDisk->Instance
2197 );
2198 } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid)) {
2199 UefiDevicePathLibCatPrint (
2200 Str,
2201 "PersistentVirtualDisk(0x%lx,0x%lx,%d)",
2202 LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2203 LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2204 RamDisk->Instance
2205 );
2206 } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid)) {
2207 UefiDevicePathLibCatPrint (
2208 Str,
2209 "PersistentVirtualCD(0x%lx,0x%lx,%d)",
2210 LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2211 LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2212 RamDisk->Instance
2213 );
2214 } else {
2215 UefiDevicePathLibCatPrint (
2216 Str,
2217 "RamDisk(0x%lx,0x%lx,%d,%36s)",
2218 LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2219 LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2220 RamDisk->Instance,
2221 G(&RamDisk->TypeGuid)
2222 );
2223 }
2224 }
2225
2226 /**
2227 Converts a BIOS Boot Specification device path structure to its string representative.
2228
2229 @param Str The string representative of input device.
2230 @param DevPath The input device path structure.
2231 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2232 of the display node is used, where applicable. If DisplayOnly
2233 is FALSE, then the longer text representation of the display node
2234 is used.
2235 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2236 representation for a device node can be used, where applicable.
2237
2238 **/
2239 static VOID
DevPathToTextBBS(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2240 DevPathToTextBBS (
2241 IN OUT POOL_PRINT *Str,
2242 IN VOID *DevPath,
2243 IN BOOLEAN DisplayOnly,
2244 IN BOOLEAN AllowShortcuts
2245 )
2246 {
2247 BBS_BBS_DEVICE_PATH *Bbs;
2248 const char *Type;
2249
2250 Bbs = DevPath;
2251 switch (Bbs->DeviceType) {
2252 case BBS_TYPE_FLOPPY:
2253 Type = "Floppy";
2254 break;
2255
2256 case BBS_TYPE_HARDDRIVE:
2257 Type = "HD";
2258 break;
2259
2260 case BBS_TYPE_CDROM:
2261 Type = "CDROM";
2262 break;
2263
2264 case BBS_TYPE_PCMCIA:
2265 Type = "PCMCIA";
2266 break;
2267
2268 case BBS_TYPE_USB:
2269 Type = "USB";
2270 break;
2271
2272 case BBS_TYPE_EMBEDDED_NETWORK:
2273 Type = "Network";
2274 break;
2275
2276 default:
2277 Type = NULL;
2278 break;
2279 }
2280
2281 if (Type != NULL) {
2282 UefiDevicePathLibCatPrint (Str, "BBS(%s,%s", Type, Bbs->String);
2283 } else {
2284 UefiDevicePathLibCatPrint (Str, "BBS(0x%x,%s", Bbs->DeviceType, Bbs->String);
2285 }
2286
2287 if (DisplayOnly) {
2288 UefiDevicePathLibCatPrint (Str, ")");
2289 return;
2290 }
2291
2292 UefiDevicePathLibCatPrint (Str, ",0x%x)", Bbs->StatusFlag);
2293 }
2294
2295 /**
2296 Converts an End-of-Device-Path structure to its string representative.
2297
2298 @param Str The string representative of input device.
2299 @param DevPath The input device path structure.
2300 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2301 of the display node is used, where applicable. If DisplayOnly
2302 is FALSE, then the longer text representation of the display node
2303 is used.
2304 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2305 representation for a device node can be used, where applicable.
2306
2307 **/
2308 static VOID
DevPathToTextEndInstance(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2309 DevPathToTextEndInstance (
2310 IN OUT POOL_PRINT *Str,
2311 IN VOID *DevPath,
2312 IN BOOLEAN DisplayOnly,
2313 IN BOOLEAN AllowShortcuts
2314 )
2315 {
2316 UefiDevicePathLibCatPrint (Str, ",");
2317 }
2318
2319 GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_GENERIC_TABLE mUefiDevicePathLibToTextTableGeneric[] = {
2320 { HARDWARE_DEVICE_PATH, "HardwarePath" },
2321 { ACPI_DEVICE_PATH, "AcpiPath" },
2322 { MESSAGING_DEVICE_PATH, "Msg" },
2323 { MEDIA_DEVICE_PATH, "MediaPath" },
2324 { BBS_DEVICE_PATH, "BbsPath" },
2325 { 0, NULL }
2326 };
2327
2328 /**
2329 Converts an unknown device path structure to its string representative.
2330
2331 @param Str The string representative of input device.
2332 @param DevPath The input device path structure.
2333 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2334 of the display node is used, where applicable. If DisplayOnly
2335 is FALSE, then the longer text representation of the display node
2336 is used.
2337 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2338 representation for a device node can be used, where applicable.
2339
2340 **/
2341 static VOID
DevPathToTextNodeGeneric(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2342 DevPathToTextNodeGeneric (
2343 IN OUT POOL_PRINT *Str,
2344 IN VOID *DevPath,
2345 IN BOOLEAN DisplayOnly,
2346 IN BOOLEAN AllowShortcuts
2347 )
2348 {
2349 EFI_DEVICE_PATH_PROTOCOL *Node;
2350 UINTN Index;
2351
2352 Node = DevPath;
2353
2354 for (Index = 0; mUefiDevicePathLibToTextTableGeneric[Index].Text != NULL; Index++) {
2355 if (DevicePathType (Node) == mUefiDevicePathLibToTextTableGeneric[Index].Type) {
2356 break;
2357 }
2358 }
2359
2360 if (mUefiDevicePathLibToTextTableGeneric[Index].Text == NULL) {
2361 //
2362 // It's a node whose type cannot be recognized
2363 //
2364 UefiDevicePathLibCatPrint (Str, "Path(%d,%d", DevicePathType (Node), DevicePathSubType (Node));
2365 } else {
2366 //
2367 // It's a node whose type can be recognized
2368 //
2369 UefiDevicePathLibCatPrint (Str, "%s(%d", mUefiDevicePathLibToTextTableGeneric[Index].Text, DevicePathSubType (Node));
2370 }
2371
2372 Index = sizeof (EFI_DEVICE_PATH_PROTOCOL);
2373 if (Index < DevicePathNodeLength (Node)) {
2374 UefiDevicePathLibCatPrint (Str, ",");
2375 for ( ; Index < DevicePathNodeLength (Node); Index++) {
2376 UefiDevicePathLibCatPrint (Str, "%02x", ((UINT8 *)Node)[Index]);
2377 }
2378 }
2379
2380 UefiDevicePathLibCatPrint (Str, ")");
2381 }
2382
2383 static const DEVICE_PATH_TO_TEXT_TABLE mUefiDevicePathLibToTextTable[] = {
2384 { HARDWARE_DEVICE_PATH, HW_PCI_DP, DevPathToTextPci },
2385 { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, DevPathToTextPccard },
2386 { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, DevPathToTextMemMap },
2387 { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DevPathToTextVendor },
2388 { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, DevPathToTextController },
2389 { HARDWARE_DEVICE_PATH, HW_BMC_DP, DevPathToTextBmc },
2390 { ACPI_DEVICE_PATH, ACPI_DP, DevPathToTextAcpi },
2391 { ACPI_DEVICE_PATH, ACPI_EXTENDED_DP, DevPathToTextAcpiEx },
2392 { ACPI_DEVICE_PATH, ACPI_ADR_DP, DevPathToTextAcpiAdr },
2393 { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, DevPathToTextAtapi },
2394 { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, DevPathToTextScsi },
2395 { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, DevPathToTextFibre },
2396 { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNELEX_DP, DevPathToTextFibreEx },
2397 { MESSAGING_DEVICE_PATH, MSG_SASEX_DP, DevPathToTextSasEx },
2398 { MESSAGING_DEVICE_PATH, MSG_NVME_NAMESPACE_DP, DevPathToTextNVMe },
2399 { MESSAGING_DEVICE_PATH, MSG_UFS_DP, DevPathToTextUfs },
2400 { MESSAGING_DEVICE_PATH, MSG_SD_DP, DevPathToTextSd },
2401 { MESSAGING_DEVICE_PATH, MSG_EMMC_DP, DevPathToTextEmmc },
2402 { MESSAGING_DEVICE_PATH, MSG_1394_DP, DevPathToText1394 },
2403 { MESSAGING_DEVICE_PATH, MSG_USB_DP, DevPathToTextUsb },
2404 { MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP, DevPathToTextUsbWWID },
2405 { MESSAGING_DEVICE_PATH, MSG_DEVICE_LOGICAL_UNIT_DP, DevPathToTextLogicalUnit },
2406 { MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, DevPathToTextUsbClass },
2407 { MESSAGING_DEVICE_PATH, MSG_SATA_DP, DevPathToTextSata },
2408 { MESSAGING_DEVICE_PATH, MSG_I2O_DP, DevPathToTextI2O },
2409 { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, DevPathToTextMacAddr },
2410 { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, DevPathToTextIPv4 },
2411 { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, DevPathToTextIPv6 },
2412 { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, DevPathToTextInfiniBand },
2413 { MESSAGING_DEVICE_PATH, MSG_UART_DP, DevPathToTextUart },
2414 { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, DevPathToTextVendor },
2415 { MESSAGING_DEVICE_PATH, MSG_ISCSI_DP, DevPathToTextiSCSI },
2416 { MESSAGING_DEVICE_PATH, MSG_VLAN_DP, DevPathToTextVlan },
2417 { MESSAGING_DEVICE_PATH, MSG_DNS_DP, DevPathToTextDns },
2418 { MESSAGING_DEVICE_PATH, MSG_URI_DP, DevPathToTextUri },
2419 { MESSAGING_DEVICE_PATH, MSG_BLUETOOTH_DP, DevPathToTextBluetooth },
2420 { MESSAGING_DEVICE_PATH, MSG_WIFI_DP, DevPathToTextWiFi },
2421 { MESSAGING_DEVICE_PATH, MSG_BLUETOOTH_LE_DP, DevPathToTextBluetoothLE },
2422 { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, DevPathToTextHardDrive },
2423 { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, DevPathToTextCDROM },
2424 { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, DevPathToTextVendor },
2425 { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, DevPathToTextMediaProtocol },
2426 { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, DevPathToTextFilePath },
2427 { MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_VOL_DP, DevPathToTextFv },
2428 { MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_FILE_DP, DevPathToTextFvFile },
2429 { MEDIA_DEVICE_PATH, MEDIA_RELATIVE_OFFSET_RANGE_DP, DevPathRelativeOffsetRange },
2430 { MEDIA_DEVICE_PATH, MEDIA_RAM_DISK_DP, DevPathToTextRamDisk },
2431 { BBS_DEVICE_PATH, BBS_BBS_DP, DevPathToTextBBS },
2432 { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance },
2433 { 0, 0, NULL }
2434 };
2435
2436 /**
2437 Converts a device node to its string representation.
2438
2439 @param DeviceNode A Pointer to the device node to be converted.
2440 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2441 of the display node is used, where applicable. If DisplayOnly
2442 is FALSE, then the longer text representation of the display node
2443 is used.
2444 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2445 representation for a device node can be used, where applicable.
2446
2447 @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
2448 is NULL or there was insufficient memory.
2449
2450 **/
2451 static char *
2452 EFIAPI
UefiDevicePathLibConvertDeviceNodeToText(IN CONST EFI_DEVICE_PATH_PROTOCOL * DeviceNode,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2453 UefiDevicePathLibConvertDeviceNodeToText (
2454 IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
2455 IN BOOLEAN DisplayOnly,
2456 IN BOOLEAN AllowShortcuts
2457 )
2458 {
2459 POOL_PRINT Str;
2460 UINTN Index;
2461 DEVICE_PATH_TO_TEXT ToText;
2462 EFI_DEVICE_PATH_PROTOCOL *Node;
2463
2464 if (DeviceNode == NULL) {
2465 return NULL;
2466 }
2467
2468 ZeroMem (&Str, sizeof (Str));
2469
2470 //
2471 // Process the device path node
2472 // If not found, use a generic function
2473 //
2474 Node = __DECONST(EFI_DEVICE_PATH_PROTOCOL *, DeviceNode);
2475 ToText = DevPathToTextNodeGeneric;
2476 for (Index = 0; mUefiDevicePathLibToTextTable[Index].Function != NULL; Index++) {
2477 if ((DevicePathType (DeviceNode) == mUefiDevicePathLibToTextTable[Index].Type) &&
2478 (DevicePathSubType (DeviceNode) == mUefiDevicePathLibToTextTable[Index].SubType)
2479 )
2480 {
2481 ToText = mUefiDevicePathLibToTextTable[Index].Function;
2482 break;
2483 }
2484 }
2485
2486 //
2487 // Print this node
2488 //
2489 ToText (&Str, (VOID *)Node, DisplayOnly, AllowShortcuts);
2490
2491 ASSERT (Str.Str != NULL);
2492 return Str.Str;
2493 }
2494
2495 /**
2496 Converts a device path to its text representation.
2497
2498 @param DevicePath A Pointer to the device to be converted.
2499 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
2500 of the display node is used, where applicable. If DisplayOnly
2501 is FALSE, then the longer text representation of the display node
2502 is used.
2503 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
2504 representation for a device node can be used, where applicable.
2505
2506 @return A pointer to the allocated text representation of the device path or
2507 NULL if DeviceNode is NULL or there was insufficient memory.
2508
2509 **/
2510 static char *
2511 EFIAPI
UefiDevicePathLibConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevicePath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)2512 UefiDevicePathLibConvertDevicePathToText (
2513 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
2514 IN BOOLEAN DisplayOnly,
2515 IN BOOLEAN AllowShortcuts
2516 )
2517 {
2518 POOL_PRINT Str;
2519 EFI_DEVICE_PATH_PROTOCOL *Node;
2520 EFI_DEVICE_PATH_PROTOCOL *AlignedNode;
2521 UINTN Index;
2522 DEVICE_PATH_TO_TEXT ToText;
2523
2524 if (DevicePath == NULL) {
2525 return NULL;
2526 }
2527
2528 ZeroMem (&Str, sizeof (Str));
2529
2530 //
2531 // Process each device path node
2532 //
2533 Node = __DECONST(EFI_DEVICE_PATH_PROTOCOL *, DevicePath);
2534 while (!IsDevicePathEnd (Node)) {
2535 //
2536 // Find the handler to dump this device path node
2537 // If not found, use a generic function
2538 //
2539 ToText = DevPathToTextNodeGeneric;
2540 for (Index = 0; mUefiDevicePathLibToTextTable[Index].Function != NULL; Index += 1) {
2541 if ((DevicePathType (Node) == mUefiDevicePathLibToTextTable[Index].Type) &&
2542 (DevicePathSubType (Node) == mUefiDevicePathLibToTextTable[Index].SubType)
2543 )
2544 {
2545 ToText = mUefiDevicePathLibToTextTable[Index].Function;
2546 break;
2547 }
2548 }
2549
2550 //
2551 // Put a path separator in if needed
2552 //
2553 if ((Str.Count != 0) && (ToText != DevPathToTextEndInstance)) {
2554 if (Str.Str[Str.Count] != ',') {
2555 UefiDevicePathLibCatPrint (&Str, "/");
2556 }
2557 }
2558
2559 AlignedNode = AllocateCopyPool (DevicePathNodeLength (Node), Node);
2560 //
2561 // Print this node of the device path
2562 //
2563 ToText (&Str, AlignedNode, DisplayOnly, AllowShortcuts);
2564 FreePool (AlignedNode);
2565
2566 //
2567 // Next device path node
2568 //
2569 Node = NextDevicePathNode (Node);
2570 }
2571
2572 if (Str.Str == NULL) {
2573 return AllocateZeroPool (sizeof (CHAR16));
2574 } else {
2575 return Str.Str;
2576 }
2577 }
2578
2579 ssize_t
efidp_format_device_path(char * buf,size_t len,const_efidp dp,ssize_t max)2580 efidp_format_device_path(char *buf, size_t len, const_efidp dp, ssize_t max)
2581 {
2582 char *str;
2583 ssize_t retval;
2584
2585 /*
2586 * Basic sanity check on the device path.
2587 */
2588 if (!IsDevicePathValid((CONST EFI_DEVICE_PATH_PROTOCOL *) dp, max)) {
2589 *buf = '\0';
2590 return 0;
2591 }
2592
2593 str = UefiDevicePathLibConvertDevicePathToText (
2594 __DECONST(EFI_DEVICE_PATH_PROTOCOL *, dp), FALSE, TRUE);
2595 if (str == NULL)
2596 return -1;
2597 strlcpy(buf, str, len);
2598 retval = strlen(str);
2599 free(str);
2600
2601 return retval;
2602 }
2603
2604 ssize_t
efidp_format_device_path_node(char * buf,size_t len,const_efidp dp)2605 efidp_format_device_path_node(char *buf, size_t len, const_efidp dp)
2606 {
2607 char *str;
2608 ssize_t retval;
2609
2610 str = UefiDevicePathLibConvertDeviceNodeToText (
2611 __DECONST(EFI_DEVICE_PATH_PROTOCOL *, dp), FALSE, TRUE);
2612 if (str == NULL)
2613 return -1;
2614 strlcpy(buf, str, len);
2615 retval = strlen(str);
2616 free(str);
2617
2618 return retval;
2619 }
2620
2621 size_t
efidp_size(const_efidp dp)2622 efidp_size(const_efidp dp)
2623 {
2624
2625 return GetDevicePathSize(__DECONST(EFI_DEVICE_PATH_PROTOCOL *, dp));
2626 }
2627
2628 char *
efidp_extract_file_path(const_efidp dp)2629 efidp_extract_file_path(const_efidp dp)
2630 {
2631 const FILEPATH_DEVICE_PATH *fp;
2632 char *name = NULL;
2633
2634 fp = (const void *)dp;
2635 ucs2_to_utf8(fp->PathName, &name);
2636 return name;
2637 }
2638