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