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