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