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