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