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 <ctype.h> 32 #include <efivar.h> 33 #include <stdio.h> 34 #include <string.h> 35 #include <wchar.h> 36 37 #include "efichar.h" 38 39 #include "efi-osdep.h" 40 #include "efivar-dp.h" 41 42 #include "uefi-dplib.h" 43 44 /* XXX STUBS -- this stuff doesn't work yet */ 45 #define StrToIpv4Address(str, unk, ipv4ptr, unk2) (void)(str) 46 #define StrToIpv6Address(str, unk, ipv6ptr, unk2) (void)(str) 47 48 /* 49 * OK. Now this is evil. Can't typedef it again. Sure beats changing them all. 50 * Since we're doing it all as narrow characters since wchar_t can't be used on 51 * FreeBSD and CHAR16 strings generally aren't a good fit. Since this parsing 52 * doesn't need Unicode for anything, this works out well. 53 */ 54 #define CHAR16 char 55 56 /* 57 * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c 58 */ 59 60 /** @file 61 DevicePathFromText protocol as defined in the UEFI 2.0 specification. 62 63 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> 64 SPDX-License-Identifier: BSD-2-Clause-Patent 65 66 **/ 67 68 // #include "UefiDevicePathLib.h" 69 70 /** 71 72 Duplicates a string. 73 74 @param Src Source string. 75 76 @return The duplicated string. 77 78 **/ 79 static 80 CHAR16 * 81 UefiDevicePathLibStrDuplicate ( 82 IN CONST CHAR16 *Src 83 ) 84 { 85 return AllocateCopyPool (StrSize (Src), Src); 86 } 87 88 /** 89 90 Get parameter in a pair of parentheses follow the given node name. 91 For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1". 92 93 @param Str Device Path Text. 94 @param NodeName Name of the node. 95 96 @return Parameter text for the node. 97 98 **/ 99 static 100 CHAR16 * 101 GetParamByNodeName ( 102 IN CHAR16 *Str, 103 IN const CHAR16 *NodeName 104 ) 105 { 106 CHAR16 *ParamStr; 107 CHAR16 *StrPointer; 108 UINTN NodeNameLength; 109 UINTN ParameterLength; 110 111 // 112 // Check whether the node name matchs 113 // 114 NodeNameLength = StrLen (NodeName); 115 if (StrnCmp (Str, NodeName, NodeNameLength) != 0) { 116 return NULL; 117 } 118 119 ParamStr = Str + NodeNameLength; 120 if (!IS_LEFT_PARENTH (*ParamStr)) { 121 return NULL; 122 } 123 124 // 125 // Skip the found '(' and find first occurrence of ')' 126 // 127 ParamStr++; 128 ParameterLength = 0; 129 StrPointer = ParamStr; 130 while (!IS_NULL (*StrPointer)) { 131 if (IS_RIGHT_PARENTH (*StrPointer)) { 132 break; 133 } 134 135 StrPointer++; 136 ParameterLength++; 137 } 138 139 if (IS_NULL (*StrPointer)) { 140 // 141 // ')' not found 142 // 143 return NULL; 144 } 145 146 ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr); 147 if (ParamStr == NULL) { 148 return NULL; 149 } 150 151 // 152 // Terminate the parameter string 153 // 154 ParamStr[ParameterLength] = '\0'; 155 156 return ParamStr; 157 } 158 159 /** 160 Gets current sub-string from a string list, before return 161 the list header is moved to next sub-string. The sub-string is separated 162 by the specified character. For example, the separator is ',', the string 163 list is "2,0,3", it returns "2", the remain list move to "0,3" 164 165 @param List A string list separated by the specified separator 166 @param Separator The separator character 167 168 @return A pointer to the current sub-string 169 170 **/ 171 static 172 CHAR16 * 173 SplitStr ( 174 IN OUT CHAR16 **List, 175 IN CHAR16 Separator 176 ) 177 { 178 CHAR16 *Str; 179 CHAR16 *ReturnStr; 180 181 Str = *List; 182 ReturnStr = Str; 183 184 if (IS_NULL (*Str)) { 185 return ReturnStr; 186 } 187 188 // 189 // Find first occurrence of the separator 190 // 191 while (!IS_NULL (*Str)) { 192 if (*Str == Separator) { 193 break; 194 } 195 196 Str++; 197 } 198 199 if (*Str == Separator) { 200 // 201 // Find a sub-string, terminate it 202 // 203 *Str = '\0'; 204 Str++; 205 } 206 207 // 208 // Move to next sub-string 209 // 210 *List = Str; 211 212 return ReturnStr; 213 } 214 215 /** 216 Gets the next parameter string from the list. 217 218 @param List A string list separated by the specified separator 219 220 @return A pointer to the current sub-string 221 222 **/ 223 static 224 CHAR16 * 225 GetNextParamStr ( 226 IN OUT CHAR16 **List 227 ) 228 { 229 // 230 // The separator is comma 231 // 232 return SplitStr (List, ','); 233 } 234 235 /** 236 Get one device node from entire device path text. 237 238 @param DevicePath On input, the current Device Path node; on output, the next device path node 239 @param IsInstanceEnd This node is the end of a device path instance 240 241 @return A device node text or NULL if no more device node available 242 243 **/ 244 static 245 CHAR16 * 246 GetNextDeviceNodeStr ( 247 IN OUT CHAR16 **DevicePath, 248 OUT BOOLEAN *IsInstanceEnd 249 ) 250 { 251 CHAR16 *Str; 252 CHAR16 *ReturnStr; 253 UINTN ParenthesesStack; 254 255 Str = *DevicePath; 256 if (IS_NULL (*Str)) { 257 return NULL; 258 } 259 260 // 261 // Skip the leading '/', '(', ')' and ',' 262 // 263 while (!IS_NULL (*Str)) { 264 if (!IS_SLASH (*Str) && 265 !IS_COMMA (*Str) && 266 !IS_LEFT_PARENTH (*Str) && 267 !IS_RIGHT_PARENTH (*Str)) 268 { 269 break; 270 } 271 272 Str++; 273 } 274 275 ReturnStr = Str; 276 277 // 278 // Scan for the separator of this device node, '/' or ',' 279 // 280 ParenthesesStack = 0; 281 while (!IS_NULL (*Str)) { 282 if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) { 283 break; 284 } 285 286 if (IS_LEFT_PARENTH (*Str)) { 287 ParenthesesStack++; 288 } else if (IS_RIGHT_PARENTH (*Str)) { 289 ParenthesesStack--; 290 } 291 292 Str++; 293 } 294 295 if (ParenthesesStack != 0) { 296 // 297 // The '(' doesn't pair with ')', invalid device path text 298 // 299 return NULL; 300 } 301 302 if (IS_COMMA (*Str)) { 303 *IsInstanceEnd = TRUE; 304 *Str = '\0'; 305 Str++; 306 } else { 307 *IsInstanceEnd = FALSE; 308 if (!IS_NULL (*Str)) { 309 *Str = '\0'; 310 Str++; 311 } 312 } 313 314 *DevicePath = Str; 315 316 return ReturnStr; 317 } 318 319 320 #ifndef __FreeBSD__ 321 /** 322 Return whether the integer string is a hex string. 323 324 @param Str The integer string 325 326 @retval TRUE Hex string 327 @retval FALSE Decimal string 328 329 **/ 330 static 331 BOOLEAN 332 IsHexStr ( 333 IN CHAR16 *Str 334 ) 335 { 336 // 337 // skip preceeding white space 338 // 339 while (*Str == ' ') { 340 Str++; 341 } 342 343 // 344 // skip preceeding zeros 345 // 346 while (*Str == '0') { 347 Str++; 348 } 349 350 return (BOOLEAN)(*Str == 'x' || *Str == 'X'); 351 } 352 353 /** 354 355 Convert integer string to uint. 356 357 @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. 358 359 @return A UINTN value represented by Str 360 361 **/ 362 static 363 UINTN 364 Strtoi ( 365 IN CHAR16 *Str 366 ) 367 { 368 if (IsHexStr (Str)) { 369 return StrHexToUintn (Str); 370 } else { 371 return StrDecimalToUintn (Str); 372 } 373 } 374 375 /** 376 377 Convert integer string to 64 bit data. 378 379 @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. 380 @param Data A pointer to the UINT64 value represented by Str 381 382 **/ 383 static 384 VOID 385 Strtoi64 ( 386 IN CHAR16 *Str, 387 OUT UINT64 *Data 388 ) 389 { 390 if (IsHexStr (Str)) { 391 *Data = StrHexToUint64 (Str); 392 } else { 393 *Data = StrDecimalToUint64 (Str); 394 } 395 } 396 #endif 397 398 /** 399 Converts a Unicode string to ASCII string. 400 401 @param Str The equivalent Unicode string 402 @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points 403 to the next ASCII string next to it 404 405 **/ 406 static 407 VOID 408 StrToAscii ( 409 IN CHAR16 *Str, 410 IN OUT CHAR8 **AsciiStr 411 ) 412 { 413 CHAR8 *Dest; 414 415 Dest = *AsciiStr; 416 while (!IS_NULL (*Str)) { 417 *(Dest++) = (CHAR8)*(Str++); 418 } 419 420 *Dest = 0; 421 422 // 423 // Return the string next to it 424 // 425 *AsciiStr = Dest + 1; 426 } 427 428 /** 429 Converts a generic text device path node to device path structure. 430 431 @param Type The type of the device path node. 432 @param TextDeviceNode The input text device path node. 433 434 @return A pointer to device path structure. 435 **/ 436 static 437 EFI_DEVICE_PATH_PROTOCOL * 438 DevPathFromTextGenericPath ( 439 IN UINT8 Type, 440 IN CHAR16 *TextDeviceNode 441 ) 442 { 443 EFI_DEVICE_PATH_PROTOCOL *Node; 444 CHAR16 *SubtypeStr; 445 CHAR16 *DataStr; 446 UINTN DataLength; 447 448 SubtypeStr = GetNextParamStr (&TextDeviceNode); 449 DataStr = GetNextParamStr (&TextDeviceNode); 450 451 if (DataStr == NULL) { 452 DataLength = 0; 453 } else { 454 DataLength = StrLen (DataStr) / 2; 455 } 456 457 Node = CreateDeviceNode ( 458 Type, 459 (UINT8)Strtoi (SubtypeStr), 460 (UINT16)(sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength) 461 ); 462 463 if (Node != NULL) { 464 StrHexToBytes (DataStr, DataLength * 2, (UINT8 *)(Node + 1), DataLength); 465 } 466 467 return Node; 468 } 469 470 /** 471 Converts a generic text device path node to device path structure. 472 473 @param TextDeviceNode The input Text device path node. 474 475 @return A pointer to device path structure. 476 477 **/ 478 static 479 EFI_DEVICE_PATH_PROTOCOL * 480 DevPathFromTextPath ( 481 IN CHAR16 *TextDeviceNode 482 ) 483 { 484 CHAR16 *TypeStr; 485 486 TypeStr = GetNextParamStr (&TextDeviceNode); 487 488 return DevPathFromTextGenericPath ((UINT8)Strtoi (TypeStr), TextDeviceNode); 489 } 490 491 /** 492 Converts a generic hardware text device path node to Hardware device path structure. 493 494 @param TextDeviceNode The input Text device path node. 495 496 @return A pointer to Hardware device path structure. 497 498 **/ 499 static 500 EFI_DEVICE_PATH_PROTOCOL * 501 DevPathFromTextHardwarePath ( 502 IN CHAR16 *TextDeviceNode 503 ) 504 { 505 return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, TextDeviceNode); 506 } 507 508 /** 509 Converts a text device path node to Hardware PCI device path structure. 510 511 @param TextDeviceNode The input Text device path node. 512 513 @return A pointer to Hardware PCI device path structure. 514 515 **/ 516 static 517 EFI_DEVICE_PATH_PROTOCOL * 518 DevPathFromTextPci ( 519 IN CHAR16 *TextDeviceNode 520 ) 521 { 522 CHAR16 *FunctionStr; 523 CHAR16 *DeviceStr; 524 PCI_DEVICE_PATH *Pci; 525 526 DeviceStr = GetNextParamStr (&TextDeviceNode); 527 FunctionStr = GetNextParamStr (&TextDeviceNode); 528 Pci = (PCI_DEVICE_PATH *)CreateDeviceNode ( 529 HARDWARE_DEVICE_PATH, 530 HW_PCI_DP, 531 (UINT16)sizeof (PCI_DEVICE_PATH) 532 ); 533 534 if (Pci != NULL) { 535 Pci->Function = (UINT8)Strtoi (FunctionStr); 536 Pci->Device = (UINT8)Strtoi (DeviceStr); 537 } 538 539 return (EFI_DEVICE_PATH_PROTOCOL *)Pci; 540 } 541 542 /** 543 Converts a text device path node to Hardware PC card device path structure. 544 545 @param TextDeviceNode The input Text device path node. 546 547 @return A pointer to Hardware PC card device path structure. 548 549 **/ 550 static 551 EFI_DEVICE_PATH_PROTOCOL * 552 DevPathFromTextPcCard ( 553 IN CHAR16 *TextDeviceNode 554 ) 555 { 556 CHAR16 *FunctionNumberStr; 557 PCCARD_DEVICE_PATH *Pccard; 558 559 FunctionNumberStr = GetNextParamStr (&TextDeviceNode); 560 Pccard = (PCCARD_DEVICE_PATH *)CreateDeviceNode ( 561 HARDWARE_DEVICE_PATH, 562 HW_PCCARD_DP, 563 (UINT16)sizeof (PCCARD_DEVICE_PATH) 564 ); 565 566 if (Pccard != NULL) { 567 Pccard->FunctionNumber = (UINT8)Strtoi (FunctionNumberStr); 568 } 569 570 return (EFI_DEVICE_PATH_PROTOCOL *)Pccard; 571 } 572 573 /** 574 Converts a text device path node to Hardware memory map device path structure. 575 576 @param TextDeviceNode The input Text device path node. 577 578 @return A pointer to Hardware memory map device path structure. 579 580 **/ 581 static 582 EFI_DEVICE_PATH_PROTOCOL * 583 DevPathFromTextMemoryMapped ( 584 IN CHAR16 *TextDeviceNode 585 ) 586 { 587 CHAR16 *MemoryTypeStr; 588 CHAR16 *StartingAddressStr; 589 CHAR16 *EndingAddressStr; 590 MEMMAP_DEVICE_PATH *MemMap; 591 592 MemoryTypeStr = GetNextParamStr (&TextDeviceNode); 593 StartingAddressStr = GetNextParamStr (&TextDeviceNode); 594 EndingAddressStr = GetNextParamStr (&TextDeviceNode); 595 MemMap = (MEMMAP_DEVICE_PATH *)CreateDeviceNode ( 596 HARDWARE_DEVICE_PATH, 597 HW_MEMMAP_DP, 598 (UINT16)sizeof (MEMMAP_DEVICE_PATH) 599 ); 600 601 if (MemMap != NULL) { 602 MemMap->MemoryType = (UINT32)Strtoi (MemoryTypeStr); 603 Strtoi64 (StartingAddressStr, &MemMap->StartingAddress); 604 Strtoi64 (EndingAddressStr, &MemMap->EndingAddress); 605 } 606 607 return (EFI_DEVICE_PATH_PROTOCOL *)MemMap; 608 } 609 610 /** 611 Converts a text device path node to Vendor device path structure based on the input Type 612 and SubType. 613 614 @param TextDeviceNode The input Text device path node. 615 @param Type The type of device path node. 616 @param SubType The subtype of device path node. 617 618 @return A pointer to the newly-created Vendor device path structure. 619 620 **/ 621 static 622 EFI_DEVICE_PATH_PROTOCOL * 623 ConvertFromTextVendor ( 624 IN CHAR16 *TextDeviceNode, 625 IN UINT8 Type, 626 IN UINT8 SubType 627 ) 628 { 629 CHAR16 *GuidStr; 630 CHAR16 *DataStr; 631 UINTN Length; 632 VENDOR_DEVICE_PATH *Vendor; 633 634 GuidStr = GetNextParamStr (&TextDeviceNode); 635 636 DataStr = GetNextParamStr (&TextDeviceNode); 637 Length = StrLen (DataStr); 638 // 639 // Two hex characters make up 1 buffer byte 640 // 641 Length = (Length + 1) / 2; 642 643 Vendor = (VENDOR_DEVICE_PATH *)CreateDeviceNode ( 644 Type, 645 SubType, 646 (UINT16)(sizeof (VENDOR_DEVICE_PATH) + Length) 647 ); 648 649 if (Vendor != NULL) { 650 StrToGuid (GuidStr, &Vendor->Guid); 651 StrHexToBytes (DataStr, Length * 2, (UINT8 *)(Vendor + 1), Length); 652 } 653 654 return (EFI_DEVICE_PATH_PROTOCOL *)Vendor; 655 } 656 657 /** 658 Converts a text device path node to Vendor Hardware device path structure. 659 660 @param TextDeviceNode The input Text device path node. 661 662 @return A pointer to the newly-created Vendor Hardware device path structure. 663 664 **/ 665 static 666 EFI_DEVICE_PATH_PROTOCOL * 667 DevPathFromTextVenHw ( 668 IN CHAR16 *TextDeviceNode 669 ) 670 { 671 return ConvertFromTextVendor ( 672 TextDeviceNode, 673 HARDWARE_DEVICE_PATH, 674 HW_VENDOR_DP 675 ); 676 } 677 678 /** 679 Converts a text device path node to Hardware Controller device path structure. 680 681 @param TextDeviceNode The input Text device path node. 682 683 @return A pointer to the newly-created Hardware Controller device path structure. 684 685 **/ 686 static 687 EFI_DEVICE_PATH_PROTOCOL * 688 DevPathFromTextCtrl ( 689 IN CHAR16 *TextDeviceNode 690 ) 691 { 692 CHAR16 *ControllerStr; 693 CONTROLLER_DEVICE_PATH *Controller; 694 695 ControllerStr = GetNextParamStr (&TextDeviceNode); 696 Controller = (CONTROLLER_DEVICE_PATH *)CreateDeviceNode ( 697 HARDWARE_DEVICE_PATH, 698 HW_CONTROLLER_DP, 699 (UINT16)sizeof (CONTROLLER_DEVICE_PATH) 700 ); 701 702 if (Controller != NULL) { 703 Controller->ControllerNumber = (UINT32)Strtoi (ControllerStr); 704 } 705 706 return (EFI_DEVICE_PATH_PROTOCOL *)Controller; 707 } 708 709 /** 710 Converts a text device path node to BMC device path structure. 711 712 @param TextDeviceNode The input Text device path node. 713 714 @return A pointer to the newly-created BMC device path structure. 715 716 **/ 717 static 718 EFI_DEVICE_PATH_PROTOCOL * 719 DevPathFromTextBmc ( 720 IN CHAR16 *TextDeviceNode 721 ) 722 { 723 CHAR16 *InterfaceTypeStr; 724 CHAR16 *BaseAddressStr; 725 BMC_DEVICE_PATH *BmcDp; 726 727 InterfaceTypeStr = GetNextParamStr (&TextDeviceNode); 728 BaseAddressStr = GetNextParamStr (&TextDeviceNode); 729 BmcDp = (BMC_DEVICE_PATH *)CreateDeviceNode ( 730 HARDWARE_DEVICE_PATH, 731 HW_BMC_DP, 732 (UINT16)sizeof (BMC_DEVICE_PATH) 733 ); 734 735 if (BmcDp != NULL) { 736 BmcDp->InterfaceType = (UINT8)Strtoi (InterfaceTypeStr); 737 WriteUnaligned64 ( 738 (UINT64 *)(&BmcDp->BaseAddress), 739 StrHexToUint64 (BaseAddressStr) 740 ); 741 } 742 743 return (EFI_DEVICE_PATH_PROTOCOL *)BmcDp; 744 } 745 746 /** 747 Converts a generic ACPI text device path node to ACPI device path structure. 748 749 @param TextDeviceNode The input Text device path node. 750 751 @return A pointer to ACPI device path structure. 752 753 **/ 754 static 755 EFI_DEVICE_PATH_PROTOCOL * 756 DevPathFromTextAcpiPath ( 757 IN CHAR16 *TextDeviceNode 758 ) 759 { 760 return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, TextDeviceNode); 761 } 762 763 /** 764 Converts a string to EisaId. 765 766 @param Text The input string. 767 768 @return UINT32 EISA ID. 769 **/ 770 static 771 UINT32 772 EisaIdFromText ( 773 IN CHAR16 *Text 774 ) 775 { 776 return (((Text[0] - 'A' + 1) & 0x1f) << 10) 777 + (((Text[1] - 'A' + 1) & 0x1f) << 5) 778 + (((Text[2] - 'A' + 1) & 0x1f) << 0) 779 + (UINT32)(StrHexToUintn (&Text[3]) << 16) 780 ; 781 } 782 783 /** 784 Converts a text device path node to ACPI HID device path structure. 785 786 @param TextDeviceNode The input Text device path node. 787 788 @return A pointer to the newly-created ACPI HID device path structure. 789 790 **/ 791 static 792 EFI_DEVICE_PATH_PROTOCOL * 793 DevPathFromTextAcpi ( 794 IN CHAR16 *TextDeviceNode 795 ) 796 { 797 CHAR16 *HIDStr; 798 CHAR16 *UIDStr; 799 ACPI_HID_DEVICE_PATH *Acpi; 800 801 HIDStr = GetNextParamStr (&TextDeviceNode); 802 UIDStr = GetNextParamStr (&TextDeviceNode); 803 Acpi = (ACPI_HID_DEVICE_PATH *)CreateDeviceNode ( 804 ACPI_DEVICE_PATH, 805 ACPI_DP, 806 (UINT16)sizeof (ACPI_HID_DEVICE_PATH) 807 ); 808 809 if (Acpi != NULL) { 810 Acpi->HID = EisaIdFromText (HIDStr); 811 Acpi->UID = (UINT32)Strtoi (UIDStr); 812 } 813 814 return (EFI_DEVICE_PATH_PROTOCOL *)Acpi; 815 } 816 817 /** 818 Converts a text device path node to ACPI HID device path structure. 819 820 @param TextDeviceNode The input Text device path node. 821 @param PnPId The input plug and play identification. 822 823 @return A pointer to the newly-created ACPI HID device path structure. 824 825 **/ 826 static 827 EFI_DEVICE_PATH_PROTOCOL * 828 ConvertFromTextAcpi ( 829 IN CHAR16 *TextDeviceNode, 830 IN UINT32 PnPId 831 ) 832 { 833 CHAR16 *UIDStr; 834 ACPI_HID_DEVICE_PATH *Acpi; 835 836 UIDStr = GetNextParamStr (&TextDeviceNode); 837 Acpi = (ACPI_HID_DEVICE_PATH *)CreateDeviceNode ( 838 ACPI_DEVICE_PATH, 839 ACPI_DP, 840 (UINT16)sizeof (ACPI_HID_DEVICE_PATH) 841 ); 842 843 if (Acpi != NULL) { 844 Acpi->HID = EFI_PNP_ID (PnPId); 845 Acpi->UID = (UINT32)Strtoi (UIDStr); 846 } 847 848 return (EFI_DEVICE_PATH_PROTOCOL *)Acpi; 849 } 850 851 /** 852 Converts a text device path node to PCI root device path structure. 853 854 @param TextDeviceNode The input Text device path node. 855 856 @return A pointer to the newly-created PCI root device path structure. 857 858 **/ 859 static 860 EFI_DEVICE_PATH_PROTOCOL * 861 DevPathFromTextPciRoot ( 862 IN CHAR16 *TextDeviceNode 863 ) 864 { 865 return ConvertFromTextAcpi (TextDeviceNode, 0x0a03); 866 } 867 868 /** 869 Converts a text device path node to PCIE root device path structure. 870 871 @param TextDeviceNode The input Text device path node. 872 873 @return A pointer to the newly-created PCIE root device path structure. 874 875 **/ 876 static 877 EFI_DEVICE_PATH_PROTOCOL * 878 DevPathFromTextPcieRoot ( 879 IN CHAR16 *TextDeviceNode 880 ) 881 { 882 return ConvertFromTextAcpi (TextDeviceNode, 0x0a08); 883 } 884 885 /** 886 Converts a text device path node to Floppy device path structure. 887 888 @param TextDeviceNode The input Text device path node. 889 890 @return A pointer to the newly-created Floppy device path structure. 891 892 **/ 893 static 894 EFI_DEVICE_PATH_PROTOCOL * 895 DevPathFromTextFloppy ( 896 IN CHAR16 *TextDeviceNode 897 ) 898 { 899 return ConvertFromTextAcpi (TextDeviceNode, 0x0604); 900 } 901 902 /** 903 Converts a text device path node to Keyboard device path structure. 904 905 @param TextDeviceNode The input Text device path node. 906 907 @return A pointer to the newly-created Keyboard device path structure. 908 909 **/ 910 static 911 EFI_DEVICE_PATH_PROTOCOL * 912 DevPathFromTextKeyboard ( 913 IN CHAR16 *TextDeviceNode 914 ) 915 { 916 return ConvertFromTextAcpi (TextDeviceNode, 0x0301); 917 } 918 919 /** 920 Converts a text device path node to Serial device path structure. 921 922 @param TextDeviceNode The input Text device path node. 923 924 @return A pointer to the newly-created Serial device path structure. 925 926 **/ 927 static 928 EFI_DEVICE_PATH_PROTOCOL * 929 DevPathFromTextSerial ( 930 IN CHAR16 *TextDeviceNode 931 ) 932 { 933 return ConvertFromTextAcpi (TextDeviceNode, 0x0501); 934 } 935 936 /** 937 Converts a text device path node to Parallel Port device path structure. 938 939 @param TextDeviceNode The input Text device path node. 940 941 @return A pointer to the newly-created Parallel Port device path structure. 942 943 **/ 944 static 945 EFI_DEVICE_PATH_PROTOCOL * 946 DevPathFromTextParallelPort ( 947 IN CHAR16 *TextDeviceNode 948 ) 949 { 950 return ConvertFromTextAcpi (TextDeviceNode, 0x0401); 951 } 952 953 /** 954 Converts a text device path node to ACPI extension device path structure. 955 956 @param TextDeviceNode The input Text device path node. 957 958 @return A pointer to the newly-created ACPI extension device path structure. 959 960 **/ 961 static 962 EFI_DEVICE_PATH_PROTOCOL * 963 DevPathFromTextAcpiEx ( 964 IN CHAR16 *TextDeviceNode 965 ) 966 { 967 CHAR16 *HIDStr; 968 CHAR16 *CIDStr; 969 CHAR16 *UIDStr; 970 CHAR16 *HIDSTRStr; 971 CHAR16 *CIDSTRStr; 972 CHAR16 *UIDSTRStr; 973 CHAR8 *AsciiStr; 974 UINT16 Length; 975 ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; 976 977 HIDStr = GetNextParamStr (&TextDeviceNode); 978 CIDStr = GetNextParamStr (&TextDeviceNode); 979 UIDStr = GetNextParamStr (&TextDeviceNode); 980 HIDSTRStr = GetNextParamStr (&TextDeviceNode); 981 CIDSTRStr = GetNextParamStr (&TextDeviceNode); 982 UIDSTRStr = GetNextParamStr (&TextDeviceNode); 983 984 Length = (UINT16)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1); 985 Length = (UINT16)(Length + StrLen (UIDSTRStr) + 1); 986 Length = (UINT16)(Length + StrLen (CIDSTRStr) + 1); 987 AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *)CreateDeviceNode ( 988 ACPI_DEVICE_PATH, 989 ACPI_EXTENDED_DP, 990 Length 991 ); 992 993 if (AcpiEx != NULL) { 994 AcpiEx->HID = EisaIdFromText (HIDStr); 995 AcpiEx->CID = EisaIdFromText (CIDStr); 996 AcpiEx->UID = (UINT32)Strtoi (UIDStr); 997 998 AsciiStr = (CHAR8 *)((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)); 999 StrToAscii (HIDSTRStr, &AsciiStr); 1000 StrToAscii (UIDSTRStr, &AsciiStr); 1001 StrToAscii (CIDSTRStr, &AsciiStr); 1002 } 1003 1004 return (EFI_DEVICE_PATH_PROTOCOL *)AcpiEx; 1005 } 1006 1007 /** 1008 Converts a text device path node to ACPI extension device path structure. 1009 1010 @param TextDeviceNode The input Text device path node. 1011 1012 @return A pointer to the newly-created ACPI extension device path structure. 1013 1014 **/ 1015 static 1016 EFI_DEVICE_PATH_PROTOCOL * 1017 DevPathFromTextAcpiExp ( 1018 IN CHAR16 *TextDeviceNode 1019 ) 1020 { 1021 CHAR16 *HIDStr; 1022 CHAR16 *CIDStr; 1023 CHAR16 *UIDSTRStr; 1024 CHAR8 *AsciiStr; 1025 UINT16 Length; 1026 ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; 1027 1028 HIDStr = GetNextParamStr (&TextDeviceNode); 1029 CIDStr = GetNextParamStr (&TextDeviceNode); 1030 UIDSTRStr = GetNextParamStr (&TextDeviceNode); 1031 Length = (UINT16)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3); 1032 AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *)CreateDeviceNode ( 1033 ACPI_DEVICE_PATH, 1034 ACPI_EXTENDED_DP, 1035 Length 1036 ); 1037 1038 if (AcpiEx == NULL) { 1039 return (EFI_DEVICE_PATH_PROTOCOL *)AcpiEx; 1040 } 1041 1042 AcpiEx->HID = EisaIdFromText (HIDStr); 1043 // 1044 // According to UEFI spec, the CID parameter is optional and has a default value of 0. 1045 // So when the CID parameter is not specified or specified as 0 in the text device node. 1046 // Set the CID to 0 in the ACPI extension device path structure. 1047 // 1048 if ((*CIDStr == '\0') || (*CIDStr == '0')) { 1049 AcpiEx->CID = 0; 1050 } else { 1051 AcpiEx->CID = EisaIdFromText (CIDStr); 1052 } 1053 1054 AcpiEx->UID = 0; 1055 1056 AsciiStr = (CHAR8 *)((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)); 1057 // 1058 // HID string is NULL 1059 // 1060 *AsciiStr = '\0'; 1061 // 1062 // Convert UID string 1063 // 1064 AsciiStr++; 1065 StrToAscii (UIDSTRStr, &AsciiStr); 1066 // 1067 // CID string is NULL 1068 // 1069 *AsciiStr = '\0'; 1070 1071 return (EFI_DEVICE_PATH_PROTOCOL *)AcpiEx; 1072 } 1073 1074 /** 1075 Converts a text device path node to ACPI _ADR device path structure. 1076 1077 @param TextDeviceNode The input Text device path node. 1078 1079 @return A pointer to the newly-created ACPI _ADR device path structure. 1080 1081 **/ 1082 static 1083 EFI_DEVICE_PATH_PROTOCOL * 1084 DevPathFromTextAcpiAdr ( 1085 IN CHAR16 *TextDeviceNode 1086 ) 1087 { 1088 CHAR16 *DisplayDeviceStr; 1089 ACPI_ADR_DEVICE_PATH *AcpiAdr; 1090 UINTN Index; 1091 UINTN Length; 1092 1093 AcpiAdr = (ACPI_ADR_DEVICE_PATH *)CreateDeviceNode ( 1094 ACPI_DEVICE_PATH, 1095 ACPI_ADR_DP, 1096 (UINT16)sizeof (ACPI_ADR_DEVICE_PATH) 1097 ); 1098 if (AcpiAdr == NULL) { 1099 ASSERT (AcpiAdr != NULL); 1100 return (EFI_DEVICE_PATH_PROTOCOL *)AcpiAdr; 1101 } 1102 1103 for (Index = 0; ; Index++) { 1104 DisplayDeviceStr = GetNextParamStr (&TextDeviceNode); 1105 if (IS_NULL (*DisplayDeviceStr)) { 1106 break; 1107 } 1108 1109 if (Index > 0) { 1110 Length = DevicePathNodeLength (AcpiAdr); 1111 AcpiAdr = ReallocatePool ( 1112 Length, 1113 Length + sizeof (UINT32), 1114 AcpiAdr 1115 ); 1116 1117 if (AcpiAdr == NULL) { 1118 ASSERT (AcpiAdr != NULL); 1119 return (EFI_DEVICE_PATH_PROTOCOL *)AcpiAdr; 1120 } 1121 1122 SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32)); 1123 } 1124 1125 (&AcpiAdr->ADR)[Index] = (UINT32)Strtoi (DisplayDeviceStr); 1126 } 1127 1128 return (EFI_DEVICE_PATH_PROTOCOL *)AcpiAdr; 1129 } 1130 1131 /** 1132 Converts a generic messaging text device path node to messaging device path structure. 1133 1134 @param TextDeviceNode The input Text device path node. 1135 1136 @return A pointer to messaging device path structure. 1137 1138 **/ 1139 static 1140 EFI_DEVICE_PATH_PROTOCOL * 1141 DevPathFromTextMsg ( 1142 IN CHAR16 *TextDeviceNode 1143 ) 1144 { 1145 return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, TextDeviceNode); 1146 } 1147 1148 /** 1149 Converts a text device path node to Parallel Port device path structure. 1150 1151 @param TextDeviceNode The input Text device path node. 1152 1153 @return A pointer to the newly-created Parallel Port device path structure. 1154 1155 **/ 1156 static 1157 EFI_DEVICE_PATH_PROTOCOL * 1158 DevPathFromTextAta ( 1159 IN CHAR16 *TextDeviceNode 1160 ) 1161 { 1162 CHAR16 *PrimarySecondaryStr; 1163 CHAR16 *SlaveMasterStr; 1164 CHAR16 *LunStr; 1165 ATAPI_DEVICE_PATH *Atapi; 1166 1167 Atapi = (ATAPI_DEVICE_PATH *)CreateDeviceNode ( 1168 MESSAGING_DEVICE_PATH, 1169 MSG_ATAPI_DP, 1170 (UINT16)sizeof (ATAPI_DEVICE_PATH) 1171 ); 1172 1173 if (Atapi == NULL) { 1174 return (EFI_DEVICE_PATH_PROTOCOL *)Atapi; 1175 } 1176 1177 PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode); 1178 SlaveMasterStr = GetNextParamStr (&TextDeviceNode); 1179 LunStr = GetNextParamStr (&TextDeviceNode); 1180 1181 if (StrCmp (PrimarySecondaryStr, "Primary") == 0) { 1182 Atapi->PrimarySecondary = 0; 1183 } else if (StrCmp (PrimarySecondaryStr, "Secondary") == 0) { 1184 Atapi->PrimarySecondary = 1; 1185 } else { 1186 Atapi->PrimarySecondary = (UINT8)Strtoi (PrimarySecondaryStr); 1187 } 1188 1189 if (StrCmp (SlaveMasterStr, "Master") == 0) { 1190 Atapi->SlaveMaster = 0; 1191 } else if (StrCmp (SlaveMasterStr, "Slave") == 0) { 1192 Atapi->SlaveMaster = 1; 1193 } else { 1194 Atapi->SlaveMaster = (UINT8)Strtoi (SlaveMasterStr); 1195 } 1196 1197 Atapi->Lun = (UINT16)Strtoi (LunStr); 1198 1199 return (EFI_DEVICE_PATH_PROTOCOL *)Atapi; 1200 } 1201 1202 /** 1203 Converts a text device path node to SCSI device path structure. 1204 1205 @param TextDeviceNode The input Text device path node. 1206 1207 @return A pointer to the newly-created SCSI device path structure. 1208 1209 **/ 1210 static 1211 EFI_DEVICE_PATH_PROTOCOL * 1212 DevPathFromTextScsi ( 1213 IN CHAR16 *TextDeviceNode 1214 ) 1215 { 1216 CHAR16 *PunStr; 1217 CHAR16 *LunStr; 1218 SCSI_DEVICE_PATH *Scsi; 1219 1220 PunStr = GetNextParamStr (&TextDeviceNode); 1221 LunStr = GetNextParamStr (&TextDeviceNode); 1222 Scsi = (SCSI_DEVICE_PATH *)CreateDeviceNode ( 1223 MESSAGING_DEVICE_PATH, 1224 MSG_SCSI_DP, 1225 (UINT16)sizeof (SCSI_DEVICE_PATH) 1226 ); 1227 1228 if (Scsi != NULL) { 1229 Scsi->Pun = (UINT16)Strtoi (PunStr); 1230 Scsi->Lun = (UINT16)Strtoi (LunStr); 1231 } 1232 1233 return (EFI_DEVICE_PATH_PROTOCOL *)Scsi; 1234 } 1235 1236 /** 1237 Converts a text device path node to Fibre device path structure. 1238 1239 @param TextDeviceNode The input Text device path node. 1240 1241 @return A pointer to the newly-created Fibre device path structure. 1242 1243 **/ 1244 static 1245 EFI_DEVICE_PATH_PROTOCOL * 1246 DevPathFromTextFibre ( 1247 IN CHAR16 *TextDeviceNode 1248 ) 1249 { 1250 CHAR16 *WWNStr; 1251 CHAR16 *LunStr; 1252 FIBRECHANNEL_DEVICE_PATH *Fibre; 1253 1254 WWNStr = GetNextParamStr (&TextDeviceNode); 1255 LunStr = GetNextParamStr (&TextDeviceNode); 1256 Fibre = (FIBRECHANNEL_DEVICE_PATH *)CreateDeviceNode ( 1257 MESSAGING_DEVICE_PATH, 1258 MSG_FIBRECHANNEL_DP, 1259 (UINT16)sizeof (FIBRECHANNEL_DEVICE_PATH) 1260 ); 1261 1262 if (Fibre != NULL) { 1263 Fibre->Reserved = 0; 1264 Strtoi64 (WWNStr, &Fibre->WWN); 1265 Strtoi64 (LunStr, &Fibre->Lun); 1266 } 1267 1268 return (EFI_DEVICE_PATH_PROTOCOL *)Fibre; 1269 } 1270 1271 /** 1272 Converts a text device path node to FibreEx device path structure. 1273 1274 @param TextDeviceNode The input Text device path node. 1275 1276 @return A pointer to the newly-created FibreEx device path structure. 1277 1278 **/ 1279 static 1280 EFI_DEVICE_PATH_PROTOCOL * 1281 DevPathFromTextFibreEx ( 1282 IN CHAR16 *TextDeviceNode 1283 ) 1284 { 1285 CHAR16 *WWNStr; 1286 CHAR16 *LunStr; 1287 FIBRECHANNELEX_DEVICE_PATH *FibreEx; 1288 1289 WWNStr = GetNextParamStr (&TextDeviceNode); 1290 LunStr = GetNextParamStr (&TextDeviceNode); 1291 FibreEx = (FIBRECHANNELEX_DEVICE_PATH *)CreateDeviceNode ( 1292 MESSAGING_DEVICE_PATH, 1293 MSG_FIBRECHANNELEX_DP, 1294 (UINT16)sizeof (FIBRECHANNELEX_DEVICE_PATH) 1295 ); 1296 1297 if (FibreEx != NULL) { 1298 FibreEx->Reserved = 0; 1299 Strtoi64 (WWNStr, (UINT64 *)(&FibreEx->WWN)); 1300 Strtoi64 (LunStr, (UINT64 *)(&FibreEx->Lun)); 1301 1302 *(UINT64 *)(&FibreEx->WWN) = SwapBytes64 (*(UINT64 *)(&FibreEx->WWN)); 1303 *(UINT64 *)(&FibreEx->Lun) = SwapBytes64 (*(UINT64 *)(&FibreEx->Lun)); 1304 } 1305 1306 return (EFI_DEVICE_PATH_PROTOCOL *)FibreEx; 1307 } 1308 1309 /** 1310 Converts a text device path node to 1394 device path structure. 1311 1312 @param TextDeviceNode The input Text device path node. 1313 1314 @return A pointer to the newly-created 1394 device path structure. 1315 1316 **/ 1317 static 1318 EFI_DEVICE_PATH_PROTOCOL * 1319 DevPathFromText1394 ( 1320 IN CHAR16 *TextDeviceNode 1321 ) 1322 { 1323 CHAR16 *GuidStr; 1324 F1394_DEVICE_PATH *F1394DevPath; 1325 1326 GuidStr = GetNextParamStr (&TextDeviceNode); 1327 F1394DevPath = (F1394_DEVICE_PATH *)CreateDeviceNode ( 1328 MESSAGING_DEVICE_PATH, 1329 MSG_1394_DP, 1330 (UINT16)sizeof (F1394_DEVICE_PATH) 1331 ); 1332 1333 if (F1394DevPath != NULL) { 1334 F1394DevPath->Reserved = 0; 1335 F1394DevPath->Guid = StrHexToUint64 (GuidStr); 1336 } 1337 1338 return (EFI_DEVICE_PATH_PROTOCOL *)F1394DevPath; 1339 } 1340 1341 /** 1342 Converts a text device path node to USB device path structure. 1343 1344 @param TextDeviceNode The input Text device path node. 1345 1346 @return A pointer to the newly-created USB device path structure. 1347 1348 **/ 1349 static 1350 EFI_DEVICE_PATH_PROTOCOL * 1351 DevPathFromTextUsb ( 1352 IN CHAR16 *TextDeviceNode 1353 ) 1354 { 1355 CHAR16 *PortStr; 1356 CHAR16 *InterfaceStr; 1357 USB_DEVICE_PATH *Usb; 1358 1359 PortStr = GetNextParamStr (&TextDeviceNode); 1360 InterfaceStr = GetNextParamStr (&TextDeviceNode); 1361 Usb = (USB_DEVICE_PATH *)CreateDeviceNode ( 1362 MESSAGING_DEVICE_PATH, 1363 MSG_USB_DP, 1364 (UINT16)sizeof (USB_DEVICE_PATH) 1365 ); 1366 1367 if (Usb != NULL) { 1368 Usb->ParentPortNumber = (UINT8)Strtoi (PortStr); 1369 Usb->InterfaceNumber = (UINT8)Strtoi (InterfaceStr); 1370 } 1371 1372 return (EFI_DEVICE_PATH_PROTOCOL *)Usb; 1373 } 1374 1375 /** 1376 Converts a text device path node to I20 device path structure. 1377 1378 @param TextDeviceNode The input Text device path node. 1379 1380 @return A pointer to the newly-created I20 device path structure. 1381 1382 **/ 1383 static 1384 EFI_DEVICE_PATH_PROTOCOL * 1385 DevPathFromTextI2O ( 1386 IN CHAR16 *TextDeviceNode 1387 ) 1388 { 1389 CHAR16 *TIDStr; 1390 I2O_DEVICE_PATH *I2ODevPath; 1391 1392 TIDStr = GetNextParamStr (&TextDeviceNode); 1393 I2ODevPath = (I2O_DEVICE_PATH *)CreateDeviceNode ( 1394 MESSAGING_DEVICE_PATH, 1395 MSG_I2O_DP, 1396 (UINT16)sizeof (I2O_DEVICE_PATH) 1397 ); 1398 1399 if (I2ODevPath != NULL) { 1400 I2ODevPath->Tid = (UINT32)Strtoi (TIDStr); 1401 } 1402 1403 return (EFI_DEVICE_PATH_PROTOCOL *)I2ODevPath; 1404 } 1405 1406 /** 1407 Converts a text device path node to Infini Band device path structure. 1408 1409 @param TextDeviceNode The input Text device path node. 1410 1411 @return A pointer to the newly-created Infini Band device path structure. 1412 1413 **/ 1414 static 1415 EFI_DEVICE_PATH_PROTOCOL * 1416 DevPathFromTextInfiniband ( 1417 IN CHAR16 *TextDeviceNode 1418 ) 1419 { 1420 CHAR16 *FlagsStr; 1421 CHAR16 *GuidStr; 1422 CHAR16 *SidStr; 1423 CHAR16 *TidStr; 1424 CHAR16 *DidStr; 1425 INFINIBAND_DEVICE_PATH *InfiniBand; 1426 1427 FlagsStr = GetNextParamStr (&TextDeviceNode); 1428 GuidStr = GetNextParamStr (&TextDeviceNode); 1429 SidStr = GetNextParamStr (&TextDeviceNode); 1430 TidStr = GetNextParamStr (&TextDeviceNode); 1431 DidStr = GetNextParamStr (&TextDeviceNode); 1432 InfiniBand = (INFINIBAND_DEVICE_PATH *)CreateDeviceNode ( 1433 MESSAGING_DEVICE_PATH, 1434 MSG_INFINIBAND_DP, 1435 (UINT16)sizeof (INFINIBAND_DEVICE_PATH) 1436 ); 1437 1438 if (InfiniBand != NULL) { 1439 InfiniBand->ResourceFlags = (UINT32)Strtoi (FlagsStr); 1440 StrToGuid (GuidStr, (EFI_GUID *)InfiniBand->PortGid); 1441 Strtoi64 (SidStr, &InfiniBand->ServiceId); 1442 Strtoi64 (TidStr, &InfiniBand->TargetPortId); 1443 Strtoi64 (DidStr, &InfiniBand->DeviceId); 1444 } 1445 1446 return (EFI_DEVICE_PATH_PROTOCOL *)InfiniBand; 1447 } 1448 1449 /** 1450 Converts a text device path node to Vendor-Defined Messaging device path structure. 1451 1452 @param TextDeviceNode The input Text device path node. 1453 1454 @return A pointer to the newly-created Vendor-Defined Messaging device path structure. 1455 1456 **/ 1457 static 1458 EFI_DEVICE_PATH_PROTOCOL * 1459 DevPathFromTextVenMsg ( 1460 IN CHAR16 *TextDeviceNode 1461 ) 1462 { 1463 return ConvertFromTextVendor ( 1464 TextDeviceNode, 1465 MESSAGING_DEVICE_PATH, 1466 MSG_VENDOR_DP 1467 ); 1468 } 1469 1470 /** 1471 Converts a text device path node to Vendor defined PC-ANSI device path structure. 1472 1473 @param TextDeviceNode The input Text device path node. 1474 1475 @return A pointer to the newly-created Vendor defined PC-ANSI device path structure. 1476 1477 **/ 1478 static 1479 EFI_DEVICE_PATH_PROTOCOL * 1480 DevPathFromTextVenPcAnsi ( 1481 IN CHAR16 *TextDeviceNode 1482 ) 1483 { 1484 VENDOR_DEVICE_PATH *Vendor; 1485 1486 Vendor = (VENDOR_DEVICE_PATH *)CreateDeviceNode ( 1487 MESSAGING_DEVICE_PATH, 1488 MSG_VENDOR_DP, 1489 (UINT16)sizeof (VENDOR_DEVICE_PATH) 1490 ); 1491 1492 if (Vendor != NULL) { 1493 CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid); 1494 } 1495 1496 return (EFI_DEVICE_PATH_PROTOCOL *)Vendor; 1497 } 1498 1499 /** 1500 Converts a text device path node to Vendor defined VT100 device path structure. 1501 1502 @param TextDeviceNode The input Text device path node. 1503 1504 @return A pointer to the newly-created Vendor defined VT100 device path structure. 1505 1506 **/ 1507 static 1508 EFI_DEVICE_PATH_PROTOCOL * 1509 DevPathFromTextVenVt100 ( 1510 IN CHAR16 *TextDeviceNode 1511 ) 1512 { 1513 VENDOR_DEVICE_PATH *Vendor; 1514 1515 Vendor = (VENDOR_DEVICE_PATH *)CreateDeviceNode ( 1516 MESSAGING_DEVICE_PATH, 1517 MSG_VENDOR_DP, 1518 (UINT16)sizeof (VENDOR_DEVICE_PATH) 1519 ); 1520 1521 if (Vendor != NULL) { 1522 CopyGuid (&Vendor->Guid, &gEfiVT100Guid); 1523 } 1524 1525 return (EFI_DEVICE_PATH_PROTOCOL *)Vendor; 1526 } 1527 1528 /** 1529 Converts a text device path node to Vendor defined VT100 Plus device path structure. 1530 1531 @param TextDeviceNode The input Text device path node. 1532 1533 @return A pointer to the newly-created Vendor defined VT100 Plus device path structure. 1534 1535 **/ 1536 static 1537 EFI_DEVICE_PATH_PROTOCOL * 1538 DevPathFromTextVenVt100Plus ( 1539 IN CHAR16 *TextDeviceNode 1540 ) 1541 { 1542 VENDOR_DEVICE_PATH *Vendor; 1543 1544 Vendor = (VENDOR_DEVICE_PATH *)CreateDeviceNode ( 1545 MESSAGING_DEVICE_PATH, 1546 MSG_VENDOR_DP, 1547 (UINT16)sizeof (VENDOR_DEVICE_PATH) 1548 ); 1549 1550 if (Vendor != NULL) { 1551 CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid); 1552 } 1553 1554 return (EFI_DEVICE_PATH_PROTOCOL *)Vendor; 1555 } 1556 1557 /** 1558 Converts a text device path node to Vendor defined UTF8 device path structure. 1559 1560 @param TextDeviceNode The input Text device path node. 1561 1562 @return A pointer to the newly-created Vendor defined UTF8 device path structure. 1563 1564 **/ 1565 static 1566 EFI_DEVICE_PATH_PROTOCOL * 1567 DevPathFromTextVenUtf8 ( 1568 IN CHAR16 *TextDeviceNode 1569 ) 1570 { 1571 VENDOR_DEVICE_PATH *Vendor; 1572 1573 Vendor = (VENDOR_DEVICE_PATH *)CreateDeviceNode ( 1574 MESSAGING_DEVICE_PATH, 1575 MSG_VENDOR_DP, 1576 (UINT16)sizeof (VENDOR_DEVICE_PATH) 1577 ); 1578 1579 if (Vendor != NULL) { 1580 CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid); 1581 } 1582 1583 return (EFI_DEVICE_PATH_PROTOCOL *)Vendor; 1584 } 1585 1586 /** 1587 Converts a text device path node to UART Flow Control device path structure. 1588 1589 @param TextDeviceNode The input Text device path node. 1590 1591 @return A pointer to the newly-created UART Flow Control device path structure. 1592 1593 **/ 1594 static 1595 EFI_DEVICE_PATH_PROTOCOL * 1596 DevPathFromTextUartFlowCtrl ( 1597 IN CHAR16 *TextDeviceNode 1598 ) 1599 { 1600 CHAR16 *ValueStr; 1601 UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl; 1602 1603 ValueStr = GetNextParamStr (&TextDeviceNode); 1604 UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *)CreateDeviceNode ( 1605 MESSAGING_DEVICE_PATH, 1606 MSG_VENDOR_DP, 1607 (UINT16)sizeof (UART_FLOW_CONTROL_DEVICE_PATH) 1608 ); 1609 1610 if (UartFlowControl != NULL) { 1611 CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid); 1612 if (StrCmp (ValueStr, "XonXoff") == 0) { 1613 UartFlowControl->FlowControlMap = 2; 1614 } else if (StrCmp (ValueStr, "Hardware") == 0) { 1615 UartFlowControl->FlowControlMap = 1; 1616 } else { 1617 UartFlowControl->FlowControlMap = 0; 1618 } 1619 } 1620 1621 return (EFI_DEVICE_PATH_PROTOCOL *)UartFlowControl; 1622 } 1623 1624 /** 1625 Converts a text device path node to Serial Attached SCSI device path structure. 1626 1627 @param TextDeviceNode The input Text device path node. 1628 1629 @return A pointer to the newly-created Serial Attached SCSI device path structure. 1630 1631 **/ 1632 static 1633 EFI_DEVICE_PATH_PROTOCOL * 1634 DevPathFromTextSAS ( 1635 IN CHAR16 *TextDeviceNode 1636 ) 1637 { 1638 CHAR16 *AddressStr; 1639 CHAR16 *LunStr; 1640 CHAR16 *RTPStr; 1641 CHAR16 *SASSATAStr; 1642 CHAR16 *LocationStr; 1643 CHAR16 *ConnectStr; 1644 CHAR16 *DriveBayStr; 1645 CHAR16 *ReservedStr; 1646 UINT16 Info; 1647 UINT16 Uint16; 1648 SAS_DEVICE_PATH *Sas; 1649 1650 AddressStr = GetNextParamStr (&TextDeviceNode); 1651 LunStr = GetNextParamStr (&TextDeviceNode); 1652 RTPStr = GetNextParamStr (&TextDeviceNode); 1653 SASSATAStr = GetNextParamStr (&TextDeviceNode); 1654 LocationStr = GetNextParamStr (&TextDeviceNode); 1655 ConnectStr = GetNextParamStr (&TextDeviceNode); 1656 DriveBayStr = GetNextParamStr (&TextDeviceNode); 1657 ReservedStr = GetNextParamStr (&TextDeviceNode); 1658 Sas = (SAS_DEVICE_PATH *)CreateDeviceNode ( 1659 MESSAGING_DEVICE_PATH, 1660 MSG_VENDOR_DP, 1661 (UINT16)sizeof (SAS_DEVICE_PATH) 1662 ); 1663 1664 if (Sas == NULL) { 1665 return (EFI_DEVICE_PATH_PROTOCOL *)Sas; 1666 } 1667 1668 CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid); 1669 Strtoi64 (AddressStr, &Sas->SasAddress); 1670 Strtoi64 (LunStr, &Sas->Lun); 1671 Sas->RelativeTargetPort = (UINT16)Strtoi (RTPStr); 1672 1673 if (StrCmp (SASSATAStr, "NoTopology") == 0) { 1674 Info = 0x0; 1675 } else if ((StrCmp (SASSATAStr, "SATA") == 0) || (StrCmp (SASSATAStr, "SAS") == 0)) { 1676 Uint16 = (UINT16)Strtoi (DriveBayStr); 1677 if (Uint16 == 0) { 1678 Info = 0x1; 1679 } else { 1680 Info = (UINT16)(0x2 | ((Uint16 - 1) << 8)); 1681 } 1682 1683 if (StrCmp (SASSATAStr, "SATA") == 0) { 1684 Info |= BIT4; 1685 } 1686 1687 // 1688 // Location is an integer between 0 and 1 or else 1689 // the keyword Internal (0) or External (1). 1690 // 1691 if (StrCmp (LocationStr, "External") == 0) { 1692 Uint16 = 1; 1693 } else if (StrCmp (LocationStr, "Internal") == 0) { 1694 Uint16 = 0; 1695 } else { 1696 Uint16 = ((UINT16)Strtoi (LocationStr) & BIT0); 1697 } 1698 1699 Info |= (Uint16 << 5); 1700 1701 // 1702 // Connect is an integer between 0 and 3 or else 1703 // the keyword Direct (0) or Expanded (1). 1704 // 1705 if (StrCmp (ConnectStr, "Expanded") == 0) { 1706 Uint16 = 1; 1707 } else if (StrCmp (ConnectStr, "Direct") == 0) { 1708 Uint16 = 0; 1709 } else { 1710 Uint16 = ((UINT16)Strtoi (ConnectStr) & (BIT0 | BIT1)); 1711 } 1712 1713 Info |= (Uint16 << 6); 1714 } else { 1715 Info = (UINT16)Strtoi (SASSATAStr); 1716 } 1717 1718 Sas->DeviceTopology = Info; 1719 Sas->Reserved = (UINT32)Strtoi (ReservedStr); 1720 1721 return (EFI_DEVICE_PATH_PROTOCOL *)Sas; 1722 } 1723 1724 /** 1725 Converts a text device path node to Serial Attached SCSI Ex device path structure. 1726 1727 @param TextDeviceNode The input Text device path node. 1728 1729 @return A pointer to the newly-created Serial Attached SCSI Ex device path structure. 1730 1731 **/ 1732 static 1733 EFI_DEVICE_PATH_PROTOCOL * 1734 DevPathFromTextSasEx ( 1735 IN CHAR16 *TextDeviceNode 1736 ) 1737 { 1738 CHAR16 *AddressStr; 1739 CHAR16 *LunStr; 1740 CHAR16 *RTPStr; 1741 CHAR16 *SASSATAStr; 1742 CHAR16 *LocationStr; 1743 CHAR16 *ConnectStr; 1744 CHAR16 *DriveBayStr; 1745 UINT16 Info; 1746 UINT16 Uint16; 1747 UINT64 SasAddress; 1748 UINT64 Lun; 1749 SASEX_DEVICE_PATH *SasEx; 1750 1751 AddressStr = GetNextParamStr (&TextDeviceNode); 1752 LunStr = GetNextParamStr (&TextDeviceNode); 1753 RTPStr = GetNextParamStr (&TextDeviceNode); 1754 SASSATAStr = GetNextParamStr (&TextDeviceNode); 1755 LocationStr = GetNextParamStr (&TextDeviceNode); 1756 ConnectStr = GetNextParamStr (&TextDeviceNode); 1757 DriveBayStr = GetNextParamStr (&TextDeviceNode); 1758 SasEx = (SASEX_DEVICE_PATH *)CreateDeviceNode ( 1759 MESSAGING_DEVICE_PATH, 1760 MSG_SASEX_DP, 1761 (UINT16)sizeof (SASEX_DEVICE_PATH) 1762 ); 1763 1764 if (SasEx == NULL) { 1765 return (EFI_DEVICE_PATH_PROTOCOL *)SasEx; 1766 } 1767 1768 Strtoi64 (AddressStr, &SasAddress); 1769 Strtoi64 (LunStr, &Lun); 1770 WriteUnaligned64 ((UINT64 *)&SasEx->SasAddress, SwapBytes64 (SasAddress)); 1771 WriteUnaligned64 ((UINT64 *)&SasEx->Lun, SwapBytes64 (Lun)); 1772 SasEx->RelativeTargetPort = (UINT16)Strtoi (RTPStr); 1773 1774 if (StrCmp (SASSATAStr, "NoTopology") == 0) { 1775 Info = 0x0; 1776 } else if ((StrCmp (SASSATAStr, "SATA") == 0) || (StrCmp (SASSATAStr, "SAS") == 0)) { 1777 Uint16 = (UINT16)Strtoi (DriveBayStr); 1778 if (Uint16 == 0) { 1779 Info = 0x1; 1780 } else { 1781 Info = (UINT16)(0x2 | ((Uint16 - 1) << 8)); 1782 } 1783 1784 if (StrCmp (SASSATAStr, "SATA") == 0) { 1785 Info |= BIT4; 1786 } 1787 1788 // 1789 // Location is an integer between 0 and 1 or else 1790 // the keyword Internal (0) or External (1). 1791 // 1792 if (StrCmp (LocationStr, "External") == 0) { 1793 Uint16 = 1; 1794 } else if (StrCmp (LocationStr, "Internal") == 0) { 1795 Uint16 = 0; 1796 } else { 1797 Uint16 = ((UINT16)Strtoi (LocationStr) & BIT0); 1798 } 1799 1800 Info |= (Uint16 << 5); 1801 1802 // 1803 // Connect is an integer between 0 and 3 or else 1804 // the keyword Direct (0) or Expanded (1). 1805 // 1806 if (StrCmp (ConnectStr, "Expanded") == 0) { 1807 Uint16 = 1; 1808 } else if (StrCmp (ConnectStr, "Direct") == 0) { 1809 Uint16 = 0; 1810 } else { 1811 Uint16 = ((UINT16)Strtoi (ConnectStr) & (BIT0 | BIT1)); 1812 } 1813 1814 Info |= (Uint16 << 6); 1815 } else { 1816 Info = (UINT16)Strtoi (SASSATAStr); 1817 } 1818 1819 SasEx->DeviceTopology = Info; 1820 1821 return (EFI_DEVICE_PATH_PROTOCOL *)SasEx; 1822 } 1823 1824 /** 1825 Converts a text device path node to NVM Express Namespace device path structure. 1826 1827 @param TextDeviceNode The input Text device path node. 1828 1829 @return A pointer to the newly-created NVM Express Namespace device path structure. 1830 1831 **/ 1832 static 1833 EFI_DEVICE_PATH_PROTOCOL * 1834 DevPathFromTextNVMe ( 1835 IN CHAR16 *TextDeviceNode 1836 ) 1837 { 1838 CHAR16 *NamespaceIdStr; 1839 CHAR16 *NamespaceUuidStr; 1840 NVME_NAMESPACE_DEVICE_PATH *Nvme; 1841 UINT8 *Uuid; 1842 UINTN Index; 1843 1844 NamespaceIdStr = GetNextParamStr (&TextDeviceNode); 1845 NamespaceUuidStr = GetNextParamStr (&TextDeviceNode); 1846 Nvme = (NVME_NAMESPACE_DEVICE_PATH *)CreateDeviceNode ( 1847 MESSAGING_DEVICE_PATH, 1848 MSG_NVME_NAMESPACE_DP, 1849 (UINT16)sizeof (NVME_NAMESPACE_DEVICE_PATH) 1850 ); 1851 1852 if (Nvme != NULL) { 1853 Nvme->NamespaceId = (UINT32)Strtoi (NamespaceIdStr); 1854 Uuid = (UINT8 *)&Nvme->NamespaceUuid; 1855 1856 Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8); 1857 while (Index-- != 0) { 1858 Uuid[Index] = (UINT8)StrHexToUintn (SplitStr (&NamespaceUuidStr, '-')); 1859 } 1860 } 1861 1862 return (EFI_DEVICE_PATH_PROTOCOL *)Nvme; 1863 } 1864 1865 /** 1866 Converts a text device path node to UFS device path structure. 1867 1868 @param TextDeviceNode The input Text device path node. 1869 1870 @return A pointer to the newly-created UFS device path structure. 1871 1872 **/ 1873 static 1874 EFI_DEVICE_PATH_PROTOCOL * 1875 DevPathFromTextUfs ( 1876 IN CHAR16 *TextDeviceNode 1877 ) 1878 { 1879 CHAR16 *PunStr; 1880 CHAR16 *LunStr; 1881 UFS_DEVICE_PATH *Ufs; 1882 1883 PunStr = GetNextParamStr (&TextDeviceNode); 1884 LunStr = GetNextParamStr (&TextDeviceNode); 1885 Ufs = (UFS_DEVICE_PATH *)CreateDeviceNode ( 1886 MESSAGING_DEVICE_PATH, 1887 MSG_UFS_DP, 1888 (UINT16)sizeof (UFS_DEVICE_PATH) 1889 ); 1890 1891 if (Ufs != NULL) { 1892 Ufs->Pun = (UINT8)Strtoi (PunStr); 1893 Ufs->Lun = (UINT8)Strtoi (LunStr); 1894 } 1895 1896 return (EFI_DEVICE_PATH_PROTOCOL *)Ufs; 1897 } 1898 1899 /** 1900 Converts a text device path node to SD (Secure Digital) device path structure. 1901 1902 @param TextDeviceNode The input Text device path node. 1903 1904 @return A pointer to the newly-created SD device path structure. 1905 1906 **/ 1907 static 1908 EFI_DEVICE_PATH_PROTOCOL * 1909 DevPathFromTextSd ( 1910 IN CHAR16 *TextDeviceNode 1911 ) 1912 { 1913 CHAR16 *SlotNumberStr; 1914 SD_DEVICE_PATH *Sd; 1915 1916 SlotNumberStr = GetNextParamStr (&TextDeviceNode); 1917 Sd = (SD_DEVICE_PATH *)CreateDeviceNode ( 1918 MESSAGING_DEVICE_PATH, 1919 MSG_SD_DP, 1920 (UINT16)sizeof (SD_DEVICE_PATH) 1921 ); 1922 1923 if (Sd != NULL) { 1924 Sd->SlotNumber = (UINT8)Strtoi (SlotNumberStr); 1925 } 1926 1927 return (EFI_DEVICE_PATH_PROTOCOL *)Sd; 1928 } 1929 1930 /** 1931 Converts a text device path node to EMMC (Embedded MMC) device path structure. 1932 1933 @param TextDeviceNode The input Text device path node. 1934 1935 @return A pointer to the newly-created EMMC device path structure. 1936 1937 **/ 1938 static 1939 EFI_DEVICE_PATH_PROTOCOL * 1940 DevPathFromTextEmmc ( 1941 IN CHAR16 *TextDeviceNode 1942 ) 1943 { 1944 CHAR16 *SlotNumberStr; 1945 EMMC_DEVICE_PATH *Emmc; 1946 1947 SlotNumberStr = GetNextParamStr (&TextDeviceNode); 1948 Emmc = (EMMC_DEVICE_PATH *)CreateDeviceNode ( 1949 MESSAGING_DEVICE_PATH, 1950 MSG_EMMC_DP, 1951 (UINT16)sizeof (EMMC_DEVICE_PATH) 1952 ); 1953 1954 if (Emmc != NULL) { 1955 Emmc->SlotNumber = (UINT8)Strtoi (SlotNumberStr); 1956 } 1957 1958 return (EFI_DEVICE_PATH_PROTOCOL *)Emmc; 1959 } 1960 1961 /** 1962 Converts a text device path node to Debug Port device path structure. 1963 1964 @param TextDeviceNode The input Text device path node. 1965 1966 @return A pointer to the newly-created Debug Port device path structure. 1967 1968 **/ 1969 static 1970 EFI_DEVICE_PATH_PROTOCOL * 1971 DevPathFromTextDebugPort ( 1972 IN CHAR16 *TextDeviceNode 1973 ) 1974 { 1975 VENDOR_DEVICE_PATH *Vend; 1976 1977 Vend = (VENDOR_DEVICE_PATH *)CreateDeviceNode ( 1978 MESSAGING_DEVICE_PATH, 1979 MSG_VENDOR_DP, 1980 (UINT16)sizeof (VENDOR_DEVICE_PATH) 1981 ); 1982 1983 if (Vend != NULL) { 1984 CopyGuid (&Vend->Guid, &gEfiDebugPortProtocolGuid); 1985 } 1986 1987 return (EFI_DEVICE_PATH_PROTOCOL *)Vend; 1988 } 1989 1990 /** 1991 Converts a text device path node to MAC device path structure. 1992 1993 @param TextDeviceNode The input Text device path node. 1994 1995 @return A pointer to the newly-created MAC device path structure. 1996 1997 **/ 1998 static 1999 EFI_DEVICE_PATH_PROTOCOL * 2000 DevPathFromTextMAC ( 2001 IN CHAR16 *TextDeviceNode 2002 ) 2003 { 2004 CHAR16 *AddressStr; 2005 CHAR16 *IfTypeStr; 2006 UINTN Length; 2007 MAC_ADDR_DEVICE_PATH *MACDevPath; 2008 2009 AddressStr = GetNextParamStr (&TextDeviceNode); 2010 IfTypeStr = GetNextParamStr (&TextDeviceNode); 2011 MACDevPath = (MAC_ADDR_DEVICE_PATH *)CreateDeviceNode ( 2012 MESSAGING_DEVICE_PATH, 2013 MSG_MAC_ADDR_DP, 2014 (UINT16)sizeof (MAC_ADDR_DEVICE_PATH) 2015 ); 2016 2017 if (MACDevPath != NULL) { 2018 MACDevPath->IfType = (UINT8)Strtoi (IfTypeStr); 2019 2020 Length = sizeof (EFI_MAC_ADDRESS); 2021 if ((MACDevPath->IfType == 0x01) || (MACDevPath->IfType == 0x00)) { 2022 Length = 6; 2023 } 2024 2025 StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length); 2026 } 2027 2028 return (EFI_DEVICE_PATH_PROTOCOL *)MACDevPath; 2029 } 2030 2031 /** 2032 Converts a text format to the network protocol ID. 2033 2034 @param Text String of protocol field. 2035 2036 @return Network protocol ID . 2037 2038 **/ 2039 static 2040 UINTN 2041 NetworkProtocolFromText ( 2042 IN CHAR16 *Text 2043 ) 2044 { 2045 if (StrCmp (Text, "UDP") == 0) { 2046 return RFC_1700_UDP_PROTOCOL; 2047 } 2048 2049 if (StrCmp (Text, "TCP") == 0) { 2050 return RFC_1700_TCP_PROTOCOL; 2051 } 2052 2053 return Strtoi (Text); 2054 } 2055 2056 /** 2057 Converts a text device path node to IPV4 device path structure. 2058 2059 @param TextDeviceNode The input Text device path node. 2060 2061 @return A pointer to the newly-created IPV4 device path structure. 2062 2063 **/ 2064 static 2065 EFI_DEVICE_PATH_PROTOCOL * 2066 DevPathFromTextIPv4 ( 2067 IN CHAR16 *TextDeviceNode 2068 ) 2069 { 2070 CHAR16 *RemoteIPStr; 2071 CHAR16 *ProtocolStr; 2072 CHAR16 *TypeStr; 2073 CHAR16 *LocalIPStr; 2074 CHAR16 *GatewayIPStr; 2075 CHAR16 *SubnetMaskStr; 2076 IPv4_DEVICE_PATH *IPv4; 2077 2078 RemoteIPStr = GetNextParamStr (&TextDeviceNode); 2079 ProtocolStr = GetNextParamStr (&TextDeviceNode); 2080 TypeStr = GetNextParamStr (&TextDeviceNode); 2081 LocalIPStr = GetNextParamStr (&TextDeviceNode); 2082 GatewayIPStr = GetNextParamStr (&TextDeviceNode); 2083 SubnetMaskStr = GetNextParamStr (&TextDeviceNode); 2084 IPv4 = (IPv4_DEVICE_PATH *)CreateDeviceNode ( 2085 MESSAGING_DEVICE_PATH, 2086 MSG_IPv4_DP, 2087 (UINT16)sizeof (IPv4_DEVICE_PATH) 2088 ); 2089 2090 if (IPv4 == NULL) { 2091 return (EFI_DEVICE_PATH_PROTOCOL *)IPv4; 2092 } 2093 2094 StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL); 2095 IPv4->Protocol = (UINT16)NetworkProtocolFromText (ProtocolStr); 2096 if (StrCmp (TypeStr, "Static") == 0) { 2097 IPv4->StaticIpAddress = TRUE; 2098 } else { 2099 IPv4->StaticIpAddress = FALSE; 2100 } 2101 2102 StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL); 2103 if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) { 2104 StrToIpv4Address (GatewayIPStr, NULL, &IPv4->GatewayIpAddress, NULL); 2105 StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask, NULL); 2106 } else { 2107 ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress)); 2108 ZeroMem (&IPv4->SubnetMask, sizeof (IPv4->SubnetMask)); 2109 } 2110 2111 IPv4->LocalPort = 0; 2112 IPv4->RemotePort = 0; 2113 2114 return (EFI_DEVICE_PATH_PROTOCOL *)IPv4; 2115 } 2116 2117 /** 2118 Converts a text device path node to IPV6 device path structure. 2119 2120 @param TextDeviceNode The input Text device path node. 2121 2122 @return A pointer to the newly-created IPV6 device path structure. 2123 2124 **/ 2125 static 2126 EFI_DEVICE_PATH_PROTOCOL * 2127 DevPathFromTextIPv6 ( 2128 IN CHAR16 *TextDeviceNode 2129 ) 2130 { 2131 CHAR16 *RemoteIPStr; 2132 CHAR16 *ProtocolStr; 2133 CHAR16 *TypeStr; 2134 CHAR16 *LocalIPStr; 2135 CHAR16 *GatewayIPStr; 2136 CHAR16 *PrefixLengthStr; 2137 IPv6_DEVICE_PATH *IPv6; 2138 2139 RemoteIPStr = GetNextParamStr (&TextDeviceNode); 2140 ProtocolStr = GetNextParamStr (&TextDeviceNode); 2141 TypeStr = GetNextParamStr (&TextDeviceNode); 2142 LocalIPStr = GetNextParamStr (&TextDeviceNode); 2143 PrefixLengthStr = GetNextParamStr (&TextDeviceNode); 2144 GatewayIPStr = GetNextParamStr (&TextDeviceNode); 2145 IPv6 = (IPv6_DEVICE_PATH *)CreateDeviceNode ( 2146 MESSAGING_DEVICE_PATH, 2147 MSG_IPv6_DP, 2148 (UINT16)sizeof (IPv6_DEVICE_PATH) 2149 ); 2150 2151 if (IPv6 == NULL) { 2152 return (EFI_DEVICE_PATH_PROTOCOL *)IPv6; 2153 } 2154 2155 StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL); 2156 IPv6->Protocol = (UINT16)NetworkProtocolFromText (ProtocolStr); 2157 if (StrCmp (TypeStr, "Static") == 0) { 2158 IPv6->IpAddressOrigin = 0; 2159 } else if (StrCmp (TypeStr, "StatelessAutoConfigure") == 0) { 2160 IPv6->IpAddressOrigin = 1; 2161 } else { 2162 IPv6->IpAddressOrigin = 2; 2163 } 2164 2165 StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL); 2166 if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) { 2167 StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL); 2168 IPv6->PrefixLength = (UINT8)Strtoi (PrefixLengthStr); 2169 } else { 2170 ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress)); 2171 IPv6->PrefixLength = 0; 2172 } 2173 2174 IPv6->LocalPort = 0; 2175 IPv6->RemotePort = 0; 2176 2177 return (EFI_DEVICE_PATH_PROTOCOL *)IPv6; 2178 } 2179 2180 /** 2181 Converts a text device path node to UART device path structure. 2182 2183 @param TextDeviceNode The input Text device path node. 2184 2185 @return A pointer to the newly-created UART device path structure. 2186 2187 **/ 2188 static 2189 EFI_DEVICE_PATH_PROTOCOL * 2190 DevPathFromTextUart ( 2191 IN CHAR16 *TextDeviceNode 2192 ) 2193 { 2194 CHAR16 *BaudStr; 2195 CHAR16 *DataBitsStr; 2196 CHAR16 *ParityStr; 2197 CHAR16 *StopBitsStr; 2198 UART_DEVICE_PATH *Uart; 2199 2200 BaudStr = GetNextParamStr (&TextDeviceNode); 2201 DataBitsStr = GetNextParamStr (&TextDeviceNode); 2202 ParityStr = GetNextParamStr (&TextDeviceNode); 2203 StopBitsStr = GetNextParamStr (&TextDeviceNode); 2204 Uart = (UART_DEVICE_PATH *)CreateDeviceNode ( 2205 MESSAGING_DEVICE_PATH, 2206 MSG_UART_DP, 2207 (UINT16)sizeof (UART_DEVICE_PATH) 2208 ); 2209 2210 if (Uart == NULL) { 2211 return (EFI_DEVICE_PATH_PROTOCOL *)Uart; 2212 } 2213 2214 if (StrCmp (BaudStr, "DEFAULT") == 0) { 2215 Uart->BaudRate = 115200; 2216 } else { 2217 Strtoi64 (BaudStr, &Uart->BaudRate); 2218 } 2219 2220 Uart->DataBits = (UINT8)((StrCmp (DataBitsStr, "DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr)); 2221 switch (*ParityStr) { 2222 case 'D': 2223 Uart->Parity = 0; 2224 break; 2225 2226 case 'N': 2227 Uart->Parity = 1; 2228 break; 2229 2230 case 'E': 2231 Uart->Parity = 2; 2232 break; 2233 2234 case 'O': 2235 Uart->Parity = 3; 2236 break; 2237 2238 case 'M': 2239 Uart->Parity = 4; 2240 break; 2241 2242 case 'S': 2243 Uart->Parity = 5; 2244 break; 2245 2246 default: 2247 Uart->Parity = (UINT8)Strtoi (ParityStr); 2248 break; 2249 } 2250 2251 if (StrCmp (StopBitsStr, "D") == 0) { 2252 Uart->StopBits = (UINT8)0; 2253 } else if (StrCmp (StopBitsStr, "1") == 0) { 2254 Uart->StopBits = (UINT8)1; 2255 } else if (StrCmp (StopBitsStr, "1.5") == 0) { 2256 Uart->StopBits = (UINT8)2; 2257 } else if (StrCmp (StopBitsStr, "2") == 0) { 2258 Uart->StopBits = (UINT8)3; 2259 } else { 2260 Uart->StopBits = (UINT8)Strtoi (StopBitsStr); 2261 } 2262 2263 return (EFI_DEVICE_PATH_PROTOCOL *)Uart; 2264 } 2265 2266 /** 2267 Converts a text device path node to USB class device path structure. 2268 2269 @param TextDeviceNode The input Text device path node. 2270 @param UsbClassText A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text. 2271 2272 @return A pointer to the newly-created USB class device path structure. 2273 2274 **/ 2275 static 2276 EFI_DEVICE_PATH_PROTOCOL * 2277 ConvertFromTextUsbClass ( 2278 IN CHAR16 *TextDeviceNode, 2279 IN USB_CLASS_TEXT *UsbClassText 2280 ) 2281 { 2282 CHAR16 *VIDStr; 2283 CHAR16 *PIDStr; 2284 CHAR16 *ClassStr; 2285 CHAR16 *SubClassStr; 2286 CHAR16 *ProtocolStr; 2287 USB_CLASS_DEVICE_PATH *UsbClass; 2288 2289 UsbClass = (USB_CLASS_DEVICE_PATH *)CreateDeviceNode ( 2290 MESSAGING_DEVICE_PATH, 2291 MSG_USB_CLASS_DP, 2292 (UINT16)sizeof (USB_CLASS_DEVICE_PATH) 2293 ); 2294 2295 if (UsbClass == NULL) { 2296 return (EFI_DEVICE_PATH_PROTOCOL *)UsbClass; 2297 } 2298 2299 VIDStr = GetNextParamStr (&TextDeviceNode); 2300 PIDStr = GetNextParamStr (&TextDeviceNode); 2301 if (UsbClassText->ClassExist) { 2302 ClassStr = GetNextParamStr (&TextDeviceNode); 2303 if (*ClassStr == '\0') { 2304 UsbClass->DeviceClass = 0xFF; 2305 } else { 2306 UsbClass->DeviceClass = (UINT8)Strtoi (ClassStr); 2307 } 2308 } else { 2309 UsbClass->DeviceClass = UsbClassText->Class; 2310 } 2311 2312 if (UsbClassText->SubClassExist) { 2313 SubClassStr = GetNextParamStr (&TextDeviceNode); 2314 if (*SubClassStr == '\0') { 2315 UsbClass->DeviceSubClass = 0xFF; 2316 } else { 2317 UsbClass->DeviceSubClass = (UINT8)Strtoi (SubClassStr); 2318 } 2319 } else { 2320 UsbClass->DeviceSubClass = UsbClassText->SubClass; 2321 } 2322 2323 ProtocolStr = GetNextParamStr (&TextDeviceNode); 2324 2325 if (*VIDStr == '\0') { 2326 UsbClass->VendorId = 0xFFFF; 2327 } else { 2328 UsbClass->VendorId = (UINT16)Strtoi (VIDStr); 2329 } 2330 2331 if (*PIDStr == '\0') { 2332 UsbClass->ProductId = 0xFFFF; 2333 } else { 2334 UsbClass->ProductId = (UINT16)Strtoi (PIDStr); 2335 } 2336 2337 if (*ProtocolStr == '\0') { 2338 UsbClass->DeviceProtocol = 0xFF; 2339 } else { 2340 UsbClass->DeviceProtocol = (UINT8)Strtoi (ProtocolStr); 2341 } 2342 2343 return (EFI_DEVICE_PATH_PROTOCOL *)UsbClass; 2344 } 2345 2346 /** 2347 Converts a text device path node to USB class device path structure. 2348 2349 @param TextDeviceNode The input Text device path node. 2350 2351 @return A pointer to the newly-created USB class device path structure. 2352 2353 **/ 2354 static 2355 EFI_DEVICE_PATH_PROTOCOL * 2356 DevPathFromTextUsbClass ( 2357 IN CHAR16 *TextDeviceNode 2358 ) 2359 { 2360 USB_CLASS_TEXT UsbClassText; 2361 2362 UsbClassText.ClassExist = TRUE; 2363 UsbClassText.SubClassExist = TRUE; 2364 2365 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2366 } 2367 2368 /** 2369 Converts a text device path node to USB audio device path structure. 2370 2371 @param TextDeviceNode The input Text device path node. 2372 2373 @return A pointer to the newly-created USB audio device path structure. 2374 2375 **/ 2376 static 2377 EFI_DEVICE_PATH_PROTOCOL * 2378 DevPathFromTextUsbAudio ( 2379 IN CHAR16 *TextDeviceNode 2380 ) 2381 { 2382 USB_CLASS_TEXT UsbClassText; 2383 2384 UsbClassText.ClassExist = FALSE; 2385 UsbClassText.Class = USB_CLASS_AUDIO; 2386 UsbClassText.SubClassExist = TRUE; 2387 2388 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2389 } 2390 2391 /** 2392 Converts a text device path node to USB CDC Control device path structure. 2393 2394 @param TextDeviceNode The input Text device path node. 2395 2396 @return A pointer to the newly-created USB CDC Control device path structure. 2397 2398 **/ 2399 static 2400 EFI_DEVICE_PATH_PROTOCOL * 2401 DevPathFromTextUsbCDCControl ( 2402 IN CHAR16 *TextDeviceNode 2403 ) 2404 { 2405 USB_CLASS_TEXT UsbClassText; 2406 2407 UsbClassText.ClassExist = FALSE; 2408 UsbClassText.Class = USB_CLASS_CDCCONTROL; 2409 UsbClassText.SubClassExist = TRUE; 2410 2411 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2412 } 2413 2414 /** 2415 Converts a text device path node to USB HID device path structure. 2416 2417 @param TextDeviceNode The input Text device path node. 2418 2419 @return A pointer to the newly-created USB HID device path structure. 2420 2421 **/ 2422 static 2423 EFI_DEVICE_PATH_PROTOCOL * 2424 DevPathFromTextUsbHID ( 2425 IN CHAR16 *TextDeviceNode 2426 ) 2427 { 2428 USB_CLASS_TEXT UsbClassText; 2429 2430 UsbClassText.ClassExist = FALSE; 2431 UsbClassText.Class = USB_CLASS_HID; 2432 UsbClassText.SubClassExist = TRUE; 2433 2434 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2435 } 2436 2437 /** 2438 Converts a text device path node to USB Image device path structure. 2439 2440 @param TextDeviceNode The input Text device path node. 2441 2442 @return A pointer to the newly-created USB Image device path structure. 2443 2444 **/ 2445 static 2446 EFI_DEVICE_PATH_PROTOCOL * 2447 DevPathFromTextUsbImage ( 2448 IN CHAR16 *TextDeviceNode 2449 ) 2450 { 2451 USB_CLASS_TEXT UsbClassText; 2452 2453 UsbClassText.ClassExist = FALSE; 2454 UsbClassText.Class = USB_CLASS_IMAGE; 2455 UsbClassText.SubClassExist = TRUE; 2456 2457 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2458 } 2459 2460 /** 2461 Converts a text device path node to USB Print device path structure. 2462 2463 @param TextDeviceNode The input Text device path node. 2464 2465 @return A pointer to the newly-created USB Print device path structure. 2466 2467 **/ 2468 static 2469 EFI_DEVICE_PATH_PROTOCOL * 2470 DevPathFromTextUsbPrinter ( 2471 IN CHAR16 *TextDeviceNode 2472 ) 2473 { 2474 USB_CLASS_TEXT UsbClassText; 2475 2476 UsbClassText.ClassExist = FALSE; 2477 UsbClassText.Class = USB_CLASS_PRINTER; 2478 UsbClassText.SubClassExist = TRUE; 2479 2480 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2481 } 2482 2483 /** 2484 Converts a text device path node to USB mass storage device path structure. 2485 2486 @param TextDeviceNode The input Text device path node. 2487 2488 @return A pointer to the newly-created USB mass storage device path structure. 2489 2490 **/ 2491 static 2492 EFI_DEVICE_PATH_PROTOCOL * 2493 DevPathFromTextUsbMassStorage ( 2494 IN CHAR16 *TextDeviceNode 2495 ) 2496 { 2497 USB_CLASS_TEXT UsbClassText; 2498 2499 UsbClassText.ClassExist = FALSE; 2500 UsbClassText.Class = USB_CLASS_MASS_STORAGE; 2501 UsbClassText.SubClassExist = TRUE; 2502 2503 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2504 } 2505 2506 /** 2507 Converts a text device path node to USB HUB device path structure. 2508 2509 @param TextDeviceNode The input Text device path node. 2510 2511 @return A pointer to the newly-created USB HUB device path structure. 2512 2513 **/ 2514 static 2515 EFI_DEVICE_PATH_PROTOCOL * 2516 DevPathFromTextUsbHub ( 2517 IN CHAR16 *TextDeviceNode 2518 ) 2519 { 2520 USB_CLASS_TEXT UsbClassText; 2521 2522 UsbClassText.ClassExist = FALSE; 2523 UsbClassText.Class = USB_CLASS_HUB; 2524 UsbClassText.SubClassExist = TRUE; 2525 2526 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2527 } 2528 2529 /** 2530 Converts a text device path node to USB CDC data device path structure. 2531 2532 @param TextDeviceNode The input Text device path node. 2533 2534 @return A pointer to the newly-created USB CDC data device path structure. 2535 2536 **/ 2537 static 2538 EFI_DEVICE_PATH_PROTOCOL * 2539 DevPathFromTextUsbCDCData ( 2540 IN CHAR16 *TextDeviceNode 2541 ) 2542 { 2543 USB_CLASS_TEXT UsbClassText; 2544 2545 UsbClassText.ClassExist = FALSE; 2546 UsbClassText.Class = USB_CLASS_CDCDATA; 2547 UsbClassText.SubClassExist = TRUE; 2548 2549 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2550 } 2551 2552 /** 2553 Converts a text device path node to USB smart card device path structure. 2554 2555 @param TextDeviceNode The input Text device path node. 2556 2557 @return A pointer to the newly-created USB smart card device path structure. 2558 2559 **/ 2560 static 2561 EFI_DEVICE_PATH_PROTOCOL * 2562 DevPathFromTextUsbSmartCard ( 2563 IN CHAR16 *TextDeviceNode 2564 ) 2565 { 2566 USB_CLASS_TEXT UsbClassText; 2567 2568 UsbClassText.ClassExist = FALSE; 2569 UsbClassText.Class = USB_CLASS_SMART_CARD; 2570 UsbClassText.SubClassExist = TRUE; 2571 2572 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2573 } 2574 2575 /** 2576 Converts a text device path node to USB video device path structure. 2577 2578 @param TextDeviceNode The input Text device path node. 2579 2580 @return A pointer to the newly-created USB video device path structure. 2581 2582 **/ 2583 static 2584 EFI_DEVICE_PATH_PROTOCOL * 2585 DevPathFromTextUsbVideo ( 2586 IN CHAR16 *TextDeviceNode 2587 ) 2588 { 2589 USB_CLASS_TEXT UsbClassText; 2590 2591 UsbClassText.ClassExist = FALSE; 2592 UsbClassText.Class = USB_CLASS_VIDEO; 2593 UsbClassText.SubClassExist = TRUE; 2594 2595 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2596 } 2597 2598 /** 2599 Converts a text device path node to USB diagnostic device path structure. 2600 2601 @param TextDeviceNode The input Text device path node. 2602 2603 @return A pointer to the newly-created USB diagnostic device path structure. 2604 2605 **/ 2606 static 2607 EFI_DEVICE_PATH_PROTOCOL * 2608 DevPathFromTextUsbDiagnostic ( 2609 IN CHAR16 *TextDeviceNode 2610 ) 2611 { 2612 USB_CLASS_TEXT UsbClassText; 2613 2614 UsbClassText.ClassExist = FALSE; 2615 UsbClassText.Class = USB_CLASS_DIAGNOSTIC; 2616 UsbClassText.SubClassExist = TRUE; 2617 2618 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2619 } 2620 2621 /** 2622 Converts a text device path node to USB wireless device path structure. 2623 2624 @param TextDeviceNode The input Text device path node. 2625 2626 @return A pointer to the newly-created USB wireless device path structure. 2627 2628 **/ 2629 static 2630 EFI_DEVICE_PATH_PROTOCOL * 2631 DevPathFromTextUsbWireless ( 2632 IN CHAR16 *TextDeviceNode 2633 ) 2634 { 2635 USB_CLASS_TEXT UsbClassText; 2636 2637 UsbClassText.ClassExist = FALSE; 2638 UsbClassText.Class = USB_CLASS_WIRELESS; 2639 UsbClassText.SubClassExist = TRUE; 2640 2641 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2642 } 2643 2644 /** 2645 Converts a text device path node to USB device firmware update device path structure. 2646 2647 @param TextDeviceNode The input Text device path node. 2648 2649 @return A pointer to the newly-created USB device firmware update device path structure. 2650 2651 **/ 2652 static 2653 EFI_DEVICE_PATH_PROTOCOL * 2654 DevPathFromTextUsbDeviceFirmwareUpdate ( 2655 IN CHAR16 *TextDeviceNode 2656 ) 2657 { 2658 USB_CLASS_TEXT UsbClassText; 2659 2660 UsbClassText.ClassExist = FALSE; 2661 UsbClassText.Class = USB_CLASS_RESERVE; 2662 UsbClassText.SubClassExist = FALSE; 2663 UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE; 2664 2665 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2666 } 2667 2668 /** 2669 Converts a text device path node to USB IRDA bridge device path structure. 2670 2671 @param TextDeviceNode The input Text device path node. 2672 2673 @return A pointer to the newly-created USB IRDA bridge device path structure. 2674 2675 **/ 2676 static 2677 EFI_DEVICE_PATH_PROTOCOL * 2678 DevPathFromTextUsbIrdaBridge ( 2679 IN CHAR16 *TextDeviceNode 2680 ) 2681 { 2682 USB_CLASS_TEXT UsbClassText; 2683 2684 UsbClassText.ClassExist = FALSE; 2685 UsbClassText.Class = USB_CLASS_RESERVE; 2686 UsbClassText.SubClassExist = FALSE; 2687 UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE; 2688 2689 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2690 } 2691 2692 /** 2693 Converts a text device path node to USB text and measurement device path structure. 2694 2695 @param TextDeviceNode The input Text device path node. 2696 2697 @return A pointer to the newly-created USB text and measurement device path structure. 2698 2699 **/ 2700 static 2701 EFI_DEVICE_PATH_PROTOCOL * 2702 DevPathFromTextUsbTestAndMeasurement ( 2703 IN CHAR16 *TextDeviceNode 2704 ) 2705 { 2706 USB_CLASS_TEXT UsbClassText; 2707 2708 UsbClassText.ClassExist = FALSE; 2709 UsbClassText.Class = USB_CLASS_RESERVE; 2710 UsbClassText.SubClassExist = FALSE; 2711 UsbClassText.SubClass = USB_SUBCLASS_TEST; 2712 2713 return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); 2714 } 2715 2716 /** 2717 Converts a text device path node to USB WWID device path structure. 2718 2719 @param TextDeviceNode The input Text device path node. 2720 2721 @return A pointer to the newly-created USB WWID device path structure. 2722 2723 **/ 2724 static 2725 EFI_DEVICE_PATH_PROTOCOL * 2726 DevPathFromTextUsbWwid ( 2727 IN CHAR16 *TextDeviceNode 2728 ) 2729 { 2730 CHAR16 *VIDStr; 2731 CHAR16 *PIDStr; 2732 CHAR16 *InterfaceNumStr; 2733 CHAR16 *SerialNumberStr; 2734 USB_WWID_DEVICE_PATH *UsbWwid; 2735 UINTN SerialNumberStrLen; 2736 2737 VIDStr = GetNextParamStr (&TextDeviceNode); 2738 PIDStr = GetNextParamStr (&TextDeviceNode); 2739 InterfaceNumStr = GetNextParamStr (&TextDeviceNode); 2740 SerialNumberStr = GetNextParamStr (&TextDeviceNode); 2741 SerialNumberStrLen = StrLen (SerialNumberStr); 2742 if ((SerialNumberStrLen >= 2) && 2743 (SerialNumberStr[0] == '\"') && 2744 (SerialNumberStr[SerialNumberStrLen - 1] == '\"') 2745 ) 2746 { 2747 SerialNumberStr[SerialNumberStrLen - 1] = '\0'; 2748 SerialNumberStr++; 2749 SerialNumberStrLen -= 2; 2750 } 2751 2752 UsbWwid = (USB_WWID_DEVICE_PATH *)CreateDeviceNode ( 2753 MESSAGING_DEVICE_PATH, 2754 MSG_USB_WWID_DP, 2755 (UINT16)(sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16)) 2756 ); 2757 2758 if (UsbWwid != NULL) { 2759 UsbWwid->VendorId = (UINT16)Strtoi (VIDStr); 2760 UsbWwid->ProductId = (UINT16)Strtoi (PIDStr); 2761 UsbWwid->InterfaceNumber = (UINT16)Strtoi (InterfaceNumStr); 2762 2763 // 2764 // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr. 2765 // Therefore, the '\0' will not be copied. 2766 // 2767 CopyMem ( 2768 (UINT8 *)UsbWwid + sizeof (USB_WWID_DEVICE_PATH), 2769 SerialNumberStr, 2770 SerialNumberStrLen * sizeof (CHAR16) 2771 ); 2772 } 2773 2774 return (EFI_DEVICE_PATH_PROTOCOL *)UsbWwid; 2775 } 2776 2777 /** 2778 Converts a text device path node to Logic Unit device path structure. 2779 2780 @param TextDeviceNode The input Text device path node. 2781 2782 @return A pointer to the newly-created Logic Unit device path structure. 2783 2784 **/ 2785 static 2786 EFI_DEVICE_PATH_PROTOCOL * 2787 DevPathFromTextUnit ( 2788 IN CHAR16 *TextDeviceNode 2789 ) 2790 { 2791 CHAR16 *LunStr; 2792 DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit; 2793 2794 LunStr = GetNextParamStr (&TextDeviceNode); 2795 LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *)CreateDeviceNode ( 2796 MESSAGING_DEVICE_PATH, 2797 MSG_DEVICE_LOGICAL_UNIT_DP, 2798 (UINT16)sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH) 2799 ); 2800 2801 if (LogicalUnit != NULL) { 2802 LogicalUnit->Lun = (UINT8)Strtoi (LunStr); 2803 } 2804 2805 return (EFI_DEVICE_PATH_PROTOCOL *)LogicalUnit; 2806 } 2807 2808 /** 2809 Converts a text device path node to iSCSI device path structure. 2810 2811 @param TextDeviceNode The input Text device path node. 2812 2813 @return A pointer to the newly-created iSCSI device path structure. 2814 2815 **/ 2816 static 2817 EFI_DEVICE_PATH_PROTOCOL * 2818 DevPathFromTextiSCSI ( 2819 IN CHAR16 *TextDeviceNode 2820 ) 2821 { 2822 UINT16 Options; 2823 CHAR16 *NameStr; 2824 CHAR16 *PortalGroupStr; 2825 CHAR16 *LunStr; 2826 CHAR16 *HeaderDigestStr; 2827 CHAR16 *DataDigestStr; 2828 CHAR16 *AuthenticationStr; 2829 CHAR16 *ProtocolStr; 2830 CHAR8 *AsciiStr; 2831 ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath; 2832 UINT64 Lun; 2833 2834 NameStr = GetNextParamStr (&TextDeviceNode); 2835 PortalGroupStr = GetNextParamStr (&TextDeviceNode); 2836 LunStr = GetNextParamStr (&TextDeviceNode); 2837 HeaderDigestStr = GetNextParamStr (&TextDeviceNode); 2838 DataDigestStr = GetNextParamStr (&TextDeviceNode); 2839 AuthenticationStr = GetNextParamStr (&TextDeviceNode); 2840 ProtocolStr = GetNextParamStr (&TextDeviceNode); 2841 ISCSIDevPath = (ISCSI_DEVICE_PATH_WITH_NAME *)CreateDeviceNode ( 2842 MESSAGING_DEVICE_PATH, 2843 MSG_ISCSI_DP, 2844 (UINT16)(sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr)) 2845 ); 2846 2847 if (ISCSIDevPath == NULL) { 2848 return (EFI_DEVICE_PATH_PROTOCOL *)ISCSIDevPath; 2849 } 2850 2851 AsciiStr = ISCSIDevPath->TargetName; 2852 StrToAscii (NameStr, &AsciiStr); 2853 2854 ISCSIDevPath->TargetPortalGroupTag = (UINT16)Strtoi (PortalGroupStr); 2855 Strtoi64 (LunStr, &Lun); 2856 WriteUnaligned64 ((UINT64 *)&ISCSIDevPath->Lun, SwapBytes64 (Lun)); 2857 2858 Options = 0x0000; 2859 if (StrCmp (HeaderDigestStr, "CRC32C") == 0) { 2860 Options |= 0x0002; 2861 } 2862 2863 if (StrCmp (DataDigestStr, "CRC32C") == 0) { 2864 Options |= 0x0008; 2865 } 2866 2867 if (StrCmp (AuthenticationStr, "None") == 0) { 2868 Options |= 0x0800; 2869 } 2870 2871 if (StrCmp (AuthenticationStr, "CHAP_UNI") == 0) { 2872 Options |= 0x1000; 2873 } 2874 2875 ISCSIDevPath->LoginOption = (UINT16)Options; 2876 2877 if (IS_NULL (*ProtocolStr) || (StrCmp (ProtocolStr, "TCP") == 0)) { 2878 ISCSIDevPath->NetworkProtocol = 0; 2879 } else { 2880 // 2881 // Undefined and reserved. 2882 // 2883 ISCSIDevPath->NetworkProtocol = 1; 2884 } 2885 2886 return (EFI_DEVICE_PATH_PROTOCOL *)ISCSIDevPath; 2887 } 2888 2889 /** 2890 Converts a text device path node to VLAN device path structure. 2891 2892 @param TextDeviceNode The input Text device path node. 2893 2894 @return A pointer to the newly-created VLAN device path structure. 2895 2896 **/ 2897 static 2898 EFI_DEVICE_PATH_PROTOCOL * 2899 DevPathFromTextVlan ( 2900 IN CHAR16 *TextDeviceNode 2901 ) 2902 { 2903 CHAR16 *VlanStr; 2904 VLAN_DEVICE_PATH *Vlan; 2905 2906 VlanStr = GetNextParamStr (&TextDeviceNode); 2907 Vlan = (VLAN_DEVICE_PATH *)CreateDeviceNode ( 2908 MESSAGING_DEVICE_PATH, 2909 MSG_VLAN_DP, 2910 (UINT16)sizeof (VLAN_DEVICE_PATH) 2911 ); 2912 2913 if (Vlan != NULL) { 2914 Vlan->VlanId = (UINT16)Strtoi (VlanStr); 2915 } 2916 2917 return (EFI_DEVICE_PATH_PROTOCOL *)Vlan; 2918 } 2919 2920 /** 2921 Converts a text device path node to Bluetooth device path structure. 2922 2923 @param TextDeviceNode The input Text device path node. 2924 2925 @return A pointer to the newly-created Bluetooth device path structure. 2926 2927 **/ 2928 static 2929 EFI_DEVICE_PATH_PROTOCOL * 2930 DevPathFromTextBluetooth ( 2931 IN CHAR16 *TextDeviceNode 2932 ) 2933 { 2934 CHAR16 *BluetoothStr; 2935 BLUETOOTH_DEVICE_PATH *BluetoothDp; 2936 2937 BluetoothStr = GetNextParamStr (&TextDeviceNode); 2938 BluetoothDp = (BLUETOOTH_DEVICE_PATH *)CreateDeviceNode ( 2939 MESSAGING_DEVICE_PATH, 2940 MSG_BLUETOOTH_DP, 2941 (UINT16)sizeof (BLUETOOTH_DEVICE_PATH) 2942 ); 2943 2944 if (BluetoothDp != NULL) { 2945 StrHexToBytes ( 2946 BluetoothStr, 2947 sizeof (BLUETOOTH_ADDRESS) * 2, 2948 BluetoothDp->BD_ADDR.Address, 2949 sizeof (BLUETOOTH_ADDRESS) 2950 ); 2951 } 2952 2953 return (EFI_DEVICE_PATH_PROTOCOL *)BluetoothDp; 2954 } 2955 2956 /** 2957 Converts a text device path node to Wi-Fi device path structure. 2958 2959 @param TextDeviceNode The input Text device path node. 2960 2961 @return A pointer to the newly-created Wi-Fi device path structure. 2962 2963 **/ 2964 static 2965 EFI_DEVICE_PATH_PROTOCOL * 2966 DevPathFromTextWiFi ( 2967 IN CHAR16 *TextDeviceNode 2968 ) 2969 { 2970 CHAR16 *SSIdStr; 2971 CHAR8 AsciiStr[33]; 2972 UINTN DataLen; 2973 WIFI_DEVICE_PATH *WiFiDp; 2974 2975 SSIdStr = GetNextParamStr (&TextDeviceNode); 2976 WiFiDp = (WIFI_DEVICE_PATH *)CreateDeviceNode ( 2977 MESSAGING_DEVICE_PATH, 2978 MSG_WIFI_DP, 2979 (UINT16)sizeof (WIFI_DEVICE_PATH) 2980 ); 2981 2982 if ((NULL != SSIdStr) && (NULL != WiFiDp)) { 2983 DataLen = StrLen (SSIdStr); 2984 if (StrLen (SSIdStr) > 32) { 2985 SSIdStr[32] = '\0'; 2986 DataLen = 32; 2987 } 2988 2989 UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr)); 2990 CopyMem (WiFiDp->SSId, AsciiStr, DataLen); 2991 } 2992 2993 return (EFI_DEVICE_PATH_PROTOCOL *)WiFiDp; 2994 } 2995 2996 /** 2997 Converts a text device path node to Bluetooth LE device path structure. 2998 2999 @param TextDeviceNode The input Text device path node. 3000 3001 @return A pointer to the newly-created Bluetooth LE device path structure. 3002 3003 **/ 3004 static 3005 EFI_DEVICE_PATH_PROTOCOL * 3006 DevPathFromTextBluetoothLE ( 3007 IN CHAR16 *TextDeviceNode 3008 ) 3009 { 3010 CHAR16 *BluetoothLeAddrStr; 3011 CHAR16 *BluetoothLeAddrTypeStr; 3012 BLUETOOTH_LE_DEVICE_PATH *BluetoothLeDp; 3013 3014 BluetoothLeAddrStr = GetNextParamStr (&TextDeviceNode); 3015 BluetoothLeAddrTypeStr = GetNextParamStr (&TextDeviceNode); 3016 BluetoothLeDp = (BLUETOOTH_LE_DEVICE_PATH *)CreateDeviceNode ( 3017 MESSAGING_DEVICE_PATH, 3018 MSG_BLUETOOTH_LE_DP, 3019 (UINT16)sizeof (BLUETOOTH_LE_DEVICE_PATH) 3020 ); 3021 3022 if (BluetoothLeDp != NULL) { 3023 BluetoothLeDp->Address.Type = (UINT8)Strtoi (BluetoothLeAddrTypeStr); 3024 StrHexToBytes ( 3025 BluetoothLeAddrStr, 3026 sizeof (BluetoothLeDp->Address.Address) * 2, 3027 BluetoothLeDp->Address.Address, 3028 sizeof (BluetoothLeDp->Address.Address) 3029 ); 3030 } 3031 3032 return (EFI_DEVICE_PATH_PROTOCOL *)BluetoothLeDp; 3033 } 3034 3035 /** 3036 Converts a text device path node to DNS device path structure. 3037 3038 @param TextDeviceNode The input Text device path node. 3039 3040 @return A pointer to the newly-created DNS device path structure. 3041 3042 **/ 3043 static 3044 EFI_DEVICE_PATH_PROTOCOL * 3045 DevPathFromTextDns ( 3046 IN CHAR16 *TextDeviceNode 3047 ) 3048 { 3049 CHAR16 *DeviceNodeStr; 3050 CHAR16 *DeviceNodeStrPtr; 3051 UINT32 DnsServerIpCount; 3052 UINT16 DnsDeviceNodeLength; 3053 DNS_DEVICE_PATH *DnsDeviceNode; 3054 UINT32 DnsServerIpIndex; 3055 CHAR16 *DnsServerIp; 3056 3057 // 3058 // Count the DNS server address number. 3059 // 3060 DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode); 3061 if (DeviceNodeStr == NULL) { 3062 return NULL; 3063 } 3064 3065 DeviceNodeStrPtr = DeviceNodeStr; 3066 3067 DnsServerIpCount = 0; 3068 while (DeviceNodeStrPtr != NULL && *DeviceNodeStrPtr != '\0') { 3069 GetNextParamStr (&DeviceNodeStrPtr); 3070 DnsServerIpCount++; 3071 } 3072 3073 FreePool (DeviceNodeStr); 3074 DeviceNodeStr = NULL; 3075 3076 // 3077 // One or more instances of the DNS server address in EFI_IP_ADDRESS, 3078 // otherwise, NULL will be returned. 3079 // 3080 if (DnsServerIpCount == 0) { 3081 return NULL; 3082 } 3083 3084 // 3085 // Create the DNS DeviceNode. 3086 // 3087 DnsDeviceNodeLength = (UINT16)(sizeof (EFI_DEVICE_PATH_PROTOCOL) + sizeof (UINT8) + DnsServerIpCount * sizeof (EFI_IP_ADDRESS)); 3088 DnsDeviceNode = (DNS_DEVICE_PATH *)CreateDeviceNode ( 3089 MESSAGING_DEVICE_PATH, 3090 MSG_DNS_DP, 3091 DnsDeviceNodeLength 3092 ); 3093 if (DnsDeviceNode == NULL) { 3094 return NULL; 3095 } 3096 3097 // 3098 // Confirm the DNS server address is IPv4 or IPv6 type. 3099 // 3100 DeviceNodeStrPtr = TextDeviceNode; 3101 while (!IS_NULL (*DeviceNodeStrPtr)) { 3102 if (*DeviceNodeStrPtr == '.') { 3103 DnsDeviceNode->IsIPv6 = 0x00; 3104 break; 3105 } 3106 3107 if (*DeviceNodeStrPtr == ':') { 3108 DnsDeviceNode->IsIPv6 = 0x01; 3109 break; 3110 } 3111 3112 DeviceNodeStrPtr++; 3113 } 3114 3115 for (DnsServerIpIndex = 0; DnsServerIpIndex < DnsServerIpCount; DnsServerIpIndex++) { 3116 DnsServerIp = GetNextParamStr (&TextDeviceNode); 3117 if (DnsDeviceNode->IsIPv6 == 0x00) { 3118 StrToIpv4Address (DnsServerIp, NULL, &(DnsDeviceNode->DnsServerIp[DnsServerIpIndex].v4), NULL); 3119 } else { 3120 StrToIpv6Address (DnsServerIp, NULL, &(DnsDeviceNode->DnsServerIp[DnsServerIpIndex].v6), NULL); 3121 } 3122 } 3123 3124 return (EFI_DEVICE_PATH_PROTOCOL *)DnsDeviceNode; 3125 } 3126 3127 /** 3128 Converts a text device path node to URI device path structure. 3129 3130 @param TextDeviceNode The input Text device path node. 3131 3132 @return A pointer to the newly-created URI device path structure. 3133 3134 **/ 3135 static 3136 EFI_DEVICE_PATH_PROTOCOL * 3137 DevPathFromTextUri ( 3138 IN CHAR16 *TextDeviceNode 3139 ) 3140 { 3141 CHAR16 *UriStr; 3142 UINTN UriLength; 3143 URI_DEVICE_PATH *Uri; 3144 3145 UriStr = GetNextParamStr (&TextDeviceNode); 3146 UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH)); 3147 Uri = (URI_DEVICE_PATH *)CreateDeviceNode ( 3148 MESSAGING_DEVICE_PATH, 3149 MSG_URI_DP, 3150 (UINT16)(sizeof (URI_DEVICE_PATH) + UriLength) 3151 ); 3152 3153 while (Uri != NULL && UriLength-- != 0) { 3154 Uri->Uri[UriLength] = (CHAR8)UriStr[UriLength]; 3155 } 3156 3157 return (EFI_DEVICE_PATH_PROTOCOL *)Uri; 3158 } 3159 3160 /** 3161 Converts a media text device path node to media device path structure. 3162 3163 @param TextDeviceNode The input Text device path node. 3164 3165 @return A pointer to media device path structure. 3166 3167 **/ 3168 static 3169 EFI_DEVICE_PATH_PROTOCOL * 3170 DevPathFromTextMediaPath ( 3171 IN CHAR16 *TextDeviceNode 3172 ) 3173 { 3174 return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode); 3175 } 3176 3177 /** 3178 Converts a text device path node to HD device path structure. 3179 3180 @param TextDeviceNode The input Text device path node. 3181 3182 @return A pointer to the newly-created HD device path structure. 3183 3184 **/ 3185 static 3186 EFI_DEVICE_PATH_PROTOCOL * 3187 DevPathFromTextHD ( 3188 IN CHAR16 *TextDeviceNode 3189 ) 3190 { 3191 CHAR16 *PartitionStr; 3192 CHAR16 *TypeStr; 3193 CHAR16 *SignatureStr; 3194 CHAR16 *StartStr; 3195 CHAR16 *SizeStr; 3196 UINT32 Signature32; 3197 HARDDRIVE_DEVICE_PATH *Hd; 3198 3199 PartitionStr = GetNextParamStr (&TextDeviceNode); 3200 TypeStr = GetNextParamStr (&TextDeviceNode); 3201 SignatureStr = GetNextParamStr (&TextDeviceNode); 3202 StartStr = GetNextParamStr (&TextDeviceNode); 3203 SizeStr = GetNextParamStr (&TextDeviceNode); 3204 Hd = (HARDDRIVE_DEVICE_PATH *)CreateDeviceNode ( 3205 MEDIA_DEVICE_PATH, 3206 MEDIA_HARDDRIVE_DP, 3207 (UINT16)sizeof (HARDDRIVE_DEVICE_PATH) 3208 ); 3209 3210 if (Hd == NULL) { 3211 return (EFI_DEVICE_PATH_PROTOCOL *)Hd; 3212 } 3213 3214 Hd->PartitionNumber = (UINT32)Strtoi (PartitionStr); 3215 3216 ZeroMem (Hd->Signature, 16); 3217 Hd->MBRType = (UINT8)0; 3218 3219 if (StrCmp (TypeStr, "MBR") == 0) { 3220 Hd->SignatureType = SIGNATURE_TYPE_MBR; 3221 Hd->MBRType = 0x01; 3222 3223 Signature32 = (UINT32)Strtoi (SignatureStr); 3224 CopyMem (Hd->Signature, &Signature32, sizeof (UINT32)); 3225 } else if (StrCmp (TypeStr, "GPT") == 0) { 3226 Hd->SignatureType = SIGNATURE_TYPE_GUID; 3227 Hd->MBRType = 0x02; 3228 3229 StrToGuid (SignatureStr, (EFI_GUID *)Hd->Signature); 3230 } else { 3231 Hd->SignatureType = (UINT8)Strtoi (TypeStr); 3232 } 3233 3234 Strtoi64 (StartStr, &Hd->PartitionStart); 3235 Strtoi64 (SizeStr, &Hd->PartitionSize); 3236 3237 return (EFI_DEVICE_PATH_PROTOCOL *)Hd; 3238 } 3239 3240 /** 3241 Converts a text device path node to CDROM device path structure. 3242 3243 @param TextDeviceNode The input Text device path node. 3244 3245 @return A pointer to the newly-created CDROM device path structure. 3246 3247 **/ 3248 static 3249 EFI_DEVICE_PATH_PROTOCOL * 3250 DevPathFromTextCDROM ( 3251 IN CHAR16 *TextDeviceNode 3252 ) 3253 { 3254 CHAR16 *EntryStr; 3255 CHAR16 *StartStr; 3256 CHAR16 *SizeStr; 3257 CDROM_DEVICE_PATH *CDROMDevPath; 3258 3259 EntryStr = GetNextParamStr (&TextDeviceNode); 3260 StartStr = GetNextParamStr (&TextDeviceNode); 3261 SizeStr = GetNextParamStr (&TextDeviceNode); 3262 CDROMDevPath = (CDROM_DEVICE_PATH *)CreateDeviceNode ( 3263 MEDIA_DEVICE_PATH, 3264 MEDIA_CDROM_DP, 3265 (UINT16)sizeof (CDROM_DEVICE_PATH) 3266 ); 3267 3268 if (CDROMDevPath != NULL) { 3269 CDROMDevPath->BootEntry = (UINT32)Strtoi (EntryStr); 3270 Strtoi64 (StartStr, &CDROMDevPath->PartitionStart); 3271 Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize); 3272 } 3273 3274 return (EFI_DEVICE_PATH_PROTOCOL *)CDROMDevPath; 3275 } 3276 3277 /** 3278 Converts a text device path node to Vendor-defined media device path structure. 3279 3280 @param TextDeviceNode The input Text device path node. 3281 3282 @return A pointer to the newly-created Vendor-defined media device path structure. 3283 3284 **/ 3285 static 3286 EFI_DEVICE_PATH_PROTOCOL * 3287 DevPathFromTextVenMedia ( 3288 IN CHAR16 *TextDeviceNode 3289 ) 3290 { 3291 return ConvertFromTextVendor ( 3292 TextDeviceNode, 3293 MEDIA_DEVICE_PATH, 3294 MEDIA_VENDOR_DP 3295 ); 3296 } 3297 3298 /** 3299 Converts a text device path node to File device path structure. 3300 3301 @param TextDeviceNode The input Text device path node. 3302 3303 @return A pointer to the newly-created File device path structure. 3304 3305 **/ 3306 static 3307 EFI_DEVICE_PATH_PROTOCOL * 3308 DevPathFromTextFilePath ( 3309 IN CHAR16 *TextDeviceNode 3310 ) 3311 { 3312 FILEPATH_DEVICE_PATH *File; 3313 3314 #ifndef __FreeBSD__ 3315 File = (FILEPATH_DEVICE_PATH *)CreateDeviceNode ( 3316 MEDIA_DEVICE_PATH, 3317 MEDIA_FILEPATH_DP, 3318 (UINT16)(sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2) 3319 ); 3320 3321 if (File != NULL) { 3322 StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode); 3323 } 3324 #else 3325 size_t len = (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2); 3326 efi_char *v; 3327 File = (FILEPATH_DEVICE_PATH *)CreateDeviceNode ( 3328 MEDIA_DEVICE_PATH, 3329 MEDIA_FILEPATH_DP, 3330 (UINT16)len 3331 ); 3332 if (File != NULL) { 3333 v = File->PathName; 3334 utf8_to_ucs2(TextDeviceNode, &v, &len); 3335 } 3336 #endif 3337 3338 return (EFI_DEVICE_PATH_PROTOCOL *)File; 3339 } 3340 3341 /** 3342 Converts a text device path node to Media protocol device path structure. 3343 3344 @param TextDeviceNode The input Text device path node. 3345 3346 @return A pointer to the newly-created Media protocol device path structure. 3347 3348 **/ 3349 static 3350 EFI_DEVICE_PATH_PROTOCOL * 3351 DevPathFromTextMedia ( 3352 IN CHAR16 *TextDeviceNode 3353 ) 3354 { 3355 CHAR16 *GuidStr; 3356 MEDIA_PROTOCOL_DEVICE_PATH *Media; 3357 3358 GuidStr = GetNextParamStr (&TextDeviceNode); 3359 Media = (MEDIA_PROTOCOL_DEVICE_PATH *)CreateDeviceNode ( 3360 MEDIA_DEVICE_PATH, 3361 MEDIA_PROTOCOL_DP, 3362 (UINT16)sizeof (MEDIA_PROTOCOL_DEVICE_PATH) 3363 ); 3364 3365 if (Media != NULL) { 3366 StrToGuid (GuidStr, &Media->Protocol); 3367 } 3368 3369 return (EFI_DEVICE_PATH_PROTOCOL *)Media; 3370 } 3371 3372 /** 3373 Converts a text device path node to firmware volume device path structure. 3374 3375 @param TextDeviceNode The input Text device path node. 3376 3377 @return A pointer to the newly-created firmware volume device path structure. 3378 3379 **/ 3380 static 3381 EFI_DEVICE_PATH_PROTOCOL * 3382 DevPathFromTextFv ( 3383 IN CHAR16 *TextDeviceNode 3384 ) 3385 { 3386 CHAR16 *GuidStr; 3387 MEDIA_FW_VOL_DEVICE_PATH *Fv; 3388 3389 GuidStr = GetNextParamStr (&TextDeviceNode); 3390 Fv = (MEDIA_FW_VOL_DEVICE_PATH *)CreateDeviceNode ( 3391 MEDIA_DEVICE_PATH, 3392 MEDIA_PIWG_FW_VOL_DP, 3393 (UINT16)sizeof (MEDIA_FW_VOL_DEVICE_PATH) 3394 ); 3395 3396 if (Fv != NULL) { 3397 StrToGuid (GuidStr, &Fv->FvName); 3398 } 3399 3400 return (EFI_DEVICE_PATH_PROTOCOL *)Fv; 3401 } 3402 3403 /** 3404 Converts a text device path node to firmware file device path structure. 3405 3406 @param TextDeviceNode The input Text device path node. 3407 3408 @return A pointer to the newly-created firmware file device path structure. 3409 3410 **/ 3411 static 3412 EFI_DEVICE_PATH_PROTOCOL * 3413 DevPathFromTextFvFile ( 3414 IN CHAR16 *TextDeviceNode 3415 ) 3416 { 3417 CHAR16 *GuidStr; 3418 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile; 3419 3420 GuidStr = GetNextParamStr (&TextDeviceNode); 3421 FvFile = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)CreateDeviceNode ( 3422 MEDIA_DEVICE_PATH, 3423 MEDIA_PIWG_FW_FILE_DP, 3424 (UINT16)sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) 3425 ); 3426 3427 if (FvFile != NULL) { 3428 StrToGuid (GuidStr, &FvFile->FvFileName); 3429 } 3430 3431 return (EFI_DEVICE_PATH_PROTOCOL *)FvFile; 3432 } 3433 3434 /** 3435 Converts a text device path node to text relative offset device path structure. 3436 3437 @param TextDeviceNode The input Text device path node. 3438 3439 @return A pointer to the newly-created Text device path structure. 3440 3441 **/ 3442 static 3443 EFI_DEVICE_PATH_PROTOCOL * 3444 DevPathFromTextRelativeOffsetRange ( 3445 IN CHAR16 *TextDeviceNode 3446 ) 3447 { 3448 CHAR16 *StartingOffsetStr; 3449 CHAR16 *EndingOffsetStr; 3450 MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset; 3451 3452 StartingOffsetStr = GetNextParamStr (&TextDeviceNode); 3453 EndingOffsetStr = GetNextParamStr (&TextDeviceNode); 3454 Offset = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *)CreateDeviceNode ( 3455 MEDIA_DEVICE_PATH, 3456 MEDIA_RELATIVE_OFFSET_RANGE_DP, 3457 (UINT16)sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH) 3458 ); 3459 3460 if (Offset != NULL) { 3461 Strtoi64 (StartingOffsetStr, &Offset->StartingOffset); 3462 Strtoi64 (EndingOffsetStr, &Offset->EndingOffset); 3463 } 3464 3465 return (EFI_DEVICE_PATH_PROTOCOL *)Offset; 3466 } 3467 3468 /** 3469 Converts a text device path node to text ram disk device path structure. 3470 3471 @param TextDeviceNode The input Text device path node. 3472 3473 @return A pointer to the newly-created Text device path structure. 3474 3475 **/ 3476 static 3477 EFI_DEVICE_PATH_PROTOCOL * 3478 DevPathFromTextRamDisk ( 3479 IN CHAR16 *TextDeviceNode 3480 ) 3481 { 3482 CHAR16 *StartingAddrStr; 3483 CHAR16 *EndingAddrStr; 3484 CHAR16 *TypeGuidStr; 3485 CHAR16 *InstanceStr; 3486 MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; 3487 UINT64 StartingAddr; 3488 UINT64 EndingAddr; 3489 3490 StartingAddrStr = GetNextParamStr (&TextDeviceNode); 3491 EndingAddrStr = GetNextParamStr (&TextDeviceNode); 3492 InstanceStr = GetNextParamStr (&TextDeviceNode); 3493 TypeGuidStr = GetNextParamStr (&TextDeviceNode); 3494 RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *)CreateDeviceNode ( 3495 MEDIA_DEVICE_PATH, 3496 MEDIA_RAM_DISK_DP, 3497 (UINT16)sizeof (MEDIA_RAM_DISK_DEVICE_PATH) 3498 ); 3499 3500 if (RamDisk != NULL) { 3501 Strtoi64 (StartingAddrStr, &StartingAddr); 3502 WriteUnaligned64 ((UINT64 *)&(RamDisk->StartingAddr[0]), StartingAddr); 3503 Strtoi64 (EndingAddrStr, &EndingAddr); 3504 WriteUnaligned64 ((UINT64 *)&(RamDisk->EndingAddr[0]), EndingAddr); 3505 RamDisk->Instance = (UINT16)Strtoi (InstanceStr); 3506 StrToGuid (TypeGuidStr, &RamDisk->TypeGuid); 3507 } 3508 3509 return (EFI_DEVICE_PATH_PROTOCOL *)RamDisk; 3510 } 3511 3512 /** 3513 Converts a text device path node to text virtual disk device path structure. 3514 3515 @param TextDeviceNode The input Text device path node. 3516 3517 @return A pointer to the newly-created Text device path structure. 3518 3519 **/ 3520 static 3521 EFI_DEVICE_PATH_PROTOCOL * 3522 DevPathFromTextVirtualDisk ( 3523 IN CHAR16 *TextDeviceNode 3524 ) 3525 { 3526 CHAR16 *StartingAddrStr; 3527 CHAR16 *EndingAddrStr; 3528 CHAR16 *InstanceStr; 3529 MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; 3530 UINT64 StartingAddr; 3531 UINT64 EndingAddr; 3532 3533 StartingAddrStr = GetNextParamStr (&TextDeviceNode); 3534 EndingAddrStr = GetNextParamStr (&TextDeviceNode); 3535 InstanceStr = GetNextParamStr (&TextDeviceNode); 3536 3537 RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *)CreateDeviceNode ( 3538 MEDIA_DEVICE_PATH, 3539 MEDIA_RAM_DISK_DP, 3540 (UINT16)sizeof (MEDIA_RAM_DISK_DEVICE_PATH) 3541 ); 3542 3543 if (RamDisk != NULL) { 3544 Strtoi64 (StartingAddrStr, &StartingAddr); 3545 WriteUnaligned64 ((UINT64 *)&(RamDisk->StartingAddr[0]), StartingAddr); 3546 Strtoi64 (EndingAddrStr, &EndingAddr); 3547 WriteUnaligned64 ((UINT64 *)&(RamDisk->EndingAddr[0]), EndingAddr); 3548 RamDisk->Instance = (UINT16)Strtoi (InstanceStr); 3549 CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid); 3550 } 3551 3552 return (EFI_DEVICE_PATH_PROTOCOL *)RamDisk; 3553 } 3554 3555 /** 3556 Converts a text device path node to text virtual cd device path structure. 3557 3558 @param TextDeviceNode The input Text device path node. 3559 3560 @return A pointer to the newly-created Text device path structure. 3561 3562 **/ 3563 static 3564 EFI_DEVICE_PATH_PROTOCOL * 3565 DevPathFromTextVirtualCd ( 3566 IN CHAR16 *TextDeviceNode 3567 ) 3568 { 3569 CHAR16 *StartingAddrStr; 3570 CHAR16 *EndingAddrStr; 3571 CHAR16 *InstanceStr; 3572 MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; 3573 UINT64 StartingAddr; 3574 UINT64 EndingAddr; 3575 3576 StartingAddrStr = GetNextParamStr (&TextDeviceNode); 3577 EndingAddrStr = GetNextParamStr (&TextDeviceNode); 3578 InstanceStr = GetNextParamStr (&TextDeviceNode); 3579 3580 RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *)CreateDeviceNode ( 3581 MEDIA_DEVICE_PATH, 3582 MEDIA_RAM_DISK_DP, 3583 (UINT16)sizeof (MEDIA_RAM_DISK_DEVICE_PATH) 3584 ); 3585 3586 if (RamDisk != NULL) { 3587 Strtoi64 (StartingAddrStr, &StartingAddr); 3588 WriteUnaligned64 ((UINT64 *)&(RamDisk->StartingAddr[0]), StartingAddr); 3589 Strtoi64 (EndingAddrStr, &EndingAddr); 3590 WriteUnaligned64 ((UINT64 *)&(RamDisk->EndingAddr[0]), EndingAddr); 3591 RamDisk->Instance = (UINT16)Strtoi (InstanceStr); 3592 CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid); 3593 } 3594 3595 return (EFI_DEVICE_PATH_PROTOCOL *)RamDisk; 3596 } 3597 3598 /** 3599 Converts a text device path node to text persistent virtual disk device path structure. 3600 3601 @param TextDeviceNode The input Text device path node. 3602 3603 @return A pointer to the newly-created Text device path structure. 3604 3605 **/ 3606 static 3607 EFI_DEVICE_PATH_PROTOCOL * 3608 DevPathFromTextPersistentVirtualDisk ( 3609 IN CHAR16 *TextDeviceNode 3610 ) 3611 { 3612 CHAR16 *StartingAddrStr; 3613 CHAR16 *EndingAddrStr; 3614 CHAR16 *InstanceStr; 3615 MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; 3616 UINT64 StartingAddr; 3617 UINT64 EndingAddr; 3618 3619 StartingAddrStr = GetNextParamStr (&TextDeviceNode); 3620 EndingAddrStr = GetNextParamStr (&TextDeviceNode); 3621 InstanceStr = GetNextParamStr (&TextDeviceNode); 3622 3623 RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *)CreateDeviceNode ( 3624 MEDIA_DEVICE_PATH, 3625 MEDIA_RAM_DISK_DP, 3626 (UINT16)sizeof (MEDIA_RAM_DISK_DEVICE_PATH) 3627 ); 3628 3629 if (RamDisk != NULL) { 3630 Strtoi64 (StartingAddrStr, &StartingAddr); 3631 WriteUnaligned64 ((UINT64 *)&(RamDisk->StartingAddr[0]), StartingAddr); 3632 Strtoi64 (EndingAddrStr, &EndingAddr); 3633 WriteUnaligned64 ((UINT64 *)&(RamDisk->EndingAddr[0]), EndingAddr); 3634 RamDisk->Instance = (UINT16)Strtoi (InstanceStr); 3635 CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid); 3636 } 3637 3638 return (EFI_DEVICE_PATH_PROTOCOL *)RamDisk; 3639 } 3640 3641 /** 3642 Converts a text device path node to text persistent virtual cd device path structure. 3643 3644 @param TextDeviceNode The input Text device path node. 3645 3646 @return A pointer to the newly-created Text device path structure. 3647 3648 **/ 3649 static 3650 EFI_DEVICE_PATH_PROTOCOL * 3651 DevPathFromTextPersistentVirtualCd ( 3652 IN CHAR16 *TextDeviceNode 3653 ) 3654 { 3655 CHAR16 *StartingAddrStr; 3656 CHAR16 *EndingAddrStr; 3657 CHAR16 *InstanceStr; 3658 MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; 3659 UINT64 StartingAddr; 3660 UINT64 EndingAddr; 3661 3662 StartingAddrStr = GetNextParamStr (&TextDeviceNode); 3663 EndingAddrStr = GetNextParamStr (&TextDeviceNode); 3664 InstanceStr = GetNextParamStr (&TextDeviceNode); 3665 3666 RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *)CreateDeviceNode ( 3667 MEDIA_DEVICE_PATH, 3668 MEDIA_RAM_DISK_DP, 3669 (UINT16)sizeof (MEDIA_RAM_DISK_DEVICE_PATH) 3670 ); 3671 3672 if (RamDisk != NULL) { 3673 Strtoi64 (StartingAddrStr, &StartingAddr); 3674 WriteUnaligned64 ((UINT64 *)&(RamDisk->StartingAddr[0]), StartingAddr); 3675 Strtoi64 (EndingAddrStr, &EndingAddr); 3676 WriteUnaligned64 ((UINT64 *)&(RamDisk->EndingAddr[0]), EndingAddr); 3677 RamDisk->Instance = (UINT16)Strtoi (InstanceStr); 3678 CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid); 3679 } 3680 3681 return (EFI_DEVICE_PATH_PROTOCOL *)RamDisk; 3682 } 3683 3684 /** 3685 Converts a BBS text device path node to BBS device path structure. 3686 3687 @param TextDeviceNode The input Text device path node. 3688 3689 @return A pointer to BBS device path structure. 3690 3691 **/ 3692 static 3693 EFI_DEVICE_PATH_PROTOCOL * 3694 DevPathFromTextBbsPath ( 3695 IN CHAR16 *TextDeviceNode 3696 ) 3697 { 3698 return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode); 3699 } 3700 3701 /** 3702 Converts a text device path node to BIOS Boot Specification device path structure. 3703 3704 @param TextDeviceNode The input Text device path node. 3705 3706 @return A pointer to the newly-created BIOS Boot Specification device path structure. 3707 3708 **/ 3709 static 3710 EFI_DEVICE_PATH_PROTOCOL * 3711 DevPathFromTextBBS ( 3712 IN CHAR16 *TextDeviceNode 3713 ) 3714 { 3715 CHAR16 *TypeStr; 3716 CHAR16 *IdStr; 3717 CHAR16 *FlagsStr; 3718 CHAR8 *AsciiStr; 3719 BBS_BBS_DEVICE_PATH *Bbs; 3720 3721 TypeStr = GetNextParamStr (&TextDeviceNode); 3722 IdStr = GetNextParamStr (&TextDeviceNode); 3723 FlagsStr = GetNextParamStr (&TextDeviceNode); 3724 Bbs = (BBS_BBS_DEVICE_PATH *)CreateDeviceNode ( 3725 BBS_DEVICE_PATH, 3726 BBS_BBS_DP, 3727 (UINT16)(sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr)) 3728 ); 3729 3730 if (Bbs == NULL) { 3731 return (EFI_DEVICE_PATH_PROTOCOL *)Bbs; 3732 } 3733 3734 if (StrCmp (TypeStr, "Floppy") == 0) { 3735 Bbs->DeviceType = BBS_TYPE_FLOPPY; 3736 } else if (StrCmp (TypeStr, "HD") == 0) { 3737 Bbs->DeviceType = BBS_TYPE_HARDDRIVE; 3738 } else if (StrCmp (TypeStr, "CDROM") == 0) { 3739 Bbs->DeviceType = BBS_TYPE_CDROM; 3740 } else if (StrCmp (TypeStr, "PCMCIA") == 0) { 3741 Bbs->DeviceType = BBS_TYPE_PCMCIA; 3742 } else if (StrCmp (TypeStr, "USB") == 0) { 3743 Bbs->DeviceType = BBS_TYPE_USB; 3744 } else if (StrCmp (TypeStr, "Network") == 0) { 3745 Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK; 3746 } else { 3747 Bbs->DeviceType = (UINT16)Strtoi (TypeStr); 3748 } 3749 3750 AsciiStr = Bbs->String; 3751 StrToAscii (IdStr, &AsciiStr); 3752 3753 Bbs->StatusFlag = (UINT16)Strtoi (FlagsStr); 3754 3755 return (EFI_DEVICE_PATH_PROTOCOL *)Bbs; 3756 } 3757 3758 /** 3759 Converts a text device path node to SATA device path structure. 3760 3761 @param TextDeviceNode The input Text device path node. 3762 3763 @return A pointer to the newly-created SATA device path structure. 3764 3765 **/ 3766 static 3767 EFI_DEVICE_PATH_PROTOCOL * 3768 DevPathFromTextSata ( 3769 IN CHAR16 *TextDeviceNode 3770 ) 3771 { 3772 SATA_DEVICE_PATH *Sata; 3773 CHAR16 *Param1; 3774 CHAR16 *Param2; 3775 CHAR16 *Param3; 3776 3777 Param1 = GetNextParamStr (&TextDeviceNode); 3778 Param2 = GetNextParamStr (&TextDeviceNode); 3779 Param3 = GetNextParamStr (&TextDeviceNode); 3780 3781 Sata = (SATA_DEVICE_PATH *)CreateDeviceNode ( 3782 MESSAGING_DEVICE_PATH, 3783 MSG_SATA_DP, 3784 (UINT16)sizeof (SATA_DEVICE_PATH) 3785 ); 3786 3787 if (Sata == NULL) { 3788 return (EFI_DEVICE_PATH_PROTOCOL *)Sata; 3789 } 3790 3791 Sata->HBAPortNumber = (UINT16)Strtoi (Param1); 3792 3793 // 3794 // According to UEFI spec, if PMPN is not provided, the default is 0xFFFF 3795 // 3796 if (*Param2 == '\0' ) { 3797 Sata->PortMultiplierPortNumber = 0xFFFF; 3798 } else { 3799 Sata->PortMultiplierPortNumber = (UINT16)Strtoi (Param2); 3800 } 3801 3802 Sata->Lun = (UINT16)Strtoi (Param3); 3803 3804 return (EFI_DEVICE_PATH_PROTOCOL *)Sata; 3805 } 3806 3807 GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = { 3808 { "Path", DevPathFromTextPath }, 3809 3810 { "HardwarePath", DevPathFromTextHardwarePath }, 3811 { "Pci", DevPathFromTextPci }, 3812 { "PcCard", DevPathFromTextPcCard }, 3813 { "MemoryMapped", DevPathFromTextMemoryMapped }, 3814 { "VenHw", DevPathFromTextVenHw }, 3815 { "Ctrl", DevPathFromTextCtrl }, 3816 { "BMC", DevPathFromTextBmc }, 3817 3818 { "AcpiPath", DevPathFromTextAcpiPath }, 3819 { "Acpi", DevPathFromTextAcpi }, 3820 { "PciRoot", DevPathFromTextPciRoot }, 3821 { "PcieRoot", DevPathFromTextPcieRoot }, 3822 { "Floppy", DevPathFromTextFloppy }, 3823 { "Keyboard", DevPathFromTextKeyboard }, 3824 { "Serial", DevPathFromTextSerial }, 3825 { "ParallelPort", DevPathFromTextParallelPort }, 3826 { "AcpiEx", DevPathFromTextAcpiEx }, 3827 { "AcpiExp", DevPathFromTextAcpiExp }, 3828 { "AcpiAdr", DevPathFromTextAcpiAdr }, 3829 3830 { "Msg", DevPathFromTextMsg }, 3831 { "Ata", DevPathFromTextAta }, 3832 { "Scsi", DevPathFromTextScsi }, 3833 { "Fibre", DevPathFromTextFibre }, 3834 { "FibreEx", DevPathFromTextFibreEx }, 3835 { "I1394", DevPathFromText1394 }, 3836 { "USB", DevPathFromTextUsb }, 3837 { "I2O", DevPathFromTextI2O }, 3838 { "Infiniband", DevPathFromTextInfiniband }, 3839 { "VenMsg", DevPathFromTextVenMsg }, 3840 { "VenPcAnsi", DevPathFromTextVenPcAnsi }, 3841 { "VenVt100", DevPathFromTextVenVt100 }, 3842 { "VenVt100Plus", DevPathFromTextVenVt100Plus }, 3843 { "VenUtf8", DevPathFromTextVenUtf8 }, 3844 { "UartFlowCtrl", DevPathFromTextUartFlowCtrl }, 3845 { "SAS", DevPathFromTextSAS }, 3846 { "SasEx", DevPathFromTextSasEx }, 3847 { "NVMe", DevPathFromTextNVMe }, 3848 { "UFS", DevPathFromTextUfs }, 3849 { "SD", DevPathFromTextSd }, 3850 { "eMMC", DevPathFromTextEmmc }, 3851 { "DebugPort", DevPathFromTextDebugPort }, 3852 { "MAC", DevPathFromTextMAC }, 3853 { "IPv4", DevPathFromTextIPv4 }, 3854 { "IPv6", DevPathFromTextIPv6 }, 3855 { "Uart", DevPathFromTextUart }, 3856 { "UsbClass", DevPathFromTextUsbClass }, 3857 { "UsbAudio", DevPathFromTextUsbAudio }, 3858 { "UsbCDCControl", DevPathFromTextUsbCDCControl }, 3859 { "UsbHID", DevPathFromTextUsbHID }, 3860 { "UsbImage", DevPathFromTextUsbImage }, 3861 { "UsbPrinter", DevPathFromTextUsbPrinter }, 3862 { "UsbMassStorage", DevPathFromTextUsbMassStorage }, 3863 { "UsbHub", DevPathFromTextUsbHub }, 3864 { "UsbCDCData", DevPathFromTextUsbCDCData }, 3865 { "UsbSmartCard", DevPathFromTextUsbSmartCard }, 3866 { "UsbVideo", DevPathFromTextUsbVideo }, 3867 { "UsbDiagnostic", DevPathFromTextUsbDiagnostic }, 3868 { "UsbWireless", DevPathFromTextUsbWireless }, 3869 { "UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate }, 3870 { "UsbIrdaBridge", DevPathFromTextUsbIrdaBridge }, 3871 { "UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement }, 3872 { "UsbWwid", DevPathFromTextUsbWwid }, 3873 { "Unit", DevPathFromTextUnit }, 3874 { "iSCSI", DevPathFromTextiSCSI }, 3875 { "Vlan", DevPathFromTextVlan }, 3876 { "Dns", DevPathFromTextDns }, 3877 { "Uri", DevPathFromTextUri }, 3878 { "Bluetooth", DevPathFromTextBluetooth }, 3879 { "Wi-Fi", DevPathFromTextWiFi }, 3880 { "BluetoothLE", DevPathFromTextBluetoothLE }, 3881 { "MediaPath", DevPathFromTextMediaPath }, 3882 { "HD", DevPathFromTextHD }, 3883 { "CDROM", DevPathFromTextCDROM }, 3884 { "VenMedia", DevPathFromTextVenMedia }, 3885 { "Media", DevPathFromTextMedia }, 3886 { "Fv", DevPathFromTextFv }, 3887 { "FvFile", DevPathFromTextFvFile }, 3888 { "File", DevPathFromTextFilePath }, 3889 { "Offset", DevPathFromTextRelativeOffsetRange }, 3890 { "RamDisk", DevPathFromTextRamDisk }, 3891 { "VirtualDisk", DevPathFromTextVirtualDisk }, 3892 { "VirtualCD", DevPathFromTextVirtualCd }, 3893 { "PersistentVirtualDisk", DevPathFromTextPersistentVirtualDisk }, 3894 { "PersistentVirtualCD", DevPathFromTextPersistentVirtualCd }, 3895 3896 { "BbsPath", DevPathFromTextBbsPath }, 3897 { "BBS", DevPathFromTextBBS }, 3898 { "Sata", DevPathFromTextSata }, 3899 { NULL, NULL } 3900 }; 3901 3902 /** 3903 Convert text to the binary representation of a device node. 3904 3905 @param TextDeviceNode TextDeviceNode points to the text representation of a device 3906 node. Conversion starts with the first character and continues 3907 until the first non-device node character. 3908 3909 @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was 3910 insufficient memory or text unsupported. 3911 3912 **/ 3913 static 3914 EFI_DEVICE_PATH_PROTOCOL * 3915 EFIAPI 3916 UefiDevicePathLibConvertTextToDeviceNode ( 3917 IN CONST CHAR16 *TextDeviceNode 3918 ) 3919 { 3920 DEVICE_PATH_FROM_TEXT FromText; 3921 CHAR16 *ParamStr; 3922 EFI_DEVICE_PATH_PROTOCOL *DeviceNode; 3923 CHAR16 *DeviceNodeStr; 3924 UINTN Index; 3925 3926 if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) { 3927 return NULL; 3928 } 3929 3930 ParamStr = NULL; 3931 FromText = NULL; 3932 DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode); 3933 ASSERT (DeviceNodeStr != NULL); 3934 3935 for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) { 3936 ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText); 3937 if (ParamStr != NULL) { 3938 FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function; 3939 break; 3940 } 3941 } 3942 3943 if (FromText == NULL) { 3944 // 3945 // A file path 3946 // 3947 FromText = DevPathFromTextFilePath; 3948 DeviceNode = FromText (DeviceNodeStr); 3949 } else { 3950 DeviceNode = FromText (ParamStr); 3951 FreePool (ParamStr); 3952 } 3953 3954 FreePool (DeviceNodeStr); 3955 3956 return DeviceNode; 3957 } 3958 3959 /** 3960 Convert text to the binary representation of a device path. 3961 3962 3963 @param TextDevicePath TextDevicePath points to the text representation of a device 3964 path. Conversion starts with the first character and continues 3965 until the first non-device node character. 3966 3967 @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or 3968 there was insufficient memory. 3969 3970 **/ 3971 static 3972 EFI_DEVICE_PATH_PROTOCOL * 3973 EFIAPI 3974 UefiDevicePathLibConvertTextToDevicePath ( 3975 IN CONST CHAR16 *TextDevicePath 3976 ) 3977 { 3978 EFI_DEVICE_PATH_PROTOCOL *DeviceNode; 3979 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; 3980 CHAR16 *DevicePathStr; 3981 CHAR16 *Str; 3982 CHAR16 *DeviceNodeStr; 3983 BOOLEAN IsInstanceEnd; 3984 EFI_DEVICE_PATH_PROTOCOL *DevicePath; 3985 3986 if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) { 3987 return NULL; 3988 } 3989 3990 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)AllocatePool (END_DEVICE_PATH_LENGTH); 3991 3992 if (DevicePath == NULL) { 3993 ASSERT (DevicePath != NULL); 3994 return NULL; 3995 } 3996 3997 SetDevicePathEndNode (DevicePath); 3998 3999 DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath); 4000 4001 if (DevicePathStr == NULL) { 4002 return NULL; 4003 } 4004 4005 Str = DevicePathStr; 4006 while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) { 4007 DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr); 4008 4009 NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode); 4010 if (DevicePath != NULL) { 4011 FreePool (DevicePath); 4012 } 4013 4014 if (DeviceNode != NULL) { 4015 FreePool (DeviceNode); 4016 } 4017 4018 DevicePath = NewDevicePath; 4019 4020 if (IsInstanceEnd) { 4021 DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *)AllocatePool (END_DEVICE_PATH_LENGTH); 4022 if (DeviceNode == NULL) { 4023 ASSERT (DeviceNode != NULL); 4024 return NULL; 4025 } 4026 4027 SetDevicePathEndNode (DeviceNode); 4028 DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; 4029 4030 NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode); 4031 if (DevicePath != NULL) { 4032 FreePool (DevicePath); 4033 } 4034 4035 if (DeviceNode != NULL) { 4036 FreePool (DeviceNode); 4037 } 4038 4039 DevicePath = NewDevicePath; 4040 } 4041 } 4042 4043 FreePool (DevicePathStr); 4044 return DevicePath; 4045 } 4046 4047 ssize_t 4048 efidp_parse_device_path(char *path, efidp out, size_t max) 4049 { 4050 EFI_DEVICE_PATH_PROTOCOL *dp; 4051 UINTN len; 4052 4053 dp = UefiDevicePathLibConvertTextToDevicePath (path); 4054 if (dp == NULL) 4055 return -1; 4056 len = GetDevicePathSize(dp); 4057 if (len > max) { 4058 free(dp); 4059 return -1; 4060 } 4061 memcpy(out, dp, len); 4062 free(dp); 4063 4064 return len; 4065 } 4066