Use C code parse device path to output hex string, and Python
run command when PCD Value need device path parse.
https://bugzilla.tianocore.org/show_bug.cgi?id=541
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/BinaryFiles.txt | 3 +-
BaseTools/Source/C/DevicePath/DevicePath.c | 188 ++
BaseTools/Source/C/DevicePath/DevicePath.h | 1404 ++++++++
BaseTools/Source/C/DevicePath/DevicePathFromText.c | 3503 ++++++++++++++++++++
BaseTools/Source/C/DevicePath/DevicePathFromText.h | 72 +
.../Source/C/DevicePath/DevicePathUtilities.c | 2352 +++++++++++++
.../Source/C/DevicePath/DevicePathUtilities.h | 555 ++++
BaseTools/Source/C/DevicePath/GNUmakefile | 30 +
BaseTools/Source/C/DevicePath/Makefile | 24 +
BaseTools/Source/C/DevicePath/UefiDevicePathLib.c | 298 ++
BaseTools/Source/C/DevicePath/UefiDevicePathLib.h | 473 +++
BaseTools/Source/C/GNUmakefile | 3 +-
BaseTools/Source/C/Makefile | 5 +-
BaseTools/Source/Python/Common/Misc.py | 35 +-
BaseTools/Source/Python/Workspace/DscBuildData.py | 2 +-
15 files changed, 8940 insertions(+), 7 deletions(-)
create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.h
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.h
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.h
create mode 100644 BaseTools/Source/C/DevicePath/GNUmakefile
create mode 100644 BaseTools/Source/C/DevicePath/Makefile
create mode 100644 BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
create mode 100644 BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
diff --git a/BaseTools/Source/BinaryFiles.txt b/BaseTools/Source/BinaryFiles.txt
index 7b014a7..a5273d4 100644
--- a/BaseTools/Source/BinaryFiles.txt
+++ b/BaseTools/Source/BinaryFiles.txt
@@ -9,11 +9,11 @@
# [ExtraFiles.Win32] section.
# The [CxFreeze.Win32] section is maintained by the owner of the Build Server who
# must ensure that files that are required by the cx_freeze frozen binaries are
# present in the Bin\Win32 directory.
#
-# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available under
# the terms and conditions of the BSD License which accompanies this distribution.
# The full text of the license may be found at:
# http://opensource.org/licenses/bsd-license.php
@@ -57,10 +57,11 @@ TianoCompress.exe
Trim.exe
UPT.exe
VfrCompile.exe
VolInfo.exe
Pkcs7Sign.exe
+DevicePath.exe
[ExtraFiles.Win32]
TestSigningPrivateKey.pem
config.ini
exception.xml
diff --git a/BaseTools/Source/C/DevicePath/DevicePath.c b/BaseTools/Source/C/DevicePath/DevicePath.c
new file mode 100644
index 0000000..6c32ad4
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePath.c
@@ -0,0 +1,188 @@
+/** @file
+ Definition for Device Path Tool.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UefiDevicePathLib.h"
+
+//
+// Utility Name
+//
+#define UTILITY_NAME "DevicePath"
+
+//
+// Utility version information
+//
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+EFI_GUID gEfiDebugPortDevicePathGuid = DEVICE_PATH_MESSAGING_DEBUGPORT;
+EFI_GUID gEfiPcAnsiGuid = EFI_PC_ANSI_GUID;
+EFI_GUID gEfiVT100Guid = EFI_VT_100_GUID;
+EFI_GUID gEfiVT100PlusGuid = EFI_VT_100_PLUS_GUID;
+EFI_GUID gEfiVTUTF8Guid = EFI_VT_UTF8_GUID;
+EFI_GUID gEfiUartDevicePathGuid = EFI_UART_DEVICE_PATH_GUID;
+EFI_GUID gEfiSasDevicePathGuid = EFI_SAS_DEVICE_PATH_GUID;
+EFI_GUID gEfiVirtualDiskGuid = { 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }};
+EFI_GUID gEfiVirtualCdGuid = { 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }};
+EFI_GUID gEfiPersistentVirtualDiskGuid = { 0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }};
+EFI_GUID gEfiPersistentVirtualCdGuid = { 0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }};
+
+STATIC
+VOID
+Version (
+ VOID
+)
+/*++
+
+Routine Description:
+
+ Displays the standard utility information to SDTOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+STATIC
+VOID
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " DevicePathString DevicePathString like as:\n"
+ " \"PciRoot(0)/Pci(0,0)\"\n"
+ " start with \" and end with \"\n"
+ " not support blank in device path string.\n");
+
+ fprintf (stdout, " --version Show program's version number and exit.\n");
+ fprintf (stdout, " -h, --help Show this help message and exit.\n");
+}
+
+
+void print_mem(void const *vp, size_t n)
+{
+ unsigned char const *p = vp;
+ for (size_t i=0; i<n; i++) {
+ printf("0x%02x ", p[i]);
+ }
+}
+
+VOID
+Ascii2UnicodeString (
+ CHAR8 *String,
+ CHAR16 *UniString
+ )
+/*++
+
+Routine Description:
+
+ Write ascii string as unicode string format to FILE
+
+Arguments:
+
+ String - Pointer to string that is written to FILE.
+ UniString - Pointer to unicode string
+
+Returns:
+
+ NULL
+
+--*/
+{
+ while (*String != '\0') {
+ *(UniString++) = (CHAR16) *(String++);
+ }
+ //
+ // End the UniString with a NULL.
+ //
+ *UniString = '\0';
+}
+
+int main(int argc, CHAR8 *argv[])
+{
+ CHAR8 * Str;
+ CHAR16* Str16;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "No input options specified.");
+ Usage ();
+ return STATUS_ERROR;
+ }
+ if ((stricmp (argv[1], "-h") == 0) || (stricmp (argv[1], "--help") == 0)) {
+ Version ();
+ Usage ();
+ return STATUS_SUCCESS;
+ }
+
+ if (stricmp (argv[1], "--version") == 0) {
+ Version ();
+ return STATUS_SUCCESS;
+ }
+ Str = argv[1];
+ if (Str == NULL) {
+ fprintf(stderr, "Invalid option value, Device Path can't be NULL");
+ return STATUS_ERROR;
+ }
+ Str16 = (CHAR16 *)malloc(1024);
+ if (Str16 == NULL) {
+ fprintf(stderr, "Resource, memory cannot be allcoated");
+ return STATUS_ERROR;
+ }
+ Ascii2UnicodeString(Str, Str16);
+ DevicePath = UefiDevicePathLibConvertTextToDevicePath(Str16);
+ while (!((DevicePath->Type == END_DEVICE_PATH_TYPE) && (DevicePath->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)) )
+ {
+ print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1] << 8));
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)DevicePath + (DevicePath->Length[0] | DevicePath->Length[1] << 8));
+ }
+ print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1] << 8));
+ putchar('\n');
+ return STATUS_SUCCESS;
+}
diff --git a/BaseTools/Source/C/DevicePath/DevicePath.h b/BaseTools/Source/C/DevicePath/DevicePath.h
new file mode 100644
index 0000000..389c993
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePath.h
@@ -0,0 +1,1404 @@
+/** @file
+ The device path protocol as defined in UEFI 2.0.
+
+ The device path represents a programmatic path to a device,
+ from a software point of view. The path must persist from boot to boot, so
+ it can not contain things like PCI bus numbers that change from boot to boot.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_DEVICE_PATH_H__
+#define __EFI_DEVICE_PATH_H__
+
+#include <Guid/PcAnsi.h>
+#include <IndustryStandard/Acpi3_0.h>
+
+///
+/// Device Path protocol.
+///
+#define EFI_DEVICE_PATH_PROTOCOL_GUID \
+ { \
+ 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+///
+/// Device Path guid definition for backward-compatible with EFI1.1.
+///
+#define DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL_GUID
+
+#pragma pack(1)
+
+/**
+ This protocol can be used on any device handle to obtain generic path/location
+ information concerning the physical device or logical device. If the handle does
+ not logically map to a physical device, the handle may not necessarily support
+ the device path protocol. The device path describes the location of the device
+ the handle is for. The size of the Device Path can be determined from the structures
+ that make up the Device Path.
+**/
+typedef struct {
+ UINT8 Type; ///< 0x01 Hardware Device Path.
+ ///< 0x02 ACPI Device Path.
+ ///< 0x03 Messaging Device Path.
+ ///< 0x04 Media Device Path.
+ ///< 0x05 BIOS Boot Specification Device Path.
+ ///< 0x7F End of Hardware Device Path.
+
+ UINT8 SubType; ///< Varies by Type
+ ///< 0xFF End Entire Device Path, or
+ ///< 0x01 End This Instance of a Device Path and start a new
+ ///< Device Path.
+
+ UINT8 Length[2]; ///< Specific Device Path data. Type and Sub-Type define
+ ///< type of data. Size of data is included in Length.
+
+} EFI_DEVICE_PATH_PROTOCOL;
+
+///
+/// Device Path protocol definition for backward-compatible with EFI1.1.
+///
+typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH;
+
+///
+/// Hardware Device Paths.
+///
+#define HARDWARE_DEVICE_PATH 0x01
+
+///
+/// PCI Device Path SubType.
+///
+#define HW_PCI_DP 0x01
+
+///
+/// PCI Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// PCI Function Number.
+ ///
+ UINT8 Function;
+ ///
+ /// PCI Device Number.
+ ///
+ UINT8 Device;
+} PCI_DEVICE_PATH;
+
+///
+/// PCCARD Device Path SubType.
+///
+#define HW_PCCARD_DP 0x02
+
+///
+/// PCCARD Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Function Number (0 = First Function).
+ ///
+ UINT8 FunctionNumber;
+} PCCARD_DEVICE_PATH;
+
+///
+/// Memory Mapped Device Path SubType.
+///
+#define HW_MEMMAP_DP 0x03
+
+///
+/// Memory Mapped Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// EFI_MEMORY_TYPE
+ ///
+ UINT32 MemoryType;
+ ///
+ /// Starting Memory Address.
+ ///
+ EFI_PHYSICAL_ADDRESS StartingAddress;
+ ///
+ /// Ending Memory Address.
+ ///
+ EFI_PHYSICAL_ADDRESS EndingAddress;
+} MEMMAP_DEVICE_PATH;
+
+///
+/// Hardware Vendor Device Path SubType.
+///
+#define HW_VENDOR_DP 0x04
+
+///
+/// The Vendor Device Path allows the creation of vendor-defined Device Paths. A vendor must
+/// allocate a Vendor GUID for a Device Path. The Vendor GUID can then be used to define the
+/// contents on the n bytes that follow in the Vendor Device Path node.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Vendor-assigned GUID that defines the data that follows.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// Vendor-defined variable size data.
+ ///
+} VENDOR_DEVICE_PATH;
+
+///
+/// Controller Device Path SubType.
+///
+#define HW_CONTROLLER_DP 0x05
+
+///
+/// Controller Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Controller number.
+ ///
+ UINT32 ControllerNumber;
+} CONTROLLER_DEVICE_PATH;
+
+///
+/// BMC Device Path SubType.
+///
+#define HW_BMC_DP 0x06
+
+///
+/// BMC Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Interface Type.
+ ///
+ UINT8 InterfaceType;
+ ///
+ /// Base Address.
+ ///
+ UINT8 BaseAddress[8];
+} BMC_DEVICE_PATH;
+
+///
+/// ACPI Device Paths.
+///
+#define ACPI_DEVICE_PATH 0x02
+
+///
+/// ACPI Device Path SubType.
+///
+#define ACPI_DP 0x01
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Device's PnP hardware ID stored in a numeric 32-bit
+ /// compressed EISA-type ID. This value must match the
+ /// corresponding _HID in the ACPI name space.
+ ///
+ UINT32 HID;
+ ///
+ /// Unique ID that is required by ACPI if two devices have the
+ /// same _HID. This value must also match the corresponding
+ /// _UID/_HID pair in the ACPI name space. Only the 32-bit
+ /// numeric value type of _UID is supported. Thus, strings must
+ /// not be used for the _UID in the ACPI name space.
+ ///
+ UINT32 UID;
+} ACPI_HID_DEVICE_PATH;
+
+///
+/// Expanded ACPI Device Path SubType.
+///
+#define ACPI_EXTENDED_DP 0x02
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Device's PnP hardware ID stored in a numeric 32-bit
+ /// compressed EISA-type ID. This value must match the
+ /// corresponding _HID in the ACPI name space.
+ ///
+ UINT32 HID;
+ ///
+ /// Unique ID that is required by ACPI if two devices have the
+ /// same _HID. This value must also match the corresponding
+ /// _UID/_HID pair in the ACPI name space.
+ ///
+ UINT32 UID;
+ ///
+ /// Device's compatible PnP hardware ID stored in a numeric
+ /// 32-bit compressed EISA-type ID. This value must match at
+ /// least one of the compatible device IDs returned by the
+ /// corresponding _CID in the ACPI name space.
+ ///
+ UINT32 CID;
+ ///
+ /// Optional variable length _HIDSTR.
+ /// Optional variable length _UIDSTR.
+ /// Optional variable length _CIDSTR.
+ ///
+} ACPI_EXTENDED_HID_DEVICE_PATH;
+
+//
+// EISA ID Macro
+// EISA ID Definition 32-bits
+// bits[15:0] - three character compressed ASCII EISA ID.
+// bits[31:16] - binary number
+// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
+//
+#define PNP_EISA_ID_CONST 0x41d0
+#define EISA_ID(_Name, _Num) ((UINT32)((_Name) | (_Num) << 16))
+#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+
+#define PNP_EISA_ID_MASK 0xffff
+#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16)
+
+///
+/// ACPI _ADR Device Path SubType.
+///
+#define ACPI_ADR_DP 0x03
+
+///
+/// The _ADR device path is used to contain video output device attributes to support the Graphics
+/// Output Protocol. The device path can contain multiple _ADR entries if multiple video output
+/// devices are displaying the same output.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// _ADR value. For video output devices the value of this
+ /// field comes from Table B-2 of the ACPI 3.0 specification. At
+ /// least one _ADR value is required.
+ ///
+ UINT32 ADR;
+ //
+ // This device path may optionally contain more than one _ADR entry.
+ //
+} ACPI_ADR_DEVICE_PATH;
+
+#define ACPI_ADR_DISPLAY_TYPE_OTHER 0
+#define ACPI_ADR_DISPLAY_TYPE_VGA 1
+#define ACPI_ADR_DISPLAY_TYPE_TV 2
+#define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL 3
+#define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL 4
+
+#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \
+ ((UINT32)( ((UINT32)((_DeviceIdScheme) & 0x1) << 31) | \
+ (((_HeadId) & 0x7) << 18) | \
+ (((_NonVgaOutput) & 0x1) << 17) | \
+ (((_BiosCanDetect) & 0x1) << 16) | \
+ (((_VendorInfo) & 0xf) << 12) | \
+ (((_Type) & 0xf) << 8) | \
+ (((_Port) & 0xf) << 4) | \
+ ((_Index) & 0xf) ))
+
+///
+/// Messaging Device Paths.
+/// This Device Path is used to describe the connection of devices outside the resource domain of the
+/// system. This Device Path can describe physical messaging information like SCSI ID, or abstract
+/// information like networking protocol IP addresses.
+///
+#define MESSAGING_DEVICE_PATH 0x03
+
+///
+/// ATAPI Device Path SubType
+///
+#define MSG_ATAPI_DP 0x01
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Set to zero for primary, or one for secondary.
+ ///
+ UINT8 PrimarySecondary;
+ ///
+ /// Set to zero for master, or one for slave mode.
+ ///
+ UINT8 SlaveMaster;
+ ///
+ /// Logical Unit Number.
+ ///
+ UINT16 Lun;
+} ATAPI_DEVICE_PATH;
+
+///
+/// SCSI Device Path SubType.
+///
+#define MSG_SCSI_DP 0x02
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Target ID on the SCSI bus (PUN).
+ ///
+ UINT16 Pun;
+ ///
+ /// Logical Unit Number (LUN).
+ ///
+ UINT16 Lun;
+} SCSI_DEVICE_PATH;
+
+///
+/// Fibre Channel SubType.
+///
+#define MSG_FIBRECHANNEL_DP 0x03
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Reserved for the future.
+ ///
+ UINT32 Reserved;
+ ///
+ /// Fibre Channel World Wide Number.
+ ///
+ UINT64 WWN;
+ ///
+ /// Fibre Channel Logical Unit Number.
+ ///
+ UINT64 Lun;
+} FIBRECHANNEL_DEVICE_PATH;
+
+///
+/// Fibre Channel Ex SubType.
+///
+#define MSG_FIBRECHANNELEX_DP 0x15
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Reserved for the future.
+ ///
+ UINT32 Reserved;
+ ///
+ /// 8 byte array containing Fibre Channel End Device Port Name.
+ ///
+ UINT8 WWN[8];
+ ///
+ /// 8 byte array containing Fibre Channel Logical Unit Number.
+ ///
+ UINT8 Lun[8];
+} FIBRECHANNELEX_DEVICE_PATH;
+
+///
+/// 1394 Device Path SubType
+///
+#define MSG_1394_DP 0x04
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Reserved for the future.
+ ///
+ UINT32 Reserved;
+ ///
+ /// 1394 Global Unique ID (GUID).
+ ///
+ UINT64 Guid;
+} F1394_DEVICE_PATH;
+
+///
+/// USB Device Path SubType.
+///
+#define MSG_USB_DP 0x05
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// USB Parent Port Number.
+ ///
+ UINT8 ParentPortNumber;
+ ///
+ /// USB Interface Number.
+ ///
+ UINT8 InterfaceNumber;
+} USB_DEVICE_PATH;
+
+///
+/// USB Class Device Path SubType.
+///
+#define MSG_USB_CLASS_DP 0x0f
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Vendor ID assigned by USB-IF. A value of 0xFFFF will
+ /// match any Vendor ID.
+ ///
+ UINT16 VendorId;
+ ///
+ /// Product ID assigned by USB-IF. A value of 0xFFFF will
+ /// match any Product ID.
+ ///
+ UINT16 ProductId;
+ ///
+ /// The class code assigned by the USB-IF. A value of 0xFF
+ /// will match any class code.
+ ///
+ UINT8 DeviceClass;
+ ///
+ /// The subclass code assigned by the USB-IF. A value of
+ /// 0xFF will match any subclass code.
+ ///
+ UINT8 DeviceSubClass;
+ ///
+ /// The protocol code assigned by the USB-IF. A value of
+ /// 0xFF will match any protocol code.
+ ///
+ UINT8 DeviceProtocol;
+} USB_CLASS_DEVICE_PATH;
+
+///
+/// USB WWID Device Path SubType.
+///
+#define MSG_USB_WWID_DP 0x10
+
+///
+/// This device path describes a USB device using its serial number.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// USB interface number.
+ ///
+ UINT16 InterfaceNumber;
+ ///
+ /// USB vendor id of the device.
+ ///
+ UINT16 VendorId;
+ ///
+ /// USB product id of the device.
+ ///
+ UINT16 ProductId;
+ ///
+ /// Last 64-or-fewer UTF-16 characters of the USB
+ /// serial number. The length of the string is
+ /// determined by the Length field less the offset of the
+ /// Serial Number field (10)
+ ///
+ /// CHAR16 SerialNumber[...];
+} USB_WWID_DEVICE_PATH;
+
+///
+/// Device Logical Unit SubType.
+///
+#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Logical Unit Number for the interface.
+ ///
+ UINT8 Lun;
+} DEVICE_LOGICAL_UNIT_DEVICE_PATH;
+
+///
+/// SATA Device Path SubType.
+///
+#define MSG_SATA_DP 0x12
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The HBA port number that facilitates the connection to the
+ /// device or a port multiplier. The value 0xFFFF is reserved.
+ ///
+ UINT16 HBAPortNumber;
+ ///
+ /// The Port multiplier port number that facilitates the connection
+ /// to the device. Must be set to 0xFFFF if the device is directly
+ /// connected to the HBA.
+ ///
+ UINT16 PortMultiplierPortNumber;
+ ///
+ /// Logical Unit Number.
+ ///
+ UINT16 Lun;
+} SATA_DEVICE_PATH;
+
+///
+/// Flag for if the device is directly connected to the HBA.
+///
+#define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000
+
+///
+/// I2O Device Path SubType.
+///
+#define MSG_I2O_DP 0x06
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Target ID (TID) for a device.
+ ///
+ UINT32 Tid;
+} I2O_DEVICE_PATH;
+
+///
+/// MAC Address Device Path SubType.
+///
+#define MSG_MAC_ADDR_DP 0x0b
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The MAC address for a network interface padded with 0s.
+ ///
+ EFI_MAC_ADDRESS MacAddress;
+ ///
+ /// Network interface type(i.e. 802.3, FDDI).
+ ///
+ UINT8 IfType;
+} MAC_ADDR_DEVICE_PATH;
+
+///
+/// IPv4 Device Path SubType
+///
+#define MSG_IPv4_DP 0x0c
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The local IPv4 address.
+ ///
+ EFI_IPv4_ADDRESS LocalIpAddress;
+ ///
+ /// The remote IPv4 address.
+ ///
+ EFI_IPv4_ADDRESS RemoteIpAddress;
+ ///
+ /// The local port number.
+ ///
+ UINT16 LocalPort;
+ ///
+ /// The remote port number.
+ ///
+ UINT16 RemotePort;
+ ///
+ /// The network protocol(i.e. UDP, TCP).
+ ///
+ UINT16 Protocol;
+ ///
+ /// 0x00 - The Source IP Address was assigned though DHCP.
+ /// 0x01 - The Source IP Address is statically bound.
+ ///
+ BOOLEAN StaticIpAddress;
+ ///
+ /// The gateway IP address
+ ///
+ EFI_IPv4_ADDRESS GatewayIpAddress;
+ ///
+ /// The subnet mask
+ ///
+ EFI_IPv4_ADDRESS SubnetMask;
+} IPv4_DEVICE_PATH;
+
+///
+/// IPv6 Device Path SubType.
+///
+#define MSG_IPv6_DP 0x0d
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The local IPv6 address.
+ ///
+ EFI_IPv6_ADDRESS LocalIpAddress;
+ ///
+ /// The remote IPv6 address.
+ ///
+ EFI_IPv6_ADDRESS RemoteIpAddress;
+ ///
+ /// The local port number.
+ ///
+ UINT16 LocalPort;
+ ///
+ /// The remote port number.
+ ///
+ UINT16 RemotePort;
+ ///
+ /// The network protocol(i.e. UDP, TCP).
+ ///
+ UINT16 Protocol;
+ ///
+ /// 0x00 - The Local IP Address was manually configured.
+ /// 0x01 - The Local IP Address is assigned through IPv6
+ /// stateless auto-configuration.
+ /// 0x02 - The Local IP Address is assigned through IPv6
+ /// stateful configuration.
+ ///
+ UINT8 IpAddressOrigin;
+ ///
+ /// The prefix length
+ ///
+ UINT8 PrefixLength;
+ ///
+ /// The gateway IP address
+ ///
+ EFI_IPv6_ADDRESS GatewayIpAddress;
+} IPv6_DEVICE_PATH;
+
+///
+/// InfiniBand Device Path SubType.
+///
+#define MSG_INFINIBAND_DP 0x09
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Flags to help identify/manage InfiniBand device path elements:
+ /// Bit 0 - IOC/Service (0b = IOC, 1b = Service).
+ /// Bit 1 - Extend Boot Environment.
+ /// Bit 2 - Console Protocol.
+ /// Bit 3 - Storage Protocol.
+ /// Bit 4 - Network Protocol.
+ /// All other bits are reserved.
+ ///
+ UINT32 ResourceFlags;
+ ///
+ /// 128-bit Global Identifier for remote fabric port.
+ ///
+ UINT8 PortGid[16];
+ ///
+ /// 64-bit unique identifier to remote IOC or server process.
+ /// Interpretation of field specified by Resource Flags (bit 0).
+ ///
+ UINT64 ServiceId;
+ ///
+ /// 64-bit persistent ID of remote IOC port.
+ ///
+ UINT64 TargetPortId;
+ ///
+ /// 64-bit persistent ID of remote device.
+ ///
+ UINT64 DeviceId;
+} INFINIBAND_DEVICE_PATH;
+
+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01
+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02
+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04
+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08
+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10
+
+///
+/// UART Device Path SubType.
+///
+#define MSG_UART_DP 0x0e
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Reserved.
+ ///
+ UINT32 Reserved;
+ ///
+ /// The baud rate setting for the UART style device. A value of 0
+ /// means that the device's default baud rate will be used.
+ ///
+ UINT64 BaudRate;
+ ///
+ /// The number of data bits for the UART style device. A value
+ /// of 0 means that the device's default number of data bits will be used.
+ ///
+ UINT8 DataBits;
+ ///
+ /// The parity setting for the UART style device.
+ /// Parity 0x00 - Default Parity.
+ /// Parity 0x01 - No Parity.
+ /// Parity 0x02 - Even Parity.
+ /// Parity 0x03 - Odd Parity.
+ /// Parity 0x04 - Mark Parity.
+ /// Parity 0x05 - Space Parity.
+ ///
+ UINT8 Parity;
+ ///
+ /// The number of stop bits for the UART style device.
+ /// Stop Bits 0x00 - Default Stop Bits.
+ /// Stop Bits 0x01 - 1 Stop Bit.
+ /// Stop Bits 0x02 - 1.5 Stop Bits.
+ /// Stop Bits 0x03 - 2 Stop Bits.
+ ///
+ UINT8 StopBits;
+} UART_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MSG_VENDOR_DP 0x0a
+typedef VENDOR_DEVICE_PATH VENDOR_DEFINED_DEVICE_PATH;
+
+#define DEVICE_PATH_MESSAGING_PC_ANSI EFI_PC_ANSI_GUID
+#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID
+#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID
+#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID
+
+///
+/// A new device path node is defined to declare flow control characteristics.
+/// UART Flow Control Messaging Device Path
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// Bitmap of supported flow control types.
+ /// Bit 0 set indicates hardware flow control.
+ /// Bit 1 set indicates Xon/Xoff flow control.
+ /// All other bits are reserved and are clear.
+ ///
+ UINT32 FlowControlMap;
+} UART_FLOW_CONTROL_DEVICE_PATH;
+
+#define UART_FLOW_CONTROL_HARDWARE 0x00000001
+#define UART_FLOW_CONTROL_XON_XOFF 0x00000010
+
+#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID
+///
+/// Serial Attached SCSI (SAS) Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// DEVICE_PATH_MESSAGING_SAS GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// Reserved for future use.
+ ///
+ UINT32 Reserved;
+ ///
+ /// SAS Address for Serial Attached SCSI Target.
+ ///
+ UINT64 SasAddress;
+ ///
+ /// SAS Logical Unit Number.
+ ///
+ UINT64 Lun;
+ ///
+ /// More Information about the device and its interconnect.
+ ///
+ UINT16 DeviceTopology;
+ ///
+ /// Relative Target Port (RTP).
+ ///
+ UINT16 RelativeTargetPort;
+} SAS_DEVICE_PATH;
+
+///
+/// Serial Attached SCSI (SAS) Ex Device Path SubType
+///
+#define MSG_SASEX_DP 0x16
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// 8-byte array of the SAS Address for Serial Attached SCSI Target Port.
+ ///
+ UINT8 SasAddress[8];
+ ///
+ /// 8-byte array of the SAS Logical Unit Number.
+ ///
+ UINT8 Lun[8];
+ ///
+ /// More Information about the device and its interconnect.
+ ///
+ UINT16 DeviceTopology;
+ ///
+ /// Relative Target Port (RTP).
+ ///
+ UINT16 RelativeTargetPort;
+} SASEX_DEVICE_PATH;
+
+///
+/// NvmExpress Namespace Device Path SubType.
+///
+#define MSG_NVME_NAMESPACE_DP 0x17
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 NamespaceId;
+ UINT64 NamespaceUuid;
+} NVME_NAMESPACE_DEVICE_PATH;
+
+///
+/// DNS Device Path SubType
+///
+#define MSG_DNS_DP 0x1F
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Indicates the DNS server address is IPv4 or IPv6 address.
+ ///
+ UINT8 IsIPv6;
+ ///
+ /// Instance of the DNS server address.
+ ///
+ EFI_IP_ADDRESS DnsServerIp[1024];
+} DNS_DEVICE_PATH;
+
+///
+/// Uniform Resource Identifiers (URI) Device Path SubType
+///
+#define MSG_URI_DP 0x18
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Instance of the URI pursuant to RFC 3986.
+ ///
+ CHAR8 Uri[1024];
+} URI_DEVICE_PATH;
+
+///
+/// Universal Flash Storage (UFS) Device Path SubType.
+///
+#define MSG_UFS_DP 0x19
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Target ID on the UFS bus (PUN).
+ ///
+ UINT8 Pun;
+ ///
+ /// Logical Unit Number (LUN).
+ ///
+ UINT8 Lun;
+} UFS_DEVICE_PATH;
+
+///
+/// SD (Secure Digital) Device Path SubType.
+///
+#define MSG_SD_DP 0x1A
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 SlotNumber;
+} SD_DEVICE_PATH;
+
+///
+/// EMMC (Embedded MMC) Device Path SubType.
+///
+#define MSG_EMMC_DP 0x1D
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 SlotNumber;
+} EMMC_DEVICE_PATH;
+
+///
+/// iSCSI Device Path SubType
+///
+#define MSG_ISCSI_DP 0x13
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Network Protocol (0 = TCP, 1+ = reserved).
+ ///
+ UINT16 NetworkProtocol;
+ ///
+ /// iSCSI Login Options.
+ ///
+ UINT16 LoginOption;
+ ///
+ /// iSCSI Logical Unit Number.
+ ///
+ UINT64 Lun;
+ ///
+ /// iSCSI Target Portal group tag the initiator intends
+ /// to establish a session with.
+ ///
+ UINT16 TargetPortalGroupTag;
+ ///
+ /// iSCSI NodeTarget Name. The length of the name
+ /// is determined by subtracting the offset of this field from Length.
+ ///
+ /// CHAR8 iSCSI Target Name.
+} ISCSI_DEVICE_PATH;
+
+#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST 0x0000
+#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C 0x0002
+#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST 0x0000
+#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C 0x0008
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP 0x0000
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON 0x1000
+#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000
+#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000
+
+///
+/// VLAN Device Path SubType.
+///
+#define MSG_VLAN_DP 0x14
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// VLAN identifier (0-4094).
+ ///
+ UINT16 VlanId;
+} VLAN_DEVICE_PATH;
+
+///
+/// BLUETOOTH_ADDRESS
+///
+typedef struct {
+ ///
+ /// 48bit Bluetooth device address.
+ ///
+ UINT8 Address[6];
+} BLUETOOTH_ADDRESS;
+
+///
+/// Bluetooth Device Path SubType.
+///
+#define MSG_BLUETOOTH_DP 0x1b
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// 48bit Bluetooth device address.
+ ///
+ BLUETOOTH_ADDRESS BD_ADDR;
+} BLUETOOTH_DEVICE_PATH;
+
+///
+/// Wi-Fi Device Path SubType.
+///
+#define MSG_WIFI_DP 0x1C
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Service set identifier. A 32-byte octets string.
+ ///
+ UINT8 SSId[32];
+} WIFI_DEVICE_PATH;
+
+///
+/// BLUETOOTH_LE_ADDRESS
+///
+typedef struct {
+ ///
+ /// 48-bit Bluetooth device address
+ ///
+ UINT8 Address[6];
+ ///
+ /// 0x00 - Public Device Address
+ /// 0x01 - Random Device Address
+ ///
+ UINT8 Type;
+} BLUETOOTH_LE_ADDRESS;
+
+///
+/// Bluetooth LE Device Path SubType.
+///
+#define MSG_BLUETOOTH_LE_DP 0x1E
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ BLUETOOTH_LE_ADDRESS Address;
+} BLUETOOTH_LE_DEVICE_PATH;
+
+//
+// Media Device Path
+//
+#define MEDIA_DEVICE_PATH 0x04
+
+///
+/// Hard Drive Media Device Path SubType.
+///
+#define MEDIA_HARDDRIVE_DP 0x01
+
+///
+/// The Hard Drive Media Device Path is used to represent a partition on a hard drive.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Describes the entry in a partition table, starting with entry 1.
+ /// Partition number zero represents the entire device. Valid
+ /// partition numbers for a MBR partition are [1, 4]. Valid
+ /// partition numbers for a GPT partition are [1, NumberOfPartitionEntries].
+ ///
+ UINT32 PartitionNumber;
+ ///
+ /// Starting LBA of the partition on the hard drive.
+ ///
+ UINT64 PartitionStart;
+ ///
+ /// Size of the partition in units of Logical Blocks.
+ ///
+ UINT64 PartitionSize;
+ ///
+ /// Signature unique to this partition:
+ /// If SignatureType is 0, this field has to be initialized with 16 zeros.
+ /// If SignatureType is 1, the MBR signature is stored in the first 4 bytes of this field.
+ /// The other 12 bytes are initialized with zeros.
+ /// If SignatureType is 2, this field contains a 16 byte signature.
+ ///
+ UINT8 Signature[16];
+ ///
+ /// Partition Format: (Unused values reserved).
+ /// 0x01 - PC-AT compatible legacy MBR.
+ /// 0x02 - GUID Partition Table.
+ ///
+ UINT8 MBRType;
+ ///
+ /// Type of Disk Signature: (Unused values reserved).
+ /// 0x00 - No Disk Signature.
+ /// 0x01 - 32-bit signature from address 0x1b8 of the type 0x01 MBR.
+ /// 0x02 - GUID signature.
+ ///
+ UINT8 SignatureType;
+} HARDDRIVE_DEVICE_PATH;
+
+#define MBR_TYPE_PCAT 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define NO_DISK_SIGNATURE 0x00
+#define SIGNATURE_TYPE_MBR 0x01
+#define SIGNATURE_TYPE_GUID 0x02
+
+///
+/// CD-ROM Media Device Path SubType.
+///
+#define MEDIA_CDROM_DP 0x02
+
+///
+/// The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Boot Entry number from the Boot Catalog. The Initial/Default entry is defined as zero.
+ ///
+ UINT32 BootEntry;
+ ///
+ /// Starting RBA of the partition on the medium. CD-ROMs use Relative logical Block Addressing.
+ ///
+ UINT64 PartitionStart;
+ ///
+ /// Size of the partition in units of Blocks, also called Sectors.
+ ///
+ UINT64 PartitionSize;
+} CDROM_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MEDIA_VENDOR_DP 0x03 ///< Media vendor device path subtype.
+
+///
+/// File Path Media Device Path SubType
+///
+#define MEDIA_FILEPATH_DP 0x04
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// A NULL-terminated Path string including directory and file names.
+ ///
+ CHAR16 PathName[1];
+} FILEPATH_DEVICE_PATH;
+
+#define SIZE_OF_FILEPATH_DEVICE_PATH OFFSET_OF(FILEPATH_DEVICE_PATH,PathName)
+
+///
+/// Media Protocol Device Path SubType.
+///
+#define MEDIA_PROTOCOL_DP 0x05
+
+///
+/// The Media Protocol Device Path is used to denote the protocol that is being
+/// used in a device path at the location of the path specified.
+/// Many protocols are inherent to the style of device path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The ID of the protocol.
+ ///
+ EFI_GUID Protocol;
+} MEDIA_PROTOCOL_DEVICE_PATH;
+
+///
+/// PIWG Firmware File SubType.
+///
+#define MEDIA_PIWG_FW_FILE_DP 0x06
+
+///
+/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware file.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Firmware file name
+ ///
+ EFI_GUID FvFileName;
+} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;
+
+///
+/// PIWG Firmware Volume Device Path SubType.
+///
+#define MEDIA_PIWG_FW_VOL_DP 0x07
+
+///
+/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware volume.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Firmware volume name.
+ ///
+ EFI_GUID FvName;
+} MEDIA_FW_VOL_DEVICE_PATH;
+
+///
+/// Media relative offset range device path.
+///
+#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08
+
+///
+/// Used to describe the offset range of media relative.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Reserved;
+ UINT64 StartingOffset;
+ UINT64 EndingOffset;
+} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;
+
+///
+/// This GUID defines a RAM Disk supporting a raw disk format in volatile memory.
+///
+#define EFI_VIRTUAL_DISK_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE
+
+extern EFI_GUID gEfiVirtualDiskGuid;
+
+///
+/// This GUID defines a RAM Disk supporting an ISO image in volatile memory.
+///
+#define EFI_VIRTUAL_CD_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE
+
+extern EFI_GUID gEfiVirtualCdGuid;
+
+///
+/// This GUID defines a RAM Disk supporting a raw disk format in persistent memory.
+///
+#define EFI_PERSISTENT_VIRTUAL_DISK_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT
+
+extern EFI_GUID gEfiPersistentVirtualDiskGuid;
+
+///
+/// This GUID defines a RAM Disk supporting an ISO image in persistent memory.
+///
+#define EFI_PERSISTENT_VIRTUAL_CD_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT
+
+extern EFI_GUID gEfiPersistentVirtualCdGuid;
+
+///
+/// Media ram disk device path.
+///
+#define MEDIA_RAM_DISK_DP 0x09
+
+///
+/// Used to describe the ram disk device path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Starting Memory Address.
+ ///
+ UINT32 StartingAddr[2];
+ ///
+ /// Ending Memory Address.
+ ///
+ UINT32 EndingAddr[2];
+ ///
+ /// GUID that defines the type of the RAM Disk.
+ ///
+ EFI_GUID TypeGuid;
+ ///
+ /// RAM Diskinstance number, if supported. The default value is zero.
+ ///
+ UINT16 Instance;
+} MEDIA_RAM_DISK_DEVICE_PATH;
+
+///
+/// BIOS Boot Specification Device Path.
+///
+#define BBS_DEVICE_PATH 0x05
+
+///
+/// BIOS Boot Specification Device Path SubType.
+///
+#define BBS_BBS_DP 0x01
+
+///
+/// This Device Path is used to describe the booting of non-EFI-aware operating systems.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Device Type as defined by the BIOS Boot Specification.
+ ///
+ UINT16 DeviceType;
+ ///
+ /// Status Flags as defined by the BIOS Boot Specification.
+ ///
+ UINT16 StatusFlag;
+ ///
+ /// Null-terminated ASCII string that describes the boot device to a user.
+ ///
+ CHAR8 String[1];
+} BBS_BBS_DEVICE_PATH;
+
+//
+// DeviceType definitions - from BBS specification
+//
+#define BBS_TYPE_FLOPPY 0x01
+#define BBS_TYPE_HARDDRIVE 0x02
+#define BBS_TYPE_CDROM 0x03
+#define BBS_TYPE_PCMCIA 0x04
+#define BBS_TYPE_USB 0x05
+#define BBS_TYPE_EMBEDDED_NETWORK 0x06
+#define BBS_TYPE_BEV 0x80
+#define BBS_TYPE_UNKNOWN 0xFF
+
+
+///
+/// Union of all possible Device Paths and pointers to Device Paths.
+///
+typedef union {
+ EFI_DEVICE_PATH_PROTOCOL DevPath;
+ PCI_DEVICE_PATH Pci;
+ PCCARD_DEVICE_PATH PcCard;
+ MEMMAP_DEVICE_PATH MemMap;
+ VENDOR_DEVICE_PATH Vendor;
+
+ CONTROLLER_DEVICE_PATH Controller;
+ BMC_DEVICE_PATH Bmc;
+ ACPI_HID_DEVICE_PATH Acpi;
+ ACPI_EXTENDED_HID_DEVICE_PATH ExtendedAcpi;
+ ACPI_ADR_DEVICE_PATH AcpiAdr;
+
+ ATAPI_DEVICE_PATH Atapi;
+ SCSI_DEVICE_PATH Scsi;
+ ISCSI_DEVICE_PATH Iscsi;
+ FIBRECHANNEL_DEVICE_PATH FibreChannel;
+ FIBRECHANNELEX_DEVICE_PATH FibreChannelEx;
+
+ F1394_DEVICE_PATH F1394;
+ USB_DEVICE_PATH Usb;
+ SATA_DEVICE_PATH Sata;
+ USB_CLASS_DEVICE_PATH UsbClass;
+ USB_WWID_DEVICE_PATH UsbWwid;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH LogicUnit;
+ I2O_DEVICE_PATH I2O;
+ MAC_ADDR_DEVICE_PATH MacAddr;
+ IPv4_DEVICE_PATH Ipv4;
+ IPv6_DEVICE_PATH Ipv6;
+ VLAN_DEVICE_PATH Vlan;
+ INFINIBAND_DEVICE_PATH InfiniBand;
+ UART_DEVICE_PATH Uart;
+ UART_FLOW_CONTROL_DEVICE_PATH UartFlowControl;
+ SAS_DEVICE_PATH Sas;
+ SASEX_DEVICE_PATH SasEx;
+ NVME_NAMESPACE_DEVICE_PATH NvmeNamespace;
+ DNS_DEVICE_PATH Dns;
+ URI_DEVICE_PATH Uri;
+ BLUETOOTH_DEVICE_PATH Bluetooth;
+ WIFI_DEVICE_PATH WiFi;
+ UFS_DEVICE_PATH Ufs;
+ SD_DEVICE_PATH Sd;
+ EMMC_DEVICE_PATH Emmc;
+ HARDDRIVE_DEVICE_PATH HardDrive;
+ CDROM_DEVICE_PATH CD;
+
+ FILEPATH_DEVICE_PATH FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;
+
+ MEDIA_FW_VOL_DEVICE_PATH FirmwareVolume;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FirmwareFile;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH Offset;
+ MEDIA_RAM_DISK_DEVICE_PATH RamDisk;
+ BBS_BBS_DEVICE_PATH Bbs;
+} EFI_DEV_PATH;
+
+
+
+typedef union {
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ PCI_DEVICE_PATH *Pci;
+ PCCARD_DEVICE_PATH *PcCard;
+ MEMMAP_DEVICE_PATH *MemMap;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ CONTROLLER_DEVICE_PATH *Controller;
+ BMC_DEVICE_PATH *Bmc;
+ ACPI_HID_DEVICE_PATH *Acpi;
+ ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
+ ACPI_ADR_DEVICE_PATH *AcpiAdr;
+
+ ATAPI_DEVICE_PATH *Atapi;
+ SCSI_DEVICE_PATH *Scsi;
+ ISCSI_DEVICE_PATH *Iscsi;
+ FIBRECHANNEL_DEVICE_PATH *FibreChannel;
+ FIBRECHANNELEX_DEVICE_PATH *FibreChannelEx;
+
+ F1394_DEVICE_PATH *F1394;
+ USB_DEVICE_PATH *Usb;
+ SATA_DEVICE_PATH *Sata;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicUnit;
+ I2O_DEVICE_PATH *I2O;
+ MAC_ADDR_DEVICE_PATH *MacAddr;
+ IPv4_DEVICE_PATH *Ipv4;
+ IPv6_DEVICE_PATH *Ipv6;
+ VLAN_DEVICE_PATH *Vlan;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+ UART_DEVICE_PATH *Uart;
+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+ SAS_DEVICE_PATH *Sas;
+ SASEX_DEVICE_PATH *SasEx;
+ NVME_NAMESPACE_DEVICE_PATH *NvmeNamespace;
+ DNS_DEVICE_PATH *Dns;
+ URI_DEVICE_PATH *Uri;
+ BLUETOOTH_DEVICE_PATH *Bluetooth;
+ WIFI_DEVICE_PATH *WiFi;
+ UFS_DEVICE_PATH *Ufs;
+ SD_DEVICE_PATH *Sd;
+ EMMC_DEVICE_PATH *Emmc;
+ HARDDRIVE_DEVICE_PATH *HardDrive;
+ CDROM_DEVICE_PATH *CD;
+
+ FILEPATH_DEVICE_PATH *FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol;
+
+ MEDIA_FW_VOL_DEVICE_PATH *FirmwareVolume;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FirmwareFile;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ BBS_BBS_DEVICE_PATH *Bbs;
+ UINT8 *Raw;
+} EFI_DEV_PATH_PTR;
+
+#define EFI_DEBUGPORT_PROTOCOL_GUID \
+ { \
+ 0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \
+ }
+//
+// DEBUGPORT variable definitions...
+//
+#define EFI_DEBUGPORT_VARIABLE_NAME L"DEBUGPORT"
+#define EFI_DEBUGPORT_VARIABLE_GUID EFI_DEBUGPORT_PROTOCOL_GUID
+extern EFI_GUID gEfiDebugPortVariableGuid;
+
+//
+// DebugPort device path definitions...
+//
+#define DEVICE_PATH_MESSAGING_DEBUGPORT EFI_DEBUGPORT_PROTOCOL_GUID
+extern EFI_GUID gEfiDebugPortDevicePathGuid;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+} DEBUGPORT_DEVICE_PATH;
+
+#pragma pack()
+
+#define END_DEVICE_PATH_TYPE 0x7f
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+
+extern EFI_GUID gEfiDevicePathProtocolGuid;
+
+#endif
diff --git a/BaseTools/Source/C/DevicePath/DevicePathFromText.c b/BaseTools/Source/C/DevicePath/DevicePathFromText.c
new file mode 100644
index 0000000..fb5b09b
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.c
@@ -0,0 +1,3503 @@
+/** @file
+ DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UefiDevicePathLib.h"
+
+/**
+
+ Duplicates a string.
+
+ @param Src Source string.
+
+ @return The duplicated string.
+
+**/
+CHAR16 *
+UefiDevicePathLibStrDuplicate (
+ CONST CHAR16 *Src
+ )
+{
+ return AllocateCopyPool (StrSize (Src), Src);
+}
+
+/**
+
+ Get parameter in a pair of parentheses follow the given node name.
+ For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
+
+ @param Str Device Path Text.
+ @param NodeName Name of the node.
+
+ @return Parameter text for the node.
+
+**/
+CHAR16 *
+GetParamByNodeName (
+ CHAR16 *Str,
+ CHAR16 *NodeName
+ )
+{
+ CHAR16 *ParamStr;
+ CHAR16 *StrPointer;
+ UINTN NodeNameLength;
+ UINTN ParameterLength;
+
+ //
+ // Check whether the node name matchs
+ //
+ NodeNameLength = StrLen (NodeName);
+ if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {
+ return NULL;
+ }
+
+ ParamStr = Str + NodeNameLength;
+ if (!IS_LEFT_PARENTH (*ParamStr)) {
+ return NULL;
+ }
+
+ //
+ // Skip the found '(' and find first occurrence of ')'
+ //
+ ParamStr++;
+ ParameterLength = 0;
+ StrPointer = ParamStr;
+ while (!IS_NULL (*StrPointer)) {
+ if (IS_RIGHT_PARENTH (*StrPointer)) {
+ break;
+ }
+ StrPointer++;
+ ParameterLength++;
+ }
+ if (IS_NULL (*StrPointer)) {
+ //
+ // ')' not found
+ //
+ return NULL;
+ }
+
+ ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
+ if (ParamStr == NULL) {
+ return NULL;
+ }
+ //
+ // Terminate the parameter string
+ //
+ ParamStr[ParameterLength] = L'\0';
+
+ return ParamStr;
+}
+
+/**
+ Gets current sub-string from a string list, before return
+ the list header is moved to next sub-string. The sub-string is separated
+ by the specified character. For example, the separator is ',', the string
+ list is "2,0,3", it returns "2", the remain list move to "0,3"
+
+ @param List A string list separated by the specified separator
+ @param Separator The separator character
+
+ @return A pointer to the current sub-string
+
+**/
+CHAR16 *
+SplitStr (
+ CHAR16 **List,
+ CHAR16 Separator
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+
+ Str = *List;
+ ReturnStr = Str;
+
+ if (IS_NULL (*Str)) {
+ return ReturnStr;
+ }
+
+ //
+ // Find first occurrence of the separator
+ //
+ while (!IS_NULL (*Str)) {
+ if (*Str == Separator) {
+ break;
+ }
+ Str++;
+ }
+
+ if (*Str == Separator) {
+ //
+ // Find a sub-string, terminate it
+ //
+ *Str = L'\0';
+ Str++;
+ }
+
+ //
+ // Move to next sub-string
+ //
+ *List = Str;
+ return ReturnStr;
+}
+
+/**
+ Gets the next parameter string from the list.
+
+ @param List A string list separated by the specified separator
+
+ @return A pointer to the current sub-string
+
+**/
+CHAR16 *
+GetNextParamStr (
+ CHAR16 **List
+ )
+{
+ //
+ // The separator is comma
+ //
+ return SplitStr (List, L',');
+}
+
+/**
+ Get one device node from entire device path text.
+
+ @param DevicePath On input, the current Device Path node; on output, the next device path node
+ @param IsInstanceEnd This node is the end of a device path instance
+
+ @return A device node text or NULL if no more device node available
+
+**/
+CHAR16 *
+GetNextDeviceNodeStr (
+ CHAR16 **DevicePath,
+ BOOLEAN *IsInstanceEnd
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+ UINTN ParenthesesStack;
+
+ Str = *DevicePath;
+ if (IS_NULL (*Str)) {
+ return NULL;
+ }
+
+ //
+ // Skip the leading '/', '(', ')' and ','
+ //
+ while (!IS_NULL (*Str)) {
+ if (!IS_SLASH (*Str) &&
+ !IS_COMMA (*Str) &&
+ !IS_LEFT_PARENTH (*Str) &&
+ !IS_RIGHT_PARENTH (*Str)) {
+ break;
+ }
+ Str++;
+ }
+
+ ReturnStr = Str;
+
+ //
+ // Scan for the separator of this device node, '/' or ','
+ //
+ ParenthesesStack = 0;
+ while (!IS_NULL (*Str)) {
+ if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {
+ break;
+ }
+
+ if (IS_LEFT_PARENTH (*Str)) {
+ ParenthesesStack++;
+ } else if (IS_RIGHT_PARENTH (*Str)) {
+ ParenthesesStack--;
+ }
+
+ Str++;
+ }
+
+ if (ParenthesesStack != 0) {
+ //
+ // The '(' doesn't pair with ')', invalid device path text
+ //
+ return NULL;
+ }
+
+ if (IS_COMMA (*Str)) {
+ *IsInstanceEnd = TRUE;
+ *Str = L'\0';
+ Str++;
+ } else {
+ *IsInstanceEnd = FALSE;
+ if (!IS_NULL (*Str)) {
+ *Str = L'\0';
+ Str++;
+ }
+ }
+
+ *DevicePath = Str;
+
+ return ReturnStr;
+}
+
+
+/**
+ Return whether the integer string is a hex string.
+
+ @param Str The integer string
+
+ @retval TRUE Hex string
+ @retval FALSE Decimal string
+
+**/
+BOOLEAN
+IsHexStr (
+ CHAR16 *Str
+ )
+{
+ //
+ // skip preceeding white space
+ //
+ while ((*Str != 0) && *Str == L' ') {
+ Str ++;
+ }
+ //
+ // skip preceeding zeros
+ //
+ while ((*Str != 0) && *Str == L'0') {
+ Str ++;
+ }
+
+ return (BOOLEAN) (*Str == L'x' || *Str == L'X');
+}
+
+/**
+
+ Convert integer string to uint.
+
+ @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
+
+ @return A UINTN value represented by Str
+
+**/
+UINTN
+Strtoi (
+ CHAR16 *Str
+ )
+{
+ if (IsHexStr (Str)) {
+ return StrHexToUintn (Str);
+ } else {
+ return StrDecimalToUintn (Str);
+ }
+}
+
+/**
+
+ Convert integer string to 64 bit data.
+
+ @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
+ @param Data A pointer to the UINT64 value represented by Str
+
+**/
+VOID
+Strtoi64 (
+ CHAR16 *Str,
+ UINT64 *Data
+ )
+{
+ if (IsHexStr (Str)) {
+ *Data = StrHexToUint64 (Str);
+ } else {
+ *Data = StrDecimalToUint64 (Str);
+ }
+}
+
+/**
+ Converts a Unicode string to ASCII string.
+
+ @param Str The equivalent Unicode string
+ @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
+ to the next ASCII string next to it
+
+**/
+VOID
+StrToAscii (
+ CHAR16 *Str,
+ CHAR8 **AsciiStr
+ )
+{
+ CHAR8 *Dest;
+
+ Dest = *AsciiStr;
+ while (!IS_NULL (*Str)) {
+ *(Dest++) = (CHAR8) *(Str++);
+ }
+ *Dest = 0;
+
+ //
+ // Return the string next to it
+ //
+ *AsciiStr = Dest + 1;
+}
+
+/**
+ Converts a generic text device path node to device path structure.
+
+ @param Type The type of the device path node.
+ @param TextDeviceNode The input text device path node.
+
+ @return A pointer to device path structure.
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextGenericPath (
+ UINT8 Type,
+ CHAR16 *TextDeviceNode
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+ CHAR16 *SubtypeStr;
+ CHAR16 *DataStr;
+ UINTN DataLength;
+
+ SubtypeStr = GetNextParamStr (&TextDeviceNode);
+ DataStr = GetNextParamStr (&TextDeviceNode);
+
+ if (DataStr == NULL) {
+ DataLength = 0;
+ } else {
+ DataLength = StrLen (DataStr) / 2;
+ }
+ Node = CreateDeviceNode (
+ Type,
+ (UINT8) Strtoi (SubtypeStr),
+ (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength)
+ );
+
+ StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength);
+ return Node;
+}
+
+/**
+ Converts a generic text device path node to device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+
+ return DevPathFromTextGenericPath ((UINT8) Strtoi (TypeStr), TextDeviceNode);
+}
+
+/**
+ Converts a generic hardware text device path node to Hardware device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHardwarePath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to Hardware PCI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware PCI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPci (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionStr;
+ CHAR16 *DeviceStr;
+ PCI_DEVICE_PATH *Pci;
+
+ DeviceStr = GetNextParamStr (&TextDeviceNode);
+ FunctionStr = GetNextParamStr (&TextDeviceNode);
+ Pci = (PCI_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCI_DP,
+ (UINT16) sizeof (PCI_DEVICE_PATH)
+ );
+
+ Pci->Function = (UINT8) Strtoi (FunctionStr);
+ Pci->Device = (UINT8) Strtoi (DeviceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
+}
+
+/**
+ Converts a text device path node to Hardware PC card device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware PC card device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcCard (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionNumberStr;
+ PCCARD_DEVICE_PATH *Pccard;
+
+ FunctionNumberStr = GetNextParamStr (&TextDeviceNode);
+ Pccard = (PCCARD_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCCARD_DP,
+ (UINT16) sizeof (PCCARD_DEVICE_PATH)
+ );
+
+ Pccard->FunctionNumber = (UINT8) Strtoi (FunctionNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
+}
+
+/**
+ Converts a text device path node to Hardware memory map device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware memory map device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMemoryMapped (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *MemoryTypeStr;
+ CHAR16 *StartingAddressStr;
+ CHAR16 *EndingAddressStr;
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemoryTypeStr = GetNextParamStr (&TextDeviceNode);
+ StartingAddressStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddressStr = GetNextParamStr (&TextDeviceNode);
+ MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ (UINT16) sizeof (MEMMAP_DEVICE_PATH)
+ );
+
+ MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr);
+ Strtoi64 (StartingAddressStr, &MemMap->StartingAddress);
+ Strtoi64 (EndingAddressStr, &MemMap->EndingAddress);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
+}
+
+/**
+ Converts a text device path node to Vendor device path structure based on the input Type
+ and SubType.
+
+ @param TextDeviceNode The input Text device path node.
+ @param Type The type of device path node.
+ @param SubType The subtype of device path node.
+
+ @return A pointer to the newly-created Vendor device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextVendor (
+ CHAR16 *TextDeviceNode,
+ UINT8 Type,
+ UINT8 SubType
+ )
+{
+ CHAR16 *GuidStr;
+ CHAR16 *DataStr;
+ UINTN Length;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+
+ DataStr = GetNextParamStr (&TextDeviceNode);
+ Length = StrLen (DataStr);
+ //
+ // Two hex characters make up 1 buffer byte
+ //
+ Length = (Length + 1) / 2;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ Type,
+ SubType,
+ (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length)
+ );
+
+ StrToGuid (GuidStr, &Vendor->Guid);
+ StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor Hardware device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor Hardware device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenHw (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to Hardware Controller device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Hardware Controller device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCtrl (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ControllerStr;
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ ControllerStr = GetNextParamStr (&TextDeviceNode);
+ Controller = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_CONTROLLER_DP,
+ (UINT16) sizeof (CONTROLLER_DEVICE_PATH)
+ );
+ Controller->ControllerNumber = (UINT32) Strtoi (ControllerStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
+}
+
+/**
+ Converts a text device path node to BMC device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created BMC device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBmc (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *InterfaceTypeStr;
+ CHAR16 *BaseAddressStr;
+ BMC_DEVICE_PATH *BmcDp;
+
+ InterfaceTypeStr = GetNextParamStr (&TextDeviceNode);
+ BaseAddressStr = GetNextParamStr (&TextDeviceNode);
+ BmcDp = (BMC_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_BMC_DP,
+ (UINT16) sizeof (BMC_DEVICE_PATH)
+ );
+
+ BmcDp->InterfaceType = (UINT8) Strtoi (InterfaceTypeStr);
+ WriteUnaligned64 (
+ (UINT64 *) (&BmcDp->BaseAddress),
+ StrHexToUint64 (BaseAddressStr)
+ );
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) BmcDp;
+}
+
+/**
+ Converts a generic ACPI text device path node to ACPI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to ACPI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiPath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a string to EisaId.
+
+ @param Text The input string.
+
+ @return UINT32 EISA ID.
+**/
+UINT32
+EisaIdFromText (
+ CHAR16 *Text
+ )
+{
+ return (((Text[0] - 'A' + 1) & 0x1f) << 10)
+ + (((Text[1] - 'A' + 1) & 0x1f) << 5)
+ + (((Text[2] - 'A' + 1) & 0x1f) << 0)
+ + (UINT32) (StrHexToUintn (&Text[3]) << 16)
+ ;
+}
+
+/**
+ Converts a text device path node to ACPI HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpi (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = EisaIdFromText (HIDStr);
+ Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+ Converts a text device path node to ACPI HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+ @param PnPId The input plug and play identification.
+
+ @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextAcpi (
+ CHAR16 *TextDeviceNode,
+ UINT32 PnPId
+ )
+{
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = EFI_PNP_ID (PnPId);
+ Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+ Converts a text device path node to PCI root device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created PCI root device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPciRoot (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a03);
+}
+
+/**
+ Converts a text device path node to PCIE root device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created PCIE root device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcieRoot (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a08);
+}
+
+/**
+ Converts a text device path node to Floppy device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Floppy device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFloppy (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0604);
+}
+
+/**
+ Converts a text device path node to Keyboard device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Keyboard device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextKeyboard (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0301);
+}
+
+/**
+ Converts a text device path node to Serial device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSerial (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0501);
+}
+
+/**
+ Converts a text device path node to Parallel Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextParallelPort (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0401);
+}
+
+/**
+ Converts a text device path node to ACPI extension device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiEx (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDStr;
+ CHAR16 *HIDSTRStr;
+ CHAR16 *CIDSTRStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ HIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ CIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+
+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1);
+ Length = (UINT16) (Length + StrLen (UIDSTRStr) + 1);
+ Length = (UINT16) (Length + StrLen (CIDSTRStr) + 1);
+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ AcpiEx->HID = EisaIdFromText (HIDStr);
+ AcpiEx->CID = EisaIdFromText (CIDStr);
+ AcpiEx->UID = (UINT32) Strtoi (UIDStr);
+
+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ StrToAscii (HIDSTRStr, &AsciiStr);
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ StrToAscii (CIDSTRStr, &AsciiStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+ Converts a text device path node to ACPI extension device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiExp (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3);
+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ AcpiEx->HID = EisaIdFromText (HIDStr);
+ AcpiEx->CID = EisaIdFromText (CIDStr);
+ AcpiEx->UID = 0;
+
+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ //
+ // HID string is NULL
+ //
+ *AsciiStr = '\0';
+ //
+ // Convert UID string
+ //
+ AsciiStr++;
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ //
+ // CID string is NULL
+ //
+ *AsciiStr = '\0';
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+ Converts a text device path node to ACPI _ADR device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI _ADR device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiAdr (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *DisplayDeviceStr;
+ ACPI_ADR_DEVICE_PATH *AcpiAdr;
+ UINTN Index;
+ UINTN Length;
+
+ AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_ADR_DP,
+ (UINT16) sizeof (ACPI_ADR_DEVICE_PATH)
+ );
+ ASSERT (AcpiAdr != NULL);
+
+ for (Index = 0; ; Index++) {
+ DisplayDeviceStr = GetNextParamStr (&TextDeviceNode);
+ if (IS_NULL (*DisplayDeviceStr)) {
+ break;
+ }
+ if (Index > 0) {
+ Length = DevicePathNodeLength (AcpiAdr);
+ AcpiAdr = ReallocatePool (
+ Length,
+ Length + sizeof (UINT32),
+ AcpiAdr
+ );
+ ASSERT (AcpiAdr != NULL);
+ SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32));
+ }
+
+ (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr;
+}
+
+/**
+ Converts a generic messaging text device path node to messaging device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to messaging device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMsg (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to Parallel Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAta (
+ CHAR16 *TextDeviceNode
+)
+{
+ CHAR16 *PrimarySecondaryStr;
+ CHAR16 *SlaveMasterStr;
+ CHAR16 *LunStr;
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ATAPI_DP,
+ (UINT16) sizeof (ATAPI_DEVICE_PATH)
+ );
+
+ PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
+ SlaveMasterStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+
+ if (StrCmp (PrimarySecondaryStr, L"Primary") == 0) {
+ Atapi->PrimarySecondary = 0;
+ } else if (StrCmp (PrimarySecondaryStr, L"Secondary") == 0) {
+ Atapi->PrimarySecondary = 1;
+ } else {
+ Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr);
+ }
+ if (StrCmp (SlaveMasterStr, L"Master") == 0) {
+ Atapi->SlaveMaster = 0;
+ } else if (StrCmp (SlaveMasterStr, L"Slave") == 0) {
+ Atapi->SlaveMaster = 1;
+ } else {
+ Atapi->SlaveMaster = (UINT8) Strtoi (SlaveMasterStr);
+ }
+
+ Atapi->Lun = (UINT16) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
+}
+
+/**
+ Converts a text device path node to SCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextScsi (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PunStr;
+ CHAR16 *LunStr;
+ SCSI_DEVICE_PATH *Scsi;
+
+ PunStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Scsi = (SCSI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SCSI_DP,
+ (UINT16) sizeof (SCSI_DEVICE_PATH)
+ );
+
+ Scsi->Pun = (UINT16) Strtoi (PunStr);
+ Scsi->Lun = (UINT16) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
+}
+
+/**
+ Converts a text device path node to Fibre device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Fibre device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibre (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Fibre = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNEL_DP,
+ (UINT16) sizeof (FIBRECHANNEL_DEVICE_PATH)
+ );
+
+ Fibre->Reserved = 0;
+ Strtoi64 (WWNStr, &Fibre->WWN);
+ Strtoi64 (LunStr, &Fibre->Lun);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
+}
+
+/**
+ Converts a text device path node to FibreEx device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created FibreEx device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibreEx (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNELEX_DEVICE_PATH *FibreEx;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNELEX_DP,
+ (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH)
+ );
+
+ FibreEx->Reserved = 0;
+ Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN));
+ Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun));
+
+ *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx->WWN));
+ *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun));
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx;
+}
+
+/**
+ Converts a text device path node to 1394 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created 1394 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromText1394 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ F1394_DEVICE_PATH *F1394DevPath;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ F1394DevPath = (F1394_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_1394_DP,
+ (UINT16) sizeof (F1394_DEVICE_PATH)
+ );
+
+ F1394DevPath->Reserved = 0;
+ F1394DevPath->Guid = StrHexToUint64 (GuidStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath;
+}
+
+/**
+ Converts a text device path node to USB device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsb (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PortStr;
+ CHAR16 *InterfaceStr;
+ USB_DEVICE_PATH *Usb;
+
+ PortStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceStr = GetNextParamStr (&TextDeviceNode);
+ Usb = (USB_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_DP,
+ (UINT16) sizeof (USB_DEVICE_PATH)
+ );
+
+ Usb->ParentPortNumber = (UINT8) Strtoi (PortStr);
+ Usb->InterfaceNumber = (UINT8) Strtoi (InterfaceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
+}
+
+/**
+ Converts a text device path node to I20 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created I20 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextI2O (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TIDStr;
+ I2O_DEVICE_PATH *I2ODevPath;
+
+ TIDStr = GetNextParamStr (&TextDeviceNode);
+ I2ODevPath = (I2O_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_I2O_DP,
+ (UINT16) sizeof (I2O_DEVICE_PATH)
+ );
+
+ I2ODevPath->Tid = (UINT32) Strtoi (TIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath;
+}
+
+/**
+ Converts a text device path node to Infini Band device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Infini Band device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextInfiniband (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FlagsStr;
+ CHAR16 *GuidStr;
+ CHAR16 *SidStr;
+ CHAR16 *TidStr;
+ CHAR16 *DidStr;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ SidStr = GetNextParamStr (&TextDeviceNode);
+ TidStr = GetNextParamStr (&TextDeviceNode);
+ DidStr = GetNextParamStr (&TextDeviceNode);
+ InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_INFINIBAND_DP,
+ (UINT16) sizeof (INFINIBAND_DEVICE_PATH)
+ );
+
+ InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr);
+ StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid);
+ Strtoi64 (SidStr, &InfiniBand->ServiceId);
+ Strtoi64 (TidStr, &InfiniBand->TargetPortId);
+ Strtoi64 (DidStr, &InfiniBand->DeviceId);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
+}
+
+/**
+ Converts a text device path node to Vendor-Defined Messaging device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor-Defined Messaging device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMsg (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to Vendor defined PC-ANSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined PC-ANSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenPcAnsi (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined VT100 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined VT100 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVT100Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined VT100 Plus device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined VT100 Plus device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100Plus (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined UTF8 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined UTF8 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenUtf8 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to UART Flow Control device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UART Flow Control device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUartFlowCtrl (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ValueStr;
+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+
+ ValueStr = GetNextParamStr (&TextDeviceNode);
+ UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
+ );
+
+ CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid);
+ if (StrCmp (ValueStr, L"XonXoff") == 0) {
+ UartFlowControl->FlowControlMap = 2;
+ } else if (StrCmp (ValueStr, L"Hardware") == 0) {
+ UartFlowControl->FlowControlMap = 1;
+ } else {
+ UartFlowControl->FlowControlMap = 0;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl;
+}
+
+/**
+ Converts a text device path node to Serial Attached SCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial Attached SCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSAS (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ CHAR16 *ReservedStr;
+ UINT16 Info;
+ UINT16 Uint16;
+ SAS_DEVICE_PATH *Sas;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ ReservedStr = GetNextParamStr (&TextDeviceNode);
+ Sas = (SAS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (SAS_DEVICE_PATH)
+ );
+
+ CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid);
+ Strtoi64 (AddressStr, &Sas->SasAddress);
+ Strtoi64 (LunStr, &Sas->Lun);
+ Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+
+ if (StrCmp (SASSATAStr, L"NoTopology") == 0) {
+ Info = 0x0;
+
+ } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) {
+
+ Uint16 = (UINT16) Strtoi (DriveBayStr);
+ if (Uint16 == 0) {
+ Info = 0x1;
+ } else {
+ Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
+ }
+
+ if (StrCmp (SASSATAStr, L"SATA") == 0) {
+ Info |= BIT4;
+ }
+
+ //
+ // Location is an integer between 0 and 1 or else
+ // the keyword Internal (0) or External (1).
+ //
+ if (StrCmp (LocationStr, L"External") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (LocationStr, L"Internal") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
+ }
+ Info |= (Uint16 << 5);
+
+ //
+ // Connect is an integer between 0 and 3 or else
+ // the keyword Direct (0) or Expanded (1).
+ //
+ if (StrCmp (ConnectStr, L"Expanded") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (ConnectStr, L"Direct") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
+ }
+ Info |= (Uint16 << 6);
+
+ } else {
+ Info = (UINT16) Strtoi (SASSATAStr);
+ }
+
+ Sas->DeviceTopology = Info;
+ Sas->Reserved = (UINT32) Strtoi (ReservedStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
+}
+
+/**
+ Converts a text device path node to Serial Attached SCSI Ex device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial Attached SCSI Ex device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSasEx (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ UINT16 Info;
+ UINT16 Uint16;
+ UINT64 SasAddress;
+ UINT64 Lun;
+ SASEX_DEVICE_PATH *SasEx;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ SasEx = (SASEX_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SASEX_DP,
+ (UINT16) sizeof (SASEX_DEVICE_PATH)
+ );
+
+ Strtoi64 (AddressStr, &SasAddress);
+ Strtoi64 (LunStr, &Lun);
+ WriteUnaligned64 ((UINT64 *) &SasEx->SasAddress, SwapBytes64 (SasAddress));
+ WriteUnaligned64 ((UINT64 *) &SasEx->Lun, SwapBytes64 (Lun));
+ SasEx->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+
+ if (StrCmp (SASSATAStr, L"NoTopology") == 0) {
+ Info = 0x0;
+
+ } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) {
+
+ Uint16 = (UINT16) Strtoi (DriveBayStr);
+ if (Uint16 == 0) {
+ Info = 0x1;
+ } else {
+ Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
+ }
+
+ if (StrCmp (SASSATAStr, L"SATA") == 0) {
+ Info |= BIT4;
+ }
+
+ //
+ // Location is an integer between 0 and 1 or else
+ // the keyword Internal (0) or External (1).
+ //
+ if (StrCmp (LocationStr, L"External") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (LocationStr, L"Internal") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
+ }
+ Info |= (Uint16 << 5);
+
+ //
+ // Connect is an integer between 0 and 3 or else
+ // the keyword Direct (0) or Expanded (1).
+ //
+ if (StrCmp (ConnectStr, L"Expanded") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (ConnectStr, L"Direct") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
+ }
+ Info |= (Uint16 << 6);
+
+ } else {
+ Info = (UINT16) Strtoi (SASSATAStr);
+ }
+
+ SasEx->DeviceTopology = Info;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) SasEx;
+}
+
+/**
+ Converts a text device path node to NVM Express Namespace device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created NVM Express Namespace device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextNVMe (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *NamespaceIdStr;
+ CHAR16 *NamespaceUuidStr;
+ NVME_NAMESPACE_DEVICE_PATH *Nvme;
+ UINT8 *Uuid;
+ UINTN Index;
+
+ NamespaceIdStr = GetNextParamStr (&TextDeviceNode);
+ NamespaceUuidStr = GetNextParamStr (&TextDeviceNode);
+ Nvme = (NVME_NAMESPACE_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_NVME_NAMESPACE_DP,
+ (UINT16) sizeof (NVME_NAMESPACE_DEVICE_PATH)
+ );
+
+ Nvme->NamespaceId = (UINT32) Strtoi (NamespaceIdStr);
+ Uuid = (UINT8 *) &Nvme->NamespaceUuid;
+
+ Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8);
+ while (Index-- != 0) {
+ Uuid[Index] = (UINT8) StrHexToUintn (SplitStr (&NamespaceUuidStr, L'-'));
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Nvme;
+}
+
+/**
+ Converts a text device path node to UFS device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UFS device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUfs (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PunStr;
+ CHAR16 *LunStr;
+ UFS_DEVICE_PATH *Ufs;
+
+ PunStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Ufs = (UFS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_UFS_DP,
+ (UINT16) sizeof (UFS_DEVICE_PATH)
+ );
+
+ Ufs->Pun = (UINT8) Strtoi (PunStr);
+ Ufs->Lun = (UINT8) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Ufs;
+}
+
+/**
+ Converts a text device path node to SD (Secure Digital) device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SD device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSd (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SlotNumberStr;
+ SD_DEVICE_PATH *Sd;
+
+ SlotNumberStr = GetNextParamStr (&TextDeviceNode);
+ Sd = (SD_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SD_DP,
+ (UINT16) sizeof (SD_DEVICE_PATH)
+ );
+
+ Sd->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sd;
+}
+
+/**
+ Converts a text device path node to EMMC (Embedded MMC) device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created EMMC device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextEmmc (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SlotNumberStr;
+ EMMC_DEVICE_PATH *Emmc;
+
+ SlotNumberStr = GetNextParamStr (&TextDeviceNode);
+ Emmc = (EMMC_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_EMMC_DP,
+ (UINT16) sizeof (EMMC_DEVICE_PATH)
+ );
+
+ Emmc->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Emmc;
+}
+
+/**
+ Converts a text device path node to Debug Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Debug Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextDebugPort (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEFINED_MESSAGING_DEVICE_PATH *Vend;
+
+ Vend = (VENDOR_DEFINED_MESSAGING_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEFINED_MESSAGING_DEVICE_PATH)
+ );
+
+ CopyGuid (&Vend->Guid, &gEfiDebugPortDevicePathGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
+}
+
+/**
+ Converts a text device path node to MAC device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created MAC device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMAC (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *IfTypeStr;
+ UINTN Length;
+ MAC_ADDR_DEVICE_PATH *MACDevPath;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ IfTypeStr = GetNextParamStr (&TextDeviceNode);
+ MACDevPath = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_MAC_ADDR_DP,
+ (UINT16) sizeof (MAC_ADDR_DEVICE_PATH)
+ );
+
+ MACDevPath->IfType = (UINT8) Strtoi (IfTypeStr);
+
+ Length = sizeof (EFI_MAC_ADDRESS);
+ if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) {
+ Length = 6;
+ }
+
+ StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath;
+}
+
+
+/**
+ Converts a text format to the network protocol ID.
+
+ @param Text String of protocol field.
+
+ @return Network protocol ID .
+
+**/
+UINTN
+NetworkProtocolFromText (
+ CHAR16 *Text
+ )
+{
+ if (StrCmp (Text, L"UDP") == 0) {
+ return RFC_1700_UDP_PROTOCOL;
+ }
+
+ if (StrCmp (Text, L"TCP") == 0) {
+ return RFC_1700_TCP_PROTOCOL;
+ }
+
+ return Strtoi (Text);
+}
+
+
+/**
+ Converts a text device path node to IPV4 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created IPV4 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv4 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ CHAR16 *GatewayIPStr;
+ CHAR16 *SubnetMaskStr;
+ IPv4_DEVICE_PATH *IPv4;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ GatewayIPStr = GetNextParamStr (&TextDeviceNode);
+ SubnetMaskStr = GetNextParamStr (&TextDeviceNode);
+ IPv4 = (IPv4_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv4_DP,
+ (UINT16) sizeof (IPv4_DEVICE_PATH)
+ );
+
+ StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL);
+ IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv4->StaticIpAddress = TRUE;
+ } else {
+ IPv4->StaticIpAddress = FALSE;
+ }
+
+ StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL);
+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {
+ StrToIpv4Address (GatewayIPStr, NULL, &IPv4->GatewayIpAddress, NULL);
+ StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask, NULL);
+ } else {
+ ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress));
+ ZeroMem (&IPv4->SubnetMask, sizeof (IPv4->SubnetMask));
+ }
+
+ IPv4->LocalPort = 0;
+ IPv4->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
+}
+
+/**
+ Converts a text device path node to IPV6 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created IPV6 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv6 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ CHAR16 *GatewayIPStr;
+ CHAR16 *PrefixLengthStr;
+ IPv6_DEVICE_PATH *IPv6;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ PrefixLengthStr = GetNextParamStr (&TextDeviceNode);
+ GatewayIPStr = GetNextParamStr (&TextDeviceNode);
+ IPv6 = (IPv6_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv6_DP,
+ (UINT16) sizeof (IPv6_DEVICE_PATH)
+ );
+
+ StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL);
+ IPv6->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv6->IpAddressOrigin = 0;
+ } else if (StrCmp (TypeStr, L"StatelessAutoConfigure") == 0) {
+ IPv6->IpAddressOrigin = 1;
+ } else {
+ IPv6->IpAddressOrigin = 2;
+ }
+
+ StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL);
+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {
+ StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL);
+ IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr);
+ } else {
+ ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress));
+ IPv6->PrefixLength = 0;
+ }
+
+ IPv6->LocalPort = 0;
+ IPv6->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
+}
+
+/**
+ Converts a text device path node to UART device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UART device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUart (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BaudStr;
+ CHAR16 *DataBitsStr;
+ CHAR16 *ParityStr;
+ CHAR16 *StopBitsStr;
+ UART_DEVICE_PATH *Uart;
+
+ BaudStr = GetNextParamStr (&TextDeviceNode);
+ DataBitsStr = GetNextParamStr (&TextDeviceNode);
+ ParityStr = GetNextParamStr (&TextDeviceNode);
+ StopBitsStr = GetNextParamStr (&TextDeviceNode);
+ Uart = (UART_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ (UINT16) sizeof (UART_DEVICE_PATH)
+ );
+
+ if (StrCmp (BaudStr, L"DEFAULT") == 0) {
+ Uart->BaudRate = 115200;
+ } else {
+ Strtoi64 (BaudStr, &Uart->BaudRate);
+ }
+ Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr));
+ switch (*ParityStr) {
+ case L'D':
+ Uart->Parity = 0;
+ break;
+
+ case L'N':
+ Uart->Parity = 1;
+ break;
+
+ case L'E':
+ Uart->Parity = 2;
+ break;
+
+ case L'O':
+ Uart->Parity = 3;
+ break;
+
+ case L'M':
+ Uart->Parity = 4;
+ break;
+
+ case L'S':
+ Uart->Parity = 5;
+ break;
+
+ default:
+ Uart->Parity = (UINT8) Strtoi (ParityStr);
+ break;
+ }
+
+ if (StrCmp (StopBitsStr, L"D") == 0) {
+ Uart->StopBits = (UINT8) 0;
+ } else if (StrCmp (StopBitsStr, L"1") == 0) {
+ Uart->StopBits = (UINT8) 1;
+ } else if (StrCmp (StopBitsStr, L"1.5") == 0) {
+ Uart->StopBits = (UINT8) 2;
+ } else if (StrCmp (StopBitsStr, L"2") == 0) {
+ Uart->StopBits = (UINT8) 3;
+ } else {
+ Uart->StopBits = (UINT8) Strtoi (StopBitsStr);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
+}
+
+/**
+ Converts a text device path node to USB class device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+ @param UsbClassText A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text.
+
+ @return A pointer to the newly-created USB class device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextUsbClass (
+ CHAR16 *TextDeviceNode,
+ USB_CLASS_TEXT *UsbClassText
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *ClassStr;
+ CHAR16 *SubClassStr;
+ CHAR16 *ProtocolStr;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+
+ UsbClass = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ (UINT16) sizeof (USB_CLASS_DEVICE_PATH)
+ );
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ if (UsbClassText->ClassExist) {
+ ClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr);
+ } else {
+ UsbClass->DeviceClass = UsbClassText->Class;
+ }
+ if (UsbClassText->SubClassExist) {
+ SubClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr);
+ } else {
+ UsbClass->DeviceSubClass = UsbClassText->SubClass;
+ }
+
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+
+ UsbClass->VendorId = (UINT16) Strtoi (VIDStr);
+ UsbClass->ProductId = (UINT16) Strtoi (PIDStr);
+ UsbClass->DeviceProtocol = (UINT8) Strtoi (ProtocolStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
+}
+
+
+/**
+ Converts a text device path node to USB class device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB class device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbClass (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = TRUE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB audio device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB audio device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbAudio (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_AUDIO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB CDC Control device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB CDC Control device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCControl (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCCONTROL;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHID (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HID;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB Image device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB Image device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbImage (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_IMAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB Print device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB Print device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbPrinter (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_PRINTER;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB mass storage device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB mass storage device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbMassStorage (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_MASS_STORAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB HUB device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB HUB device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHub (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HUB;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB CDC data device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB CDC data device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCData (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCDATA;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB smart card device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB smart card device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbSmartCard (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_SMART_CARD;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB video device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB video device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbVideo (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_VIDEO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB diagnostic device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB diagnostic device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDiagnostic (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_DIAGNOSTIC;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB wireless device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB wireless device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWireless (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_WIRELESS;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB device firmware update device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB device firmware update device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDeviceFirmwareUpdate (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB IRDA bridge device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB IRDA bridge device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbIrdaBridge (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB text and measurement device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB text and measurement device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbTestAndMeasurement (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_TEST;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB WWID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB WWID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWwid (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *InterfaceNumStr;
+ CHAR16 *SerialNumberStr;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+ UINTN SerialNumberStrLen;
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceNumStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStrLen = StrLen (SerialNumberStr);
+ if (SerialNumberStrLen >= 2 &&
+ SerialNumberStr[0] == L'\"' &&
+ SerialNumberStr[SerialNumberStrLen - 1] == L'\"'
+ ) {
+ SerialNumberStr[SerialNumberStrLen - 1] = L'\0';
+ SerialNumberStr++;
+ SerialNumberStrLen -= 2;
+ }
+ UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_WWID_DP,
+ (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16))
+ );
+ UsbWwid->VendorId = (UINT16) Strtoi (VIDStr);
+ UsbWwid->ProductId = (UINT16) Strtoi (PIDStr);
+ UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
+
+ //
+ // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr.
+ // Therefore, the '\0' will not be copied.
+ //
+ memcpy (
+ (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH),
+ SerialNumberStr,
+ SerialNumberStrLen * sizeof (CHAR16)
+ );
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
+}
+
+/**
+ Converts a text device path node to Logic Unit device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Logic Unit device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUnit (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *LunStr;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_DEVICE_LOGICAL_UNIT_DP,
+ (UINT16) sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
+ );
+
+ LogicalUnit->Lun = (UINT8) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
+}
+
+/**
+ Converts a text device path node to iSCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created iSCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextiSCSI (
+ CHAR16 *TextDeviceNode
+ )
+{
+ UINT16 Options;
+ CHAR16 *NameStr;
+ CHAR16 *PortalGroupStr;
+ CHAR16 *LunStr;
+ CHAR16 *HeaderDigestStr;
+ CHAR16 *DataDigestStr;
+ CHAR16 *AuthenticationStr;
+ CHAR16 *ProtocolStr;
+ CHAR8 *AsciiStr;
+ ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
+
+ NameStr = GetNextParamStr (&TextDeviceNode);
+ PortalGroupStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ HeaderDigestStr = GetNextParamStr (&TextDeviceNode);
+ DataDigestStr = GetNextParamStr (&TextDeviceNode);
+ AuthenticationStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ ISCSIDevPath = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ISCSI_DP,
+ (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr))
+ );
+
+ AsciiStr = ISCSIDevPath->TargetName;
+ StrToAscii (NameStr, &AsciiStr);
+
+ ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr);
+ Strtoi64 (LunStr, &ISCSIDevPath->Lun);
+
+ Options = 0x0000;
+ if (StrCmp (HeaderDigestStr, L"CRC32C") == 0) {
+ Options |= 0x0002;
+ }
+
+ if (StrCmp (DataDigestStr, L"CRC32C") == 0) {
+ Options |= 0x0008;
+ }
+
+ if (StrCmp (AuthenticationStr, L"None") == 0) {
+ Options |= 0x0800;
+ }
+
+ if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) {
+ Options |= 0x1000;
+ }
+
+ ISCSIDevPath->LoginOption = (UINT16) Options;
+
+ if (StrCmp (ProtocolStr, L"TCP") == 0) {
+ ISCSIDevPath->NetworkProtocol = 0;
+ } else {
+ //
+ // Undefined and reserved.
+ //
+ ISCSIDevPath->NetworkProtocol = 1;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath;
+}
+
+/**
+ Converts a text device path node to VLAN device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created VLAN device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVlan (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VlanStr;
+ VLAN_DEVICE_PATH *Vlan;
+
+ VlanStr = GetNextParamStr (&TextDeviceNode);
+ Vlan = (VLAN_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VLAN_DP,
+ (UINT16) sizeof (VLAN_DEVICE_PATH)
+ );
+
+ Vlan->VlanId = (UINT16) Strtoi (VlanStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vlan;
+}
+
+/**
+ Converts a text device path node to Bluetooth device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Bluetooth device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBluetooth (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BluetoothStr;
+ BLUETOOTH_DEVICE_PATH *BluetoothDp;
+
+ BluetoothStr = GetNextParamStr (&TextDeviceNode);
+ BluetoothDp = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_BLUETOOTH_DP,
+ (UINT16) sizeof (BLUETOOTH_DEVICE_PATH)
+ );
+ StrHexToBytes (
+ BluetoothStr,
+ sizeof (BLUETOOTH_ADDRESS) * 2,
+ BluetoothDp->BD_ADDR.Address,
+ sizeof (BLUETOOTH_ADDRESS)
+ );
+ return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp;
+}
+
+/**
+ Converts a text device path node to Wi-Fi device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Wi-Fi device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextWiFi (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SSIdStr;
+ CHAR8 AsciiStr[33];
+ UINTN DataLen;
+ WIFI_DEVICE_PATH *WiFiDp;
+
+ SSIdStr = GetNextParamStr (&TextDeviceNode);
+ WiFiDp = (WIFI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_WIFI_DP,
+ (UINT16) sizeof (WIFI_DEVICE_PATH)
+ );
+
+ if (NULL != SSIdStr) {
+ DataLen = StrLen (SSIdStr);
+ if (StrLen (SSIdStr) > 32) {
+ SSIdStr[32] = L'\0';
+ DataLen = 32;
+ }
+
+ UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr));
+ memcpy (WiFiDp->SSId, AsciiStr, DataLen);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp;
+}
+
+/**
+ Converts a text device path node to URI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created URI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUri (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *UriStr;
+ UINTN UriLength;
+ URI_DEVICE_PATH *Uri;
+
+ UriStr = GetNextParamStr (&TextDeviceNode);
+ UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH));
+ Uri = (URI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_URI_DP,
+ (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength)
+ );
+
+ while (UriLength-- != 0) {
+ Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength];
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Uri;
+}
+
+/**
+ Converts a media text device path node to media device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to media device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMediaPath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to HD device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created HD device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHD (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PartitionStr;
+ CHAR16 *TypeStr;
+ CHAR16 *SignatureStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ UINT32 Signature32;
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ PartitionStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ SignatureStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ Hd = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_HARDDRIVE_DP,
+ (UINT16) sizeof (HARDDRIVE_DEVICE_PATH)
+ );
+
+ Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr);
+
+ ZeroMem (Hd->Signature, 16);
+ Hd->MBRType = (UINT8) 0;
+
+ if (StrCmp (TypeStr, L"MBR") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_MBR;
+ Hd->MBRType = 0x01;
+
+ Signature32 = (UINT32) Strtoi (SignatureStr);
+ memcpy (Hd->Signature, &Signature32, sizeof (UINT32));
+ } else if (StrCmp (TypeStr, L"GPT") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_GUID;
+ Hd->MBRType = 0x02;
+
+ StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature);
+ } else {
+ Hd->SignatureType = (UINT8) Strtoi (TypeStr);
+ }
+
+ Strtoi64 (StartStr, &Hd->PartitionStart);
+ Strtoi64 (SizeStr, &Hd->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
+}
+
+/**
+ Converts a text device path node to CDROM device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created CDROM device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCDROM (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *EntryStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ CDROM_DEVICE_PATH *CDROMDevPath;
+
+ EntryStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ CDROMDevPath = (CDROM_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_CDROM_DP,
+ (UINT16) sizeof (CDROM_DEVICE_PATH)
+ );
+
+ CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr);
+ Strtoi64 (StartStr, &CDROMDevPath->PartitionStart);
+ Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath;
+}
+
+/**
+ Converts a text device path node to Vendor-defined media device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor-defined media device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMedia (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MEDIA_DEVICE_PATH,
+ MEDIA_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to File device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created File device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFilePath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ FILEPATH_DEVICE_PATH *File;
+
+ File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2)
+ );
+
+ StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) File;
+}
+
+/**
+ Converts a text device path node to Media protocol device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Media protocol device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMedia (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_PROTOCOL_DEVICE_PATH *Media;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Media = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PROTOCOL_DP,
+ (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Media->Protocol);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Media;
+}
+
+/**
+ Converts a text device path node to firmware volume device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created firmware volume device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFv (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_FW_VOL_DEVICE_PATH *Fv;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Fv = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_VOL_DP,
+ (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Fv->FvName);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
+}
+
+/**
+ Converts a text device path node to firmware file device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created firmware file device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFvFile (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ FvFile = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_FILE_DP,
+ (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &FvFile->FvFileName);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
+}
+
+/**
+ Converts a text device path node to text relative offset device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRelativeOffsetRange (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingOffsetStr;
+ CHAR16 *EndingOffsetStr;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+ StartingOffsetStr = GetNextParamStr (&TextDeviceNode);
+ EndingOffsetStr = GetNextParamStr (&TextDeviceNode);
+ Offset = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RELATIVE_OFFSET_RANGE_DP,
+ (UINT16) sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingOffsetStr, &Offset->StartingOffset);
+ Strtoi64 (EndingOffsetStr, &Offset->EndingOffset);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Offset;
+}
+
+/**
+ Converts a text device path node to text ram disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRamDisk (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *TypeGuidStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+ TypeGuidStr = GetNextParamStr (&TextDeviceNode);
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ StrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text virtual disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVirtualDisk (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text virtual cd device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVirtualCd (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text persistent virtual disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPersistentVirtualDisk (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text persistent virtual cd device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPersistentVirtualCd (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a BBS text device path node to BBS device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to BBS device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBbsPath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to BIOS Boot Specification device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created BIOS Boot Specification device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBBS (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+ CHAR16 *IdStr;
+ CHAR16 *FlagsStr;
+ CHAR8 *AsciiStr;
+ BBS_BBS_DEVICE_PATH *Bbs;
+
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ IdStr = GetNextParamStr (&TextDeviceNode);
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ Bbs = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr))
+ );
+
+ if (StrCmp (TypeStr, L"Floppy") == 0) {
+ Bbs->DeviceType = BBS_TYPE_FLOPPY;
+ } else if (StrCmp (TypeStr, L"HD") == 0) {
+ Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
+ } else if (StrCmp (TypeStr, L"CDROM") == 0) {
+ Bbs->DeviceType = BBS_TYPE_CDROM;
+ } else if (StrCmp (TypeStr, L"PCMCIA") == 0) {
+ Bbs->DeviceType = BBS_TYPE_PCMCIA;
+ } else if (StrCmp (TypeStr, L"USB") == 0) {
+ Bbs->DeviceType = BBS_TYPE_USB;
+ } else if (StrCmp (TypeStr, L"Network") == 0) {
+ Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
+ } else {
+ Bbs->DeviceType = (UINT16) Strtoi (TypeStr);
+ }
+
+ AsciiStr = Bbs->String;
+ StrToAscii (IdStr, &AsciiStr);
+
+ Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
+}
+
+/**
+ Converts a text device path node to SATA device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SATA device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSata (
+ CHAR16 *TextDeviceNode
+ )
+{
+ SATA_DEVICE_PATH *Sata;
+ CHAR16 *Param1;
+ CHAR16 *Param2;
+ CHAR16 *Param3;
+
+ Param1 = GetNextParamStr (&TextDeviceNode);
+ Param2 = GetNextParamStr (&TextDeviceNode);
+ Param3 = GetNextParamStr (&TextDeviceNode);
+
+ Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SATA_DP,
+ (UINT16) sizeof (SATA_DEVICE_PATH)
+ );
+ Sata->HBAPortNumber = (UINT16) Strtoi (Param1);
+ Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2);
+ Sata->Lun = (UINT16) Strtoi (Param3);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
+}
+
+DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = {
+ {L"Path", DevPathFromTextPath },
+
+ {L"HardwarePath", DevPathFromTextHardwarePath },
+ {L"Pci", DevPathFromTextPci },
+ {L"PcCard", DevPathFromTextPcCard },
+ {L"MemoryMapped", DevPathFromTextMemoryMapped },
+ {L"VenHw", DevPathFromTextVenHw },
+ {L"Ctrl", DevPathFromTextCtrl },
+ {L"BMC", DevPathFromTextBmc },
+
+ {L"AcpiPath", DevPathFromTextAcpiPath },
+ {L"Acpi", DevPathFromTextAcpi },
+ {L"PciRoot", DevPathFromTextPciRoot },
+ {L"PcieRoot", DevPathFromTextPcieRoot },
+ {L"Floppy", DevPathFromTextFloppy },
+ {L"Keyboard", DevPathFromTextKeyboard },
+ {L"Serial", DevPathFromTextSerial },
+ {L"ParallelPort", DevPathFromTextParallelPort },
+ {L"AcpiEx", DevPathFromTextAcpiEx },
+ {L"AcpiExp", DevPathFromTextAcpiExp },
+ {L"AcpiAdr", DevPathFromTextAcpiAdr },
+
+ {L"Msg", DevPathFromTextMsg },
+ {L"Ata", DevPathFromTextAta },
+ {L"Scsi", DevPathFromTextScsi },
+ {L"Fibre", DevPathFromTextFibre },
+ {L"FibreEx", DevPathFromTextFibreEx },
+ {L"I1394", DevPathFromText1394 },
+ {L"USB", DevPathFromTextUsb },
+ {L"I2O", DevPathFromTextI2O },
+ {L"Infiniband", DevPathFromTextInfiniband },
+ {L"VenMsg", DevPathFromTextVenMsg },
+ {L"VenPcAnsi", DevPathFromTextVenPcAnsi },
+ {L"VenVt100", DevPathFromTextVenVt100 },
+ {L"VenVt100Plus", DevPathFromTextVenVt100Plus },
+ {L"VenUtf8", DevPathFromTextVenUtf8 },
+ {L"UartFlowCtrl", DevPathFromTextUartFlowCtrl },
+ {L"SAS", DevPathFromTextSAS },
+ {L"SasEx", DevPathFromTextSasEx },
+ {L"NVMe", DevPathFromTextNVMe },
+ {L"UFS", DevPathFromTextUfs },
+ {L"SD", DevPathFromTextSd },
+ {L"eMMC", DevPathFromTextEmmc },
+ {L"DebugPort", DevPathFromTextDebugPort },
+ {L"MAC", DevPathFromTextMAC },
+ {L"IPv4", DevPathFromTextIPv4 },
+ {L"IPv6", DevPathFromTextIPv6 },
+ {L"Uart", DevPathFromTextUart },
+ {L"UsbClass", DevPathFromTextUsbClass },
+ {L"UsbAudio", DevPathFromTextUsbAudio },
+ {L"UsbCDCControl", DevPathFromTextUsbCDCControl },
+ {L"UsbHID", DevPathFromTextUsbHID },
+ {L"UsbImage", DevPathFromTextUsbImage },
+ {L"UsbPrinter", DevPathFromTextUsbPrinter },
+ {L"UsbMassStorage", DevPathFromTextUsbMassStorage },
+ {L"UsbHub", DevPathFromTextUsbHub },
+ {L"UsbCDCData", DevPathFromTextUsbCDCData },
+ {L"UsbSmartCard", DevPathFromTextUsbSmartCard },
+ {L"UsbVideo", DevPathFromTextUsbVideo },
+ {L"UsbDiagnostic", DevPathFromTextUsbDiagnostic },
+ {L"UsbWireless", DevPathFromTextUsbWireless },
+ {L"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate },
+ {L"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge },
+ {L"UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement },
+ {L"UsbWwid", DevPathFromTextUsbWwid },
+ {L"Unit", DevPathFromTextUnit },
+ {L"iSCSI", DevPathFromTextiSCSI },
+ {L"Vlan", DevPathFromTextVlan },
+ {L"Uri", DevPathFromTextUri },
+ {L"Bluetooth", DevPathFromTextBluetooth },
+ {L"Wi-Fi", DevPathFromTextWiFi },
+ {L"MediaPath", DevPathFromTextMediaPath },
+ {L"HD", DevPathFromTextHD },
+ {L"CDROM", DevPathFromTextCDROM },
+ {L"VenMedia", DevPathFromTextVenMedia },
+ {L"Media", DevPathFromTextMedia },
+ {L"Fv", DevPathFromTextFv },
+ {L"FvFile", DevPathFromTextFvFile },
+ {L"Offset", DevPathFromTextRelativeOffsetRange },
+ {L"RamDisk", DevPathFromTextRamDisk },
+ {L"VirtualDisk", DevPathFromTextVirtualDisk },
+ {L"VirtualCD", DevPathFromTextVirtualCd },
+ {L"PersistentVirtualDisk", DevPathFromTextPersistentVirtualDisk },
+ {L"PersistentVirtualCD", DevPathFromTextPersistentVirtualCd },
+
+ {L"BbsPath", DevPathFromTextBbsPath },
+ {L"BBS", DevPathFromTextBBS },
+ {L"Sata", DevPathFromTextSata },
+ {NULL, NULL}
+};
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ )
+{
+ DEVICE_PATH_FROM_TEXT FromText;
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ CHAR16 *DeviceNodeStr;
+ UINTN Index;
+
+ if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
+ return NULL;
+ }
+
+ ParamStr = NULL;
+ FromText = NULL;
+ DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
+ ASSERT (DeviceNodeStr != NULL);
+
+ for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (FromText == NULL) {
+ //
+ // A file path
+ //
+ FromText = DevPathFromTextFilePath;
+ DeviceNode = FromText (DeviceNodeStr);
+ } else {
+ DeviceNode = FromText (ParamStr);
+ free (ParamStr);
+ }
+
+ free (DeviceNodeStr);
+
+ return DeviceNode;
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ CHAR16 *DevicePathStr;
+ CHAR16 *Str;
+ CHAR16 *DeviceNodeStr;
+ BOOLEAN IsInstanceEnd;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
+ return NULL;
+ }
+
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ ASSERT (DevicePath != NULL);
+ SetDevicePathEndNode (DevicePath);
+
+ DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath);
+
+ Str = DevicePathStr;
+ while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
+ DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr);
+
+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
+ free (DevicePath);
+ free (DeviceNode);
+ DevicePath = NewDevicePath;
+
+ if (IsInstanceEnd) {
+ DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ ASSERT (DeviceNode != NULL);
+ SetDevicePathEndNode (DeviceNode);
+ DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
+ free (DevicePath);
+ free (DeviceNode);
+ DevicePath = NewDevicePath;
+ }
+ }
+
+ free (DevicePathStr);
+ return DevicePath;
+}
diff --git a/BaseTools/Source/C/DevicePath/DevicePathFromText.h b/BaseTools/Source/C/DevicePath/DevicePathFromText.h
new file mode 100644
index 0000000..4c46921
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.h
@@ -0,0 +1,72 @@
+/** @file
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL as defined in UEFI 2.0.
+ This protocol provides service to convert text to device paths and device nodes.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__
+#define __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__
+
+///
+/// Device Path From Text protocol
+///
+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
+ { \
+ 0x5c99a21, 0xc70f, 0x4ad2, {0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \
+ }
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @retval a_pointer Pointer to the EFI device node.
+ @retval NULL if TextDeviceNode is NULL or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_FROM_TEXT_NODE)(
+ CONST CHAR16 *TextDeviceNode
+ );
+
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device path character.
+
+ @retval a_pointer Pointer to the allocated device path.
+ @retval NULL if TextDeviceNode is NULL or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_FROM_TEXT_PATH)(
+ CONST CHAR16 *TextDevicePath
+ );
+
+///
+/// This protocol converts text to device paths and device nodes.
+///
+typedef struct {
+ EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode;
+ EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath;
+} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;
+
+extern EFI_GUID gEfiDevicePathFromTextProtocolGuid;
+
+#endif
diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.c b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
new file mode 100644
index 0000000..07a58ee
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
@@ -0,0 +1,2352 @@
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment varibles. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UefiDevicePathLib.h"
+#include "DevicePathUtilities.h"
+
+#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
+ do { \
+ ASSERT (Expression); \
+ if (!(Expression)) { \
+ return Status; \
+ } \
+ } while (FALSE)
+
+
+//
+// Template for an end-of-device path node.
+//
+CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+};
+
+/**
+ Determine whether a given device path is valid.
+ If DevicePath is NULL, then ASSERT().
+
+ @param DevicePath A pointer to a device path data structure.
+ @param MaxSize The maximum size of the device path data structure.
+
+ @retval TRUE DevicePath is valid.
+ @retval FALSE The length of any node node in the DevicePath is less
+ than sizeof (EFI_DEVICE_PATH_PROTOCOL).
+ @retval FALSE If MaxSize is not zero, the size of the DevicePath
+ exceeds MaxSize.
+ @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node
+ count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
+**/
+BOOLEAN
+IsDevicePathValid (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ UINTN MaxSize
+ )
+{
+ UINTN Count;
+ UINTN Size;
+ UINTN NodeLength;
+
+ ASSERT (DevicePath != NULL);
+
+ if (MaxSize == 0) {
+ MaxSize = MAX_UINTN;
+ }
+
+ //
+ // Validate the input size big enough to touch the first node.
+ //
+ if (MaxSize < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return FALSE;
+ }
+
+ for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
+ NodeLength = DevicePathNodeLength (DevicePath);
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return FALSE;
+ }
+
+ if (NodeLength > MAX_UINTN - Size) {
+ return FALSE;
+ }
+ Size += NodeLength;
+
+ //
+ // Validate next node before touch it.
+ //
+ if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) {
+ return FALSE;
+ }
+
+ Count++;
+ if (Count >= MAX_DEVICE_PATH_NODE_COUNT) {
+ return FALSE;
+ }
+
+ }
+
+ //
+ // Only return TRUE when the End Device Path node is valid.
+ //
+ return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
+}
+
+
+/**
+ Returns the Type field of a device path node.
+
+ Returns the Type field of the device path node specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The Type field of the device path node specified by Node.
+
+**/
+UINT8
+DevicePathType (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type;
+}
+
+/**
+ Returns the SubType field of a device path node.
+
+ Returns the SubType field of the device path node specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The SubType field of the device path node specified by Node.
+
+**/
+UINT8
+DevicePathSubType (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType;
+}
+
+/**
+ Returns the 16-bit Length field of a device path node.
+
+ Returns the 16-bit Length field of the device path node specified by Node.
+ Node is not required to be aligned on a 16-bit boundary, so it is recommended
+ that a function such as ReadUnaligned16() be used to extract the contents of
+ the Length field.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The 16-bit Length field of the device path node specified by Node.
+
+**/
+UINTN
+DevicePathNodeLength (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
+}
+
+/**
+ Returns a pointer to the next node in a device path.
+
+ Returns a pointer to the device path node that follows the device path node
+ specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return a pointer to the device path node that follows the device path node
+ specified by Node.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+NextDevicePathNode (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength(Node));
+}
+
+/**
+ Determines if a device path node is an end node of a device path.
+ This includes nodes that are the end of a device path instance and nodes that
+ are the end of an entire device path.
+
+ Determines if the device path node specified by Node is an end node of a device path.
+ This includes nodes that are the end of a device path instance and nodes that are the
+ end of an entire device path. If Node represents an end node of a device path,
+ then TRUE is returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is an end node of a
+ device path.
+ @retval FALSE The device path node specified by Node is not an end node of
+ a device path.
+
+**/
+BOOLEAN
+IsDevicePathEndType (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE);
+}
+
+/**
+ Determines if a device path node is an end node of an entire device path.
+
+ Determines if a device path node specified by Node is an end node of an entire
+ device path. If Node represents the end of an entire device path, then TRUE is
+ returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is the end of an entire
+ device path.
+ @retval FALSE The device path node specified by Node is not the end of an
+ entire device path.
+
+**/
+BOOLEAN
+IsDevicePathEnd (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
+}
+
+/**
+ Determines if a device path node is an end node of a device path instance.
+
+ Determines if a device path node specified by Node is an end node of a device
+ path instance. If Node represents the end of a device path instance, then TRUE
+ is returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is the end of a device
+ path instance.
+ @retval FALSE The device path node specified by Node is not the end of a
+ device path instance.
+
+**/
+BOOLEAN
+IsDevicePathEndInstance (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
+}
+
+/**
+ Sets the length, in bytes, of a device path node.
+
+ Sets the length of the device path node specified by Node to the value specified
+ by NodeLength. NodeLength is returned. Node is not required to be aligned on
+ a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()
+ be used to set the contents of the Length field.
+
+ If Node is NULL, then ASSERT().
+ If NodeLength >= SIZE_64KB, then ASSERT().
+ If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+ @param Length The length, in bytes, of the device path node.
+
+ @return Length
+
+**/
+UINT16
+SetDevicePathNodeLength (
+ VOID *Node,
+ UINTN Length
+ )
+{
+ ASSERT (Node != NULL);
+ ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB));
+ return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
+}
+
+/**
+ Fills in all the fields of a device path node that is the end of an entire device path.
+
+ Fills in all the fields of a device path node specified by Node so Node represents
+ the end of an entire device path. The Type field of Node is set to
+ END_DEVICE_PATH_TYPE, the SubType field of Node is set to
+ END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to
+ END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary,
+ so it is recommended that a function such as WriteUnaligned16() be used to set
+ the contents of the Length field.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+**/
+VOID
+SetDevicePathEndNode (
+ VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));
+}
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+UefiDevicePathLibGetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0)) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = DevicePath;
+ while (!IsDevicePathEnd (DevicePath)) {
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+
+ //
+ // Compute the size and add back in the size of the end device path structure
+ //
+ return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);
+}
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibDuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ UINTN Size;
+
+ //
+ // Compute the size
+ //
+ Size = GetDevicePathSize (DevicePath);
+ if (Size == 0) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for duplicate device path
+ //
+
+ return AllocateCopyPool (Size, DevicePath);
+}
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath
+ )
+{
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath2;
+
+ //
+ // If there's only 1 path, just duplicate it.
+ //
+ if (FirstDevicePath == NULL) {
+ return DuplicateDevicePath ((SecondDevicePath != NULL) ? SecondDevicePath : &mUefiDevicePathLibEndDevicePath);
+ }
+
+ if (SecondDevicePath == NULL) {
+ return DuplicateDevicePath (FirstDevicePath);
+ }
+
+ if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL.
+ //
+ Size1 = GetDevicePathSize (FirstDevicePath);
+ Size2 = GetDevicePathSize (SecondDevicePath);
+ Size = Size1 + Size2 - END_DEVICE_PATH_LENGTH;
+
+ NewDevicePath = AllocatePool (Size);
+
+ if (NewDevicePath != NULL) {
+ NewDevicePath = memcpy (NewDevicePath, FirstDevicePath, Size1);
+ //
+ // Over write FirstDevicePath EndNode and do the copy
+ //
+ DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath +
+ (Size1 - END_DEVICE_PATH_LENGTH));
+ memcpy (DevicePath2, SecondDevicePath, Size2);
+ }
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN NodeLength;
+
+ if (DevicePathNode == NULL) {
+ return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : &mUefiDevicePathLibEndDevicePath);
+ }
+ //
+ // Build a Node that has a terminator on it
+ //
+ NodeLength = DevicePathNodeLength (DevicePathNode);
+
+ TempDevicePath = AllocatePool (NodeLength + END_DEVICE_PATH_LENGTH);
+ if (TempDevicePath == NULL) {
+ return NULL;
+ }
+ TempDevicePath = memcpy (TempDevicePath, DevicePathNode, NodeLength);
+ //
+ // Add and end device path node to convert Node to device path
+ //
+ NextNode = NextDevicePathNode (TempDevicePath);
+ SetDevicePathEndNode (NextNode);
+ //
+ // Append device paths
+ //
+ NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath);
+
+ free (TempDevicePath);
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ UINTN SrcSize;
+ UINTN InstanceSize;
+
+ if (DevicePath == NULL) {
+ return DuplicateDevicePath (DevicePathInstance);
+ }
+
+ if (DevicePathInstance == NULL) {
+ return NULL;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid (DevicePathInstance, 0)) {
+ return NULL;
+ }
+
+ SrcSize = GetDevicePathSize (DevicePath);
+ InstanceSize = GetDevicePathSize (DevicePathInstance);
+
+ NewDevicePath = AllocatePool (SrcSize + InstanceSize);
+ if (NewDevicePath != NULL) {
+
+ TempDevicePath = memcpy (NewDevicePath, DevicePath, SrcSize);;
+
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+
+ TempDevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ memcpy (TempDevicePath, DevicePathInstance, InstanceSize);
+ }
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibGetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ EFI_DEVICE_PATH_PROTOCOL *ReturnValue;
+ UINT8 Temp;
+
+ ASSERT (Size != NULL);
+
+ if (DevicePath == NULL || *DevicePath == NULL) {
+ *Size = 0;
+ return NULL;
+ }
+
+ if (!IsDevicePathValid (*DevicePath, 0)) {
+ return NULL;
+ }
+
+ //
+ // Find the end of the device path instance
+ //
+ DevPath = *DevicePath;
+ while (!IsDevicePathEndType (DevPath)) {
+ DevPath = NextDevicePathNode (DevPath);
+ }
+
+ //
+ // Compute the size of the device path instance
+ //
+ *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+ //
+ // Make a copy and return the device path instance
+ //
+ Temp = DevPath->SubType;
+ DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ ReturnValue = DuplicateDevicePath (*DevicePath);
+ DevPath->SubType = Temp;
+
+ //
+ // If DevPath is the end of an entire device path, then another instance
+ // does not follow, so *DevicePath is set to NULL.
+ //
+ if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+ *DevicePath = NULL;
+ } else {
+ *DevicePath = NextDevicePathNode (DevPath);
+ }
+
+ return ReturnValue;
+}
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibCreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ //
+ // NodeLength is less than the size of the header.
+ //
+ return NULL;
+ }
+
+ DevicePath = AllocateZeroPool (NodeLength);
+ if (DevicePath != NULL) {
+ DevicePath->Type = NodeType;
+ DevicePath->SubType = NodeSubType;
+ SetDevicePathNodeLength (DevicePath, NodeLength);
+ }
+
+ return DevicePath;
+}
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+UefiDevicePathLibIsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (DevicePath == NULL) {
+ return FALSE;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0)) {
+ return FALSE;
+ }
+
+ Node = DevicePath;
+ while (!IsDevicePathEnd (Node)) {
+ if (IsDevicePathEndInstance (Node)) {
+ return TRUE;
+ }
+
+ Node = NextDevicePathNode (Node);
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Retrieves the device path protocol from a handle.
+
+ This function returns the device path protocol from the handle specified by Handle.
+ If Handle is NULL or Handle does not contain a device path protocol, then NULL
+ is returned.
+
+ @param Handle The handle from which to retrieve the device
+ path protocol.
+
+ @return The device path protocol from the handle specified by Handle.
+
+**/
+/*
+EFI_DEVICE_PATH_PROTOCOL *
+DevicePathFromHandle (
+ EFI_HANDLE Handle
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ DevicePath = NULL;
+ }
+ return DevicePath;
+}
+*/
+/**
+ Allocates a device path for a file and appends it to an existing device path.
+
+ If Device is a valid device handle that contains a device path protocol, then a device path for
+ the file specified by FileName is allocated and appended to the device path associated with the
+ handle Device. The allocated device path is returned. If Device is NULL or Device is a handle
+ that does not support the device path protocol, then a device path containing a single device
+ path node for the file specified by FileName is allocated and returned.
+ The memory for the new device path is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ If FileName is NULL, then ASSERT().
+ If FileName is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Device A pointer to a device handle. This parameter
+ is optional and may be NULL.
+ @param FileName A pointer to a Null-terminated Unicode string.
+
+ @return The allocated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+FileDevicePath (
+ EFI_HANDLE Device, OPTIONAL
+ CONST CHAR16 *FileName
+ )
+{
+ UINTN Size;
+ FILEPATH_DEVICE_PATH *FilePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;
+
+ DevicePath = NULL;
+
+ Size = StrSize (FileName);
+ FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
+ if (FileDevicePath != NULL) {
+ FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
+ FilePath->Header.Type = MEDIA_DEVICE_PATH;
+ FilePath->Header.SubType = MEDIA_FILEPATH_DP;
+ memcpy (&FilePath->PathName, FileName, Size);
+ SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
+ SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
+
+ //if (Device != NULL) {
+ // DevicePath = DevicePathFromHandle (Device);
+ //}
+
+ DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
+ free (FileDevicePath);
+ }
+
+ return DevicePath;
+}
+
+CHAR16
+InternalCharToUpper (
+ CHAR16 Char
+ )
+{
+ if (Char >= L'a' && Char <= L'z') {
+ return (CHAR16) (Char - (L'a' - L'A'));
+ }
+
+ return Char;
+}
+
+UINTN
+StrnLenS (
+ CONST CHAR16 *String,
+ UINTN MaxSize
+ )
+{
+ UINTN Length;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
+ //
+ if ((String == NULL) || (MaxSize == 0)) {
+ return 0;
+ }
+
+ Length = 0;
+ while (String[Length] != 0) {
+ if (Length >= MaxSize - 1) {
+ return MaxSize;
+ }
+ Length++;
+ }
+ return Length;
+}
+
+
+VOID *
+InternalAllocatePool (
+ UINTN AllocationSize
+ )
+{
+ VOID * Memory;
+
+ Memory = malloc(AllocationSize);
+ ASSERT(Memory != NULL);
+ return Memory;
+}
+
+
+VOID *
+InternalReallocatePool (
+ UINTN OldSize,
+ UINTN NewSize,
+ VOID *OldBuffer OPTIONAL
+ )
+{
+ VOID *NewBuffer;
+
+ NewBuffer = AllocateZeroPool (NewSize);
+ if (NewBuffer != NULL && OldBuffer != NULL) {
+ memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
+ free(OldBuffer);
+ }
+ return NewBuffer;
+}
+
+VOID *
+ReallocatePool (
+ UINTN OldSize,
+ UINTN NewSize,
+ VOID *OldBuffer OPTIONAL
+ )
+{
+ return InternalReallocatePool (OldSize, NewSize, OldBuffer);
+}
+
+/**
+ Returns the length of a Null-terminated Unicode string.
+
+ This function returns the number of Unicode characters in the Null-terminated
+ Unicode string specified by String.
+
+ If String is NULL, then ASSERT().
+ If String is not aligned on a 16-bit boundary, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the
+ Null-terminator, then ASSERT().
+
+ @param String A pointer to a Null-terminated Unicode string.
+
+ @return The length of String.
+
+**/
+UINTN
+StrLen (
+ CONST CHAR16 *String
+ )
+{
+ UINTN Length;
+
+ ASSERT (String != NULL);
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ for (Length = 0; *String != L'\0'; String++, Length++) {
+ //
+ // If PcdMaximumUnicodeStringLength is not zero,
+ // length should not more than PcdMaximumUnicodeStringLength
+ //
+ }
+ return Length;
+}
+
+BOOLEAN
+InternalSafeStringIsOverlap (
+ IN VOID *Base1,
+ IN UINTN Size1,
+ IN VOID *Base2,
+ IN UINTN Size2
+ )
+{
+ if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
+ (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOLEAN
+InternalSafeStringNoStrOverlap (
+ IN CHAR16 *Str1,
+ IN UINTN Size1,
+ IN CHAR16 *Str2,
+ IN UINTN Size2
+ )
+{
+ return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
+}
+
+RETURN_STATUS
+StrDecimalToUintnS (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINTN *Data
+ )
+{
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. Neither String nor Data shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. The length of String shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+
+ //
+ // Ignore the pad spaces (space or tab)
+ //
+ while ((*String == L' ') || (*String == L'\t')) {
+ String++;
+ }
+
+ //
+ // Ignore leading Zeros after the spaces
+ //
+ while (*String == L'0') {
+ String++;
+ }
+
+ *Data = 0;
+
+ while (InternalIsDecimalDigitCharacter (*String)) {
+ //
+ // If the number represented by String overflows according to the range
+ // defined by UINTN, then MAX_UINTN is stored in *Data and
+ // RETURN_UNSUPPORTED is returned.
+ //
+ if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {
+ *Data = MAX_UINTN;
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_UNSUPPORTED;
+ }
+
+ *Data = *Data * 10 + (*String - L'0');
+ String++;
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_SUCCESS;
+}
+
+/**
+ Convert a Null-terminated Unicode decimal string to a value of type UINT64.
+
+ This function outputs a value of type UINT64 by interpreting the contents of
+ the Unicode string specified by String as a decimal number. The format of the
+ input Unicode string String is:
+
+ [spaces] [decimal digits].
+
+ The valid decimal digit character is in the range [0-9]. The function will
+ ignore the pad space, which includes spaces or tab characters, before
+ [decimal digits]. The running zero in the beginning of [decimal digits] will
+ be ignored. Then, the function stops at the first character that is a not a
+ valid decimal character or a Null-terminator, whichever one comes first.
+
+ If String is NULL, then ASSERT().
+ If Data is NULL, then ASSERT().
+ If String is not aligned in a 16-bit boundary, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the
+ Null-terminator, then ASSERT().
+
+ If String has no valid decimal digits in the above format, then 0 is stored
+ at the location pointed to by Data.
+ If the number represented by String exceeds the range defined by UINT64, then
+ MAX_UINT64 is stored at the location pointed to by Data.
+
+ If EndPointer is not NULL, a pointer to the character that stopped the scan
+ is stored at the location pointed to by EndPointer. If String has no valid
+ decimal digits right after the optional pad spaces, the value of String is
+ stored at the location pointed to by EndPointer.
+
+ @param String Pointer to a Null-terminated Unicode string.
+ @param EndPointer Pointer to character that stops scan.
+ @param Data Pointer to the converted value.
+
+ @retval RETURN_SUCCESS Value is translated from String.
+ @retval RETURN_INVALID_PARAMETER If String is NULL.
+ If Data is NULL.
+ If PcdMaximumUnicodeStringLength is not
+ zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode
+ characters, not including the
+ Null-terminator.
+ @retval RETURN_UNSUPPORTED If the number represented by String exceeds
+ the range defined by UINT64.
+
+**/
+RETURN_STATUS
+StrDecimalToUint64S (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINT64 *Data
+ )
+{
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. Neither String nor Data shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. The length of String shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+
+ //
+ // Ignore the pad spaces (space or tab)
+ //
+ while ((*String == L' ') || (*String == L'\t')) {
+ String++;
+ }
+
+ //
+ // Ignore leading Zeros after the spaces
+ //
+ while (*String == L'0') {
+ String++;
+ }
+
+ *Data = 0;
+
+ while (InternalIsDecimalDigitCharacter (*String)) {
+ //
+ // If the number represented by String overflows according to the range
+ // defined by UINT64, then MAX_UINT64 is stored in *Data and
+ // RETURN_UNSUPPORTED is returned.
+ //
+ if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) {
+ *Data = MAX_UINT64;
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_UNSUPPORTED;
+ }
+
+ *Data = (*Data) * 10 + (*String - L'0');
+ String++;
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_SUCCESS;
+}
+
+/**
+ Convert a Null-terminated Unicode hexadecimal string to a value of type
+ UINTN.
+
+ This function outputs a value of type UINTN by interpreting the contents of
+ the Unicode string specified by String as a hexadecimal number. The format of
+ the input Unicode string String is:
+
+ [spaces][zeros][x][hexadecimal digits].
+
+ The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+ The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
+ If "x" appears in the input string, it must be prefixed with at least one 0.
+ The function will ignore the pad space, which includes spaces or tab
+ characters, before [zeros], [x] or [hexadecimal digit]. The running zero
+ before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
+ after [x] or the first valid hexadecimal digit. Then, the function stops at
+ the first character that is a not a valid hexadecimal character or NULL,
+ whichever one comes first.
+
+ If String is NULL, then ASSERT().
+ If Data is NULL, then ASSERT().
+ If String is not aligned in a 16-bit boundary, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the
+ Null-terminator, then ASSERT().
+
+ If String has no valid hexadecimal digits in the above format, then 0 is
+ stored at the location pointed to by Data.
+ If the number represented by String exceeds the range defined by UINTN, then
+ MAX_UINTN is stored at the location pointed to by Data.
+
+ If EndPointer is not NULL, a pointer to the character that stopped the scan
+ is stored at the location pointed to by EndPointer. If String has no valid
+ hexadecimal digits right after the optional pad spaces, the value of String
+ is stored at the location pointed to by EndPointer.
+
+ @param String Pointer to a Null-terminated Unicode string.
+ @param EndPointer Pointer to character that stops scan.
+ @param Data Pointer to the converted value.
+
+ @retval RETURN_SUCCESS Value is translated from String.
+ @retval RETURN_INVALID_PARAMETER If String is NULL.
+ If Data is NULL.
+ If PcdMaximumUnicodeStringLength is not
+ zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode
+ characters, not including the
+ Null-terminator.
+ @retval RETURN_UNSUPPORTED If the number represented by String exceeds
+ the range defined by UINTN.
+
+**/
+RETURN_STATUS
+StrHexToUintnS (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINTN *Data
+ )
+{
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. Neither String nor Data shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. The length of String shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+
+ //
+ // Ignore the pad spaces (space or tab)
+ //
+ while ((*String == L' ') || (*String == L'\t')) {
+ String++;
+ }
+
+ //
+ // Ignore leading Zeros after the spaces
+ //
+ while (*String == L'0') {
+ String++;
+ }
+
+ if (InternalCharToUpper (*String) == L'X') {
+ if (*(String - 1) != L'0') {
+ *Data = 0;
+ return RETURN_SUCCESS;
+ }
+ //
+ // Skip the 'X'
+ //
+ String++;
+ }
+
+ *Data = 0;
+
+ while (InternalIsHexaDecimalDigitCharacter (*String)) {
+ //
+ // If the number represented by String overflows according to the range
+ // defined by UINTN, then MAX_UINTN is stored in *Data and
+ // RETURN_UNSUPPORTED is returned.
+ //
+ if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {
+ *Data = MAX_UINTN;
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_UNSUPPORTED;
+ }
+
+ *Data = (*Data << 4) + InternalHexCharToUintn (*String);
+ String++;
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_SUCCESS;
+}
+RETURN_STATUS
+StrHexToUint64S (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINT64 *Data
+ )
+{
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. Neither String nor Data shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. The length of String shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+
+ //
+ // Ignore the pad spaces (space or tab)
+ //
+ while ((*String == L' ') || (*String == L'\t')) {
+ String++;
+ }
+
+ //
+ // Ignore leading Zeros after the spaces
+ //
+ while (*String == L'0') {
+ String++;
+ }
+
+ if (InternalCharToUpper (*String) == L'X') {
+ if (*(String - 1) != L'0') {
+ *Data = 0;
+ return RETURN_SUCCESS;
+ }
+ //
+ // Skip the 'X'
+ //
+ String++;
+ }
+
+ *Data = 0;
+
+ while (InternalIsHexaDecimalDigitCharacter (*String)) {
+ //
+ // If the number represented by String overflows according to the range
+ // defined by UINT64, then MAX_UINT64 is stored in *Data and
+ // RETURN_UNSUPPORTED is returned.
+ //
+ if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) {
+ *Data = MAX_UINT64;
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_UNSUPPORTED;
+ }
+
+ *Data = ((*Data) << 4) + InternalHexCharToUintn (*String);
+ String++;
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_SUCCESS;
+}
+
+UINT64
+StrDecimalToUint64 (
+ CONST CHAR16 *String
+ )
+{
+ UINT64 Result;
+
+ StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);
+ return Result;
+}
+
+
+UINT64
+StrHexToUint64 (
+ CONST CHAR16 *String
+ )
+{
+ UINT64 Result;
+
+ StrHexToUint64S (String, (CHAR16 **) NULL, &Result);
+ return Result;
+}
+
+UINTN
+StrDecimalToUintn (
+ CONST CHAR16 *String
+ )
+{
+ UINTN Result;
+
+ StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result);
+ return Result;
+}
+
+UINTN
+StrHexToUintn (
+ CONST CHAR16 *String
+ )
+{
+ UINTN Result;
+
+ StrHexToUintnS (String, (CHAR16 **) NULL, &Result);
+ return Result;
+}
+
+UINTN
+StrSize (
+ CONST CHAR16 *String
+ )
+{
+ return (StrLen (String) + 1) * sizeof (*String);
+}
+
+
+UINT64
+ReadUnaligned64 (
+ CONST UINT64 *Buffer
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return *Buffer;
+}
+
+UINT64
+WriteUnaligned64 (
+ UINT64 *Buffer,
+ UINT64 Value
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return *Buffer = Value;
+}
+
+
+EFI_GUID *
+CopyGuid (
+ EFI_GUID *DestinationGuid,
+ CONST EFI_GUID *SourceGuid
+ )
+{
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid)
+ );
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid + 1,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
+ );
+ return DestinationGuid;
+}
+
+UINT16
+SwapBytes16 (
+ UINT16 Value
+ )
+{
+ return (UINT16) ((Value<< 8) | (Value>> 8));
+}
+
+
+UINT32
+SwapBytes32 (
+ UINT32 Value
+ )
+{
+ UINT32 LowerBytes;
+ UINT32 HigherBytes;
+
+ LowerBytes = (UINT32) SwapBytes16 ((UINT16) Value);
+ HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16));
+ return (LowerBytes << 16 | HigherBytes);
+}
+
+BOOLEAN
+InternalIsDecimalDigitCharacter (
+ CHAR16 Char
+ )
+{
+ return (BOOLEAN) (Char >= L'0' && Char <= L'9');
+}
+
+VOID *
+InternalAllocateCopyPool (
+ UINTN AllocationSize,
+ CONST VOID *Buffer
+ )
+{
+ VOID *Memory;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
+
+ Memory = malloc (AllocationSize);
+ if (Memory != NULL) {
+ Memory = memcpy (Memory, Buffer, AllocationSize);
+ }
+ return Memory;
+}
+
+BOOLEAN
+InternalIsHexaDecimalDigitCharacter (
+ CHAR16 Char
+ )
+{
+
+ return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
+ (Char >= L'A' && Char <= L'F') ||
+ (Char >= L'a' && Char <= L'f'));
+}
+
+UINTN
+InternalHexCharToUintn (
+ CHAR16 Char
+ )
+{
+ if (InternalIsDecimalDigitCharacter (Char)) {
+ return Char - L'0';
+ }
+
+ return (10 + InternalCharToUpper (Char) - L'A');
+}
+
+
+/**
+ Convert a Null-terminated Unicode hexadecimal string to a byte array.
+
+ This function outputs a byte array by interpreting the contents of
+ the Unicode string specified by String in hexadecimal format. The format of
+ the input Unicode string String is:
+
+ [XX]*
+
+ X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+ The function decodes every two hexadecimal digit characters as one byte. The
+ decoding stops after Length of characters and outputs Buffer containing
+ (Length / 2) bytes.
+
+ If String is not aligned in a 16-bit boundary, then ASSERT().
+
+ If String is NULL, then ASSERT().
+
+ If Buffer is NULL, then ASSERT().
+
+ If Length is not multiple of 2, then ASSERT().
+
+ If PcdMaximumUnicodeStringLength is not zero and Length is greater than
+ PcdMaximumUnicodeStringLength, then ASSERT().
+
+ If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+ @param String Pointer to a Null-terminated Unicode string.
+ @param Length The number of Unicode characters to decode.
+ @param Buffer Pointer to the converted bytes array.
+ @param MaxBufferSize The maximum size of Buffer.
+
+ @retval RETURN_SUCCESS Buffer is translated from String.
+ @retval RETURN_INVALID_PARAMETER If String is NULL.
+ If Data is NULL.
+ If Length is not multiple of 2.
+ If PcdMaximumUnicodeStringLength is not zero,
+ and Length is greater than
+ PcdMaximumUnicodeStringLength.
+ @retval RETURN_UNSUPPORTED If Length of characters from String contain
+ a character that is not valid hexadecimal
+ digit characters, or a Null-terminator.
+ @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+StrHexToBytes (
+ CONST CHAR16 *String,
+ UINTN Length,
+ UINT8 *Buffer,
+ UINTN MaxBufferSize
+ )
+{
+ UINTN Index;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. None of String or Buffer shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. Length shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ //
+ // 3. Length shall not be odd.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
+
+ //
+ // 4. MaxBufferSize shall equal to or greater than Length / 2.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
+
+ //
+ // 5. String shall not contains invalid hexadecimal digits.
+ //
+ for (Index = 0; Index < Length; Index++) {
+ if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
+ break;
+ }
+ }
+ if (Index != Length) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Convert the hex string to bytes.
+ //
+ for(Index = 0; Index < Length; Index++) {
+
+ //
+ // For even characters, write the upper nibble for each buffer byte,
+ // and for even characters, the lower nibble.
+ //
+ if ((Index & BIT0) == 0) {
+ Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4;
+ } else {
+ Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
+ }
+ }
+ return RETURN_SUCCESS;
+}
+
+/**
+ Convert a Null-terminated Unicode GUID string to a value of type
+ EFI_GUID.
+
+ This function outputs a GUID value by interpreting the contents of
+ the Unicode string specified by String. The format of the input
+ Unicode string String consists of 36 characters, as follows:
+
+ aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+ The pairs aa - pp are two characters in the range [0-9], [a-f] and
+ [A-F], with each pair representing a single byte hexadecimal value.
+
+ The mapping between String and the EFI_GUID structure is as follows:
+ aa Data1[24:31]
+ bb Data1[16:23]
+ cc Data1[8:15]
+ dd Data1[0:7]
+ ee Data2[8:15]
+ ff Data2[0:7]
+ gg Data3[8:15]
+ hh Data3[0:7]
+ ii Data4[0:7]
+ jj Data4[8:15]
+ kk Data4[16:23]
+ ll Data4[24:31]
+ mm Data4[32:39]
+ nn Data4[40:47]
+ oo Data4[48:55]
+ pp Data4[56:63]
+
+ If String is NULL, then ASSERT().
+ If Guid is NULL, then ASSERT().
+ If String is not aligned in a 16-bit boundary, then ASSERT().
+
+ @param String Pointer to a Null-terminated Unicode string.
+ @param Guid Pointer to the converted GUID.
+
+ @retval RETURN_SUCCESS Guid is translated from String.
+ @retval RETURN_INVALID_PARAMETER If String is NULL.
+ If Data is NULL.
+ @retval RETURN_UNSUPPORTED If String is not as the above format.
+
+**/
+RETURN_STATUS
+StrToGuid (
+ CONST CHAR16 *String,
+ EFI_GUID *Guid
+ )
+{
+ RETURN_STATUS Status;
+ EFI_GUID LocalGuid;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. None of String or Guid shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // Get aabbccdd in big-endian.
+ //
+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
+ return RETURN_UNSUPPORTED;
+ }
+ //
+ // Convert big-endian to little-endian.
+ //
+ LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
+ String += 2 * sizeof (LocalGuid.Data1) + 1;
+
+ //
+ // Get eeff in big-endian.
+ //
+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
+ return RETURN_UNSUPPORTED;
+ }
+ //
+ // Convert big-endian to little-endian.
+ //
+ LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
+ String += 2 * sizeof (LocalGuid.Data2) + 1;
+
+ //
+ // Get gghh in big-endian.
+ //
+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
+ return RETURN_UNSUPPORTED;
+ }
+ //
+ // Convert big-endian to little-endian.
+ //
+ LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
+ String += 2 * sizeof (LocalGuid.Data3) + 1;
+
+ //
+ // Get iijj.
+ //
+ Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
+ if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
+ return RETURN_UNSUPPORTED;
+ }
+ String += 2 * 2 + 1;
+
+ //
+ // Get kkllmmnnoopp.
+ //
+ Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
+ if (RETURN_ERROR (Status)) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ CopyGuid (Guid, &LocalGuid);
+ return RETURN_SUCCESS;
+}
+
+/**
+ Compares up to a specified length the contents of two Null-terminated Unicode strings,
+ and returns the difference between the first mismatched Unicode characters.
+
+ This function compares the Null-terminated Unicode string FirstString to the
+ Null-terminated Unicode string SecondString. At most, Length Unicode
+ characters will be compared. If Length is 0, then 0 is returned. If
+ FirstString is identical to SecondString, then 0 is returned. Otherwise, the
+ value returned is the first mismatched Unicode character in SecondString
+ subtracted from the first mismatched Unicode character in FirstString.
+
+ If Length > 0 and FirstString is NULL, then ASSERT().
+ If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
+ If Length > 0 and SecondString is NULL, then ASSERT().
+ If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
+ PcdMaximumUnicodeStringLength, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+ then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+ then ASSERT().
+
+ @param FirstString A pointer to a Null-terminated Unicode string.
+ @param SecondString A pointer to a Null-terminated Unicode string.
+ @param Length The maximum number of Unicode characters to compare.
+
+ @retval 0 FirstString is identical to SecondString.
+ @return others FirstString is not identical to SecondString.
+
+**/
+INTN
+StrnCmp (
+ CONST CHAR16 *FirstString,
+ CONST CHAR16 *SecondString,
+ UINTN Length
+ )
+{
+ if (Length == 0) {
+ return 0;
+ }
+
+ //
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
+ // Length tests are performed inside StrLen().
+ //
+ ASSERT (StrSize (FirstString) != 0);
+ ASSERT (StrSize (SecondString) != 0);
+
+ while ((*FirstString != L'\0') &&
+ (*SecondString != L'\0') &&
+ (*FirstString == *SecondString) &&
+ (Length > 1)) {
+ FirstString++;
+ SecondString++;
+ Length--;
+ }
+
+ return *FirstString - *SecondString;
+}
+
+VOID *
+AllocateCopyPool (
+ UINTN AllocationSize,
+ CONST VOID *Buffer
+ )
+{
+ return InternalAllocateCopyPool (AllocationSize, Buffer);
+}
+
+INTN
+StrCmp (
+ CONST CHAR16 *FirstString,
+ CONST CHAR16 *SecondString
+ )
+{
+ //
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
+ //
+ ASSERT (StrSize (FirstString) != 0);
+ ASSERT (StrSize (SecondString) != 0);
+
+ while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
+ FirstString++;
+ SecondString++;
+ }
+ return *FirstString - *SecondString;
+}
+
+UINT64
+SwapBytes64 (
+ UINT64 Value
+ )
+{
+ return InternalMathSwapBytes64 (Value);
+}
+
+UINT64
+InternalMathSwapBytes64 (
+ UINT64 Operand
+ )
+{
+ UINT64 LowerBytes;
+ UINT64 HigherBytes;
+
+ LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand);
+ HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));
+
+ return (LowerBytes << 32 | HigherBytes);
+}
+
+RETURN_STATUS
+StrToIpv4Address (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ EFI_IPv4_ADDRESS *Address,
+ UINT8 *PrefixLength
+ )
+{
+ RETURN_STATUS Status;
+ UINTN AddressIndex;
+ UINTN Uintn;
+ EFI_IPv4_ADDRESS LocalAddress;
+ UINT8 LocalPrefixLength;
+ CHAR16 *Pointer;
+
+ LocalPrefixLength = MAX_UINT8;
+ LocalAddress.Addr[0] = 0;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. None of String or Guid shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+ for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+ if (!InternalIsDecimalDigitCharacter (*Pointer)) {
+ //
+ // D or P contains invalid characters.
+ //
+ break;
+ }
+
+ //
+ // Get D or P.
+ //
+ Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer, &Uintn);
+ if (RETURN_ERROR (Status)) {
+ return RETURN_UNSUPPORTED;
+ }
+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+ //
+ // It's P.
+ //
+ if (Uintn > 32) {
+ return RETURN_UNSUPPORTED;
+ }
+ LocalPrefixLength = (UINT8) Uintn;
+ } else {
+ //
+ // It's D.
+ //
+ if (Uintn > MAX_UINT8) {
+ return RETURN_UNSUPPORTED;
+ }
+ LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
+ AddressIndex++;
+ }
+
+ //
+ // Check the '.' or '/', depending on the AddressIndex.
+ //
+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+ if (*Pointer == L'/') {
+ //
+ // '/P' is in the String.
+ // Skip "/" and get P in next loop.
+ //
+ Pointer++;
+ } else {
+ //
+ // '/P' is not in the String.
+ //
+ break;
+ }
+ } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+ if (*Pointer == L'.') {
+ //
+ // D should be followed by '.'
+ //
+ Pointer++;
+ } else {
+ return RETURN_UNSUPPORTED;
+ }
+ }
+ }
+
+ if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ memcpy (Address, &LocalAddress, sizeof (*Address));
+ if (PrefixLength != NULL) {
+ *PrefixLength = LocalPrefixLength;
+ }
+ if (EndPointer != NULL) {
+ *EndPointer = Pointer;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+StrToIpv6Address (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ EFI_IPv6_ADDRESS *Address,
+ UINT8 *PrefixLength
+ )
+{
+ RETURN_STATUS Status;
+ UINTN AddressIndex;
+ UINTN Uintn;
+ EFI_IPv6_ADDRESS LocalAddress;
+ UINT8 LocalPrefixLength;
+ CONST CHAR16 *Pointer;
+ CHAR16 *End;
+ UINTN CompressStart;
+ BOOLEAN ExpectPrefix;
+
+ LocalPrefixLength = MAX_UINT8;
+ CompressStart = ARRAY_SIZE (Address->Addr);
+ ExpectPrefix = FALSE;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. None of String or Guid shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+ for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+ if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
+ if (*Pointer != L':') {
+ //
+ // ":" or "/" should be followed by digit characters.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Meet second ":" after previous ":" or "/"
+ // or meet first ":" in the beginning of String.
+ //
+ if (ExpectPrefix) {
+ //
+ // ":" shall not be after "/"
+ //
+ return RETURN_UNSUPPORTED;
+ }
+
+ if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
+ //
+ // "::" can only appear once.
+ // "::" can only appear when address is not full length.
+ //
+ return RETURN_UNSUPPORTED;
+ } else {
+ //
+ // Remember the start of zero compressing.
+ //
+ CompressStart = AddressIndex;
+ Pointer++;
+
+ if (CompressStart == 0) {
+ if (*Pointer != L':') {
+ //
+ // Single ":" shall not be in the beginning of String.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ Pointer++;
+ }
+ }
+ }
+
+ if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
+ if (*Pointer == L'/') {
+ //
+ // Might be optional "/P" after "::".
+ //
+ if (CompressStart != AddressIndex) {
+ return RETURN_UNSUPPORTED;
+ }
+ } else {
+ break;
+ }
+ } else {
+ if (!ExpectPrefix) {
+ //
+ // Get X.
+ //
+ Status = StrHexToUintnS (Pointer, &End, &Uintn);
+ if (RETURN_ERROR (Status) || End - Pointer > 4) {
+ //
+ // Number of hexadecimal digit characters is no more than 4.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ Pointer = End;
+ //
+ // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
+ //
+ ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
+ LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
+ LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
+ AddressIndex += 2;
+ } else {
+ //
+ // Get P, then exit the loop.
+ //
+ Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
+ if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
+ //
+ // Prefix length should not exceed 128.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ LocalPrefixLength = (UINT8) Uintn;
+ Pointer = End;
+ break;
+ }
+ }
+
+ //
+ // Skip ':' or "/"
+ //
+ if (*Pointer == L'/') {
+ ExpectPrefix = TRUE;
+ } else if (*Pointer == L':') {
+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+ //
+ // Meet additional ":" after all 8 16-bit address
+ //
+ break;
+ }
+ } else {
+ //
+ // Meet other character that is not "/" or ":" after all 8 16-bit address
+ //
+ break;
+ }
+ Pointer++;
+ }
+
+ if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
+ (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
+ ) {
+ //
+ // Full length of address shall not have compressing zeros.
+ // Non-full length of address shall have compressing zeros.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
+ memset (&Address->Addr[CompressStart], 0, ARRAY_SIZE (Address->Addr) - AddressIndex);
+ if (AddressIndex > CompressStart) {
+ memcpy (
+ &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
+ &LocalAddress.Addr[CompressStart],
+ AddressIndex - CompressStart
+ );
+ }
+
+ if (PrefixLength != NULL) {
+ *PrefixLength = LocalPrefixLength;
+ }
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) Pointer;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+RETURN_STATUS
+UnicodeStrToAsciiStrS (
+ CONST CHAR16 *Source,
+ CHAR8 *Destination,
+ UINTN DestMax
+ )
+{
+ UINTN SourceLen;
+
+ ASSERT (((UINTN) Source & BIT0) == 0);
+
+ //
+ // 1. Neither Destination nor Source shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
+ //
+ if (ASCII_RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ //
+ // 3. DestMax shall not equal zero.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
+
+ //
+ // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
+ //
+ SourceLen = StrnLenS (Source, DestMax);
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
+
+ //
+ // 5. Copying shall not take place between objects that overlap.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
+
+ //
+ // convert string
+ //
+ while (*Source != '\0') {
+ //
+ // If any Unicode characters in Source contain
+ // non-zero value in the upper 8 bits, then ASSERT().
+ //
+ ASSERT (*Source < 0x100);
+ *(Destination++) = (CHAR8) *(Source++);
+ }
+ *Destination = '\0';
+
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+StrCpyS (
+ CHAR16 *Destination,
+ UINTN DestMax,
+ CONST CHAR16 *Source
+ )
+{
+ UINTN SourceLen;
+
+ ASSERT (((UINTN) Destination & BIT0) == 0);
+ ASSERT (((UINTN) Source & BIT0) == 0);
+
+ //
+ // 1. Neither Destination nor Source shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. DestMax shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ //
+ // 3. DestMax shall not equal zero.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
+
+ //
+ // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
+ //
+ SourceLen = StrnLenS (Source, DestMax);
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
+
+ //
+ // 5. Copying shall not take place between objects that overlap.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
+
+ //
+ // The StrCpyS function copies the string pointed to by Source (including the terminating
+ // null character) into the array pointed to by Destination.
+ //
+ while (*Source != 0) {
+ *(Destination++) = *(Source++);
+ }
+ *Destination = 0;
+
+ return RETURN_SUCCESS;
+}
+
+VOID *
+AllocateZeroPool (
+ UINTN AllocationSize
+ )
+{
+ VOID * Memory;
+ Memory = malloc(AllocationSize);
+ ASSERT (Memory != NULL);
+ if (Memory == NULL) {
+ fprintf(stderr, "Not memory for malloc\n");
+ }
+ memset(Memory, 0, AllocationSize);
+ return Memory;
+}
+
+VOID *
+AllocatePool (
+ UINTN AllocationSize
+ )
+{
+ return InternalAllocatePool (AllocationSize);
+}
+
+UINT16
+WriteUnaligned16 (
+ UINT16 *Buffer,
+ UINT16 Value
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return *Buffer = Value;
+}
+
+UINT16
+ReadUnaligned16 (
+ CONST UINT16 *Buffer
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return *Buffer;
+}
diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.h b/BaseTools/Source/C/DevicePath/DevicePathUtilities.h
new file mode 100644
index 0000000..418615f
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.h
@@ -0,0 +1,555 @@
+/** @file
+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0.
+ Use to create and manipulate device paths and device nodes.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DEVICE_PATH_UTILITIES_H__
+#define __DEVICE_PATH_UTILITIES_H__
+
+///
+/// Device Path Utilities protocol
+///
+#define EFI_DEVICE_PATH_UTILITIES_GUID \
+ { \
+ 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \
+ }
+
+/**
+ Returns the size of the device path, in bytes.
+
+ @param DevicePath Points to the start of the EFI device path.
+
+ @return Size Size of the specified device path, in bytes, including the end-of-path tag.
+ @retval 0 DevicePath is NULL
+
+**/
+typedef
+UINTN
+( *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+
+/**
+ Create a duplicate of the specified path.
+
+ @param DevicePath Points to the source EFI device path.
+
+ @retval Pointer A pointer to the duplicate device path.
+ @retval NULL insufficient memory or DevicePath is NULL
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Create a new path by appending the second device path to the first.
+ If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned.
+ If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned.
+ If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is returned.
+
+ @param Src1 Points to the first device path.
+ @param Src2 Points to the second device path.
+
+ @retval Pointer A pointer to the newly created device path.
+ @retval NULL Memory could not be allocated
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_PATH)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+ CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+ );
+
+/**
+ Creates a new path by appending the device node to the device path.
+ If DeviceNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DeviceNode, followed by an end-of-device path device node is returned.
+ If both DeviceNode and DevicePath are NULL then a copy of an end-of-device-path device node is returned.
+
+ @param DevicePath Points to the device path.
+ @param DeviceNode Points to the device node.
+
+ @retval Pointer A pointer to the allocated device node.
+ @retval NULL There was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_NODE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+ );
+
+/**
+ Creates a new path by appending the specified device path instance to the specified device path.
+
+ @param DevicePath Points to the device path. If NULL, then ignored.
+ @param DevicePathInstance Points to the device path instance.
+
+ @retval Pointer A pointer to the newly created device path
+ @retval NULL Memory could not be allocated or DevicePathInstance is NULL.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ @param DevicePathInstance On input, this holds the pointer to the current device path
+ instance. On output, this holds the pointer to the next
+ device path instance or NULL if there are no more device
+ path instances in the device path.
+ @param DevicePathInstanceSize On output, this holds the size of the device path instance,
+ in bytes or zero, if DevicePathInstance is NULL.
+ If NULL, then the instance size is not output.
+
+ @retval Pointer A pointer to the copy of the current device path instance.
+ @retval NULL DevicePathInstace was NULL on entry or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)(
+ EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
+ UINTN *DevicePathInstanceSize
+ );
+
+/**
+ Creates a device node
+
+ @param NodeType NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+ the new device node.
+ @param NodeSubType NodeSubType is the device node sub-type
+ EFI_DEVICE_PATH.SubType) for the new device node.
+ @param NodeLength NodeLength is the length of the device node
+ (EFI_DEVICE_PATH.Length) for the new device node.
+
+ @retval Pointer A pointer to the newly created device node.
+ @retval NULL NodeLength is less than
+ the size of the header or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_CREATE_NODE)(
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+);
+
+/**
+ Returns whether a device path is multi-instance.
+
+ @param DevicePath Points to the device path. If NULL, then ignored.
+
+ @retval TRUE The device path has more than one instance
+ @retval FALSE The device path is empty or contains only a single instance.
+
+**/
+typedef
+BOOLEAN
+( *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+///
+/// This protocol is used to creates and manipulates device paths and device nodes.
+///
+typedef struct {
+ EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;
+ EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath;
+ EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath;
+ EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode;
+ EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance;
+ EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance;
+ EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance;
+ EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode;
+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;
+
+extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid;
+
+UINTN
+StrLen (
+ CONST CHAR16 *String
+ );
+
+VOID *
+AllocateCopyPool (
+ UINTN AllocationSize,
+ CONST VOID *Buffer
+ );
+
+INTN
+StrnCmp (
+ CONST CHAR16 *FirstString,
+ CONST CHAR16 *SecondString,
+ UINTN Length
+ );
+
+RETURN_STATUS
+StrToGuid (
+ CONST CHAR16 *String,
+ EFI_GUID *Guid
+ );
+
+RETURN_STATUS
+StrHexToBytes (
+ CONST CHAR16 *String,
+ UINTN Length,
+ UINT8 *Buffer,
+ UINTN MaxBufferSize
+ );
+
+UINTN
+InternalHexCharToUintn (
+ CHAR16 Char
+ );
+
+VOID *
+InternalAllocateCopyPool (
+ UINTN AllocationSize,
+ CONST VOID *Buffer
+ );
+
+BOOLEAN
+InternalIsDecimalDigitCharacter (
+ CHAR16 Char
+ );
+
+UINT32
+SwapBytes32 (
+ UINT32 Value
+ );
+
+UINT16
+SwapBytes16 (
+ UINT16 Value
+ );
+
+EFI_GUID *
+CopyGuid (
+ EFI_GUID *DestinationGuid,
+ CONST EFI_GUID *SourceGuid
+ );
+
+UINT64
+WriteUnaligned64 (
+ UINT64 *Buffer,
+ UINT64 Value
+ );
+
+UINT64
+ReadUnaligned64 (
+ CONST UINT64 *Buffer
+ );
+
+UINTN
+StrSize (
+ CONST CHAR16 *String
+ );
+
+UINTN
+StrHexToUintn (
+ CONST CHAR16 *String
+ );
+
+UINTN
+StrDecimalToUintn (
+ CONST CHAR16 *String
+ );
+
+UINT64
+StrHexToUint64 (
+ CONST CHAR16 *String
+ );
+
+UINT64
+StrDecimalToUint64 (
+ CONST CHAR16 *String
+ );
+
+RETURN_STATUS
+StrHexToUint64S (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ UINT64 *Data
+ );
+
+RETURN_STATUS
+StrHexToUintnS (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINTN *Data
+ );
+
+RETURN_STATUS
+StrDecimalToUint64S (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINT64 *Data
+ );
+
+RETURN_STATUS
+StrDecimalToUintnS (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINTN *Data
+ );
+
+VOID *
+ReallocatePool (
+ UINTN OldSize,
+ UINTN NewSize,
+ VOID *OldBuffer OPTIONAL
+ );
+
+VOID *
+InternalReallocatePool (
+ UINTN OldSize,
+ UINTN NewSize,
+ VOID *OldBuffer OPTIONAL
+ );
+
+VOID *
+InternalAllocateZeroPool (
+ UINTN AllocationSize
+ ) ;
+
+VOID *
+InternalAllocatePool (
+ UINTN AllocationSize
+ );
+
+UINTN
+StrnLenS (
+ CONST CHAR16 *String,
+ UINTN MaxSize
+ );
+
+CHAR16
+InternalCharToUpper (
+ CHAR16 Char
+ );
+
+UINTN
+DevicePathNodeLength (
+ CONST VOID *Node
+ );
+
+UINT16
+SetDevicePathNodeLength (
+ VOID *Node,
+ UINTN Length
+ );
+
+INTN
+StrCmp (
+ CONST CHAR16 *FirstString,
+ CONST CHAR16 *SecondString
+ );
+
+UINT64
+SwapBytes64 (
+ UINT64 Value
+ );
+
+UINT64
+InternalMathSwapBytes64 (
+ UINT64 Operand
+ );
+
+RETURN_STATUS
+StrToIpv4Address (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ EFI_IPv4_ADDRESS *Address,
+ UINT8 *PrefixLength
+ );
+
+RETURN_STATUS
+StrToIpv6Address (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ EFI_IPv6_ADDRESS *Address,
+ UINT8 *PrefixLength
+ );
+
+RETURN_STATUS
+StrCpyS (
+ CHAR16 *Destination,
+ UINTN DestMax,
+ CONST CHAR16 *Source
+ );
+
+RETURN_STATUS
+UnicodeStrToAsciiStrS (
+ CONST CHAR16 *Source,
+ CHAR8 *Destination,
+ UINTN DestMax
+ );
+VOID *
+AllocatePool (
+ UINTN AllocationSize
+ );
+
+VOID
+SetDevicePathEndNode (
+ VOID *Node
+ );
+
+BOOLEAN
+IsDevicePathValid (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ UINTN MaxSize
+ );
+
+UINT8
+DevicePathType (
+ CONST VOID *Node
+ );
+
+UINT8
+DevicePathSubType (
+ CONST VOID *Node
+ );
+
+UINTN
+DevicePathNodeLength (
+ CONST VOID *Node
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+NextDevicePathNode (
+ CONST VOID *Node
+ );
+
+BOOLEAN
+IsDevicePathEndType (
+ CONST VOID *Node
+ );
+
+BOOLEAN
+IsDevicePathEnd (
+ CONST VOID *Node
+ );
+BOOLEAN
+IsDevicePathEndInstance (
+ CONST VOID *Node
+ );
+
+UINT16
+SetDevicePathNodeLength (
+ VOID *Node,
+ UINTN Length
+ );
+
+VOID
+SetDevicePathEndNode (
+ VOID *Node
+ );
+
+UINTN
+UefiDevicePathLibGetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibDuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibGetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibCreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+BOOLEAN
+UefiDevicePathLibIsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+UINT16
+WriteUnaligned16 (
+ UINT16 *Buffer,
+ UINT16 Value
+ );
+
+UINT16
+ReadUnaligned16 (
+ CONST UINT16 *Buffer
+ );
+
+VOID *
+AllocateZeroPool (
+ UINTN AllocationSize
+ );
+
+BOOLEAN
+InternalIsHexaDecimalDigitCharacter (
+ CHAR16 Char
+ );
+
+BOOLEAN
+InternalSafeStringIsOverlap (
+ IN VOID *Base1,
+ IN UINTN Size1,
+ IN VOID *Base2,
+ IN UINTN Size2
+ );
+
+BOOLEAN
+InternalSafeStringNoStrOverlap (
+ IN CHAR16 *Str1,
+ IN UINTN Size1,
+ IN CHAR16 *Str2,
+ IN UINTN Size2
+ );
+
+#endif
diff --git a/BaseTools/Source/C/DevicePath/GNUmakefile b/BaseTools/Source/C/DevicePath/GNUmakefile
new file mode 100644
index 0000000..27f6fa1
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/GNUmakefile
@@ -0,0 +1,30 @@
+## @file
+# GNU/Linux makefile for 'DevicePath' module build.
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+ARCH ?= IA32
+MAKEROOT ?= ..
+
+APPNAME = DevicePath
+
+OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o DevicePathUtilities.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+ifeq ($(CYGWIN), CYGWIN)
+ LIBS += -L/lib/e2fsprogs -luuid
+endif
+
+ifeq ($(LINUX), Linux)
+ LIBS += -luuid
+endif
+
diff --git a/BaseTools/Source/C/DevicePath/Makefile b/BaseTools/Source/C/DevicePath/Makefile
new file mode 100644
index 0000000..a069c22
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/Makefile
@@ -0,0 +1,24 @@
+## @file
+# Windows makefile for 'DevicePath' module build.
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = DevicePath
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = DevicePath.obj UefiDevicePathLib.obj DevicePathFromText.obj DevicePathUtilities.obj
+
+#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
new file mode 100644
index 0000000..a2e0322
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
@@ -0,0 +1,298 @@
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment varibles. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "UefiDevicePathLib.h"
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+GetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibGetDevicePathSize (DevicePath);
+}
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibDuplicateDevicePath (DevicePath);
+}
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);
+}
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);
+}
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);
+}
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ )
+{
+ return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);
+}
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ )
+{
+ return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength);
+}
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+IsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);
+}
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ )
+{
+ return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ )
+{
+ return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);
+}
diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
new file mode 100644
index 0000000..e03fbd0
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
@@ -0,0 +1,473 @@
+/** @file
+ Definition for Device Path library.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _UEFI_DEVICE_PATH_LIB_H_
+#define _UEFI_DEVICE_PATH_LIB_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#ifdef __GNUC__
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+#include <Common/UefiBaseTypes.h>
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+#include "DevicePath.h"
+#include "DevicePathUtilities.h"
+#include "DevicePathFromText.h"
+
+
+#define IS_COMMA(a) ((a) == L',')
+#define IS_HYPHEN(a) ((a) == L'-')
+#define IS_DOT(a) ((a) == L'.')
+#define IS_LEFT_PARENTH(a) ((a) == L'(')
+#define IS_RIGHT_PARENTH(a) ((a) == L')')
+#define IS_SLASH(a) ((a) == L'/')
+#define IS_NULL(a) ((a) == L'\0')
+
+#define MAX_UINTN MAX_ADDRESS
+#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL)
+#define MAX_UINT16 ((UINT16)0xFFFF)
+#define MAX_UINT8 ((UINT8)0xFF)
+
+#define END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL))
+#define MAX_DEVICE_PATH_NODE_COUNT 1024
+#define SIZE_64KB 0x00010000
+#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
+#define ASCII_RSIZE_MAX 1000000
+#ifndef RSIZE_MAX
+#define RSIZE_MAX 1000000
+#endif
+
+//
+// Private Data structure
+//
+typedef
+EFI_DEVICE_PATH_PROTOCOL *
+(*DEVICE_PATH_FROM_TEXT) (
+ IN CHAR16 *Str
+ );
+
+typedef struct {
+ CHAR16 *Str;
+ UINTN Count;
+ UINTN Capacity;
+} POOL_PRINT;
+
+
+typedef struct {
+ CHAR16 *DevicePathNodeText;
+ DEVICE_PATH_FROM_TEXT Function;
+} DEVICE_PATH_FROM_TEXT_TABLE;
+
+typedef struct {
+ BOOLEAN ClassExist;
+ UINT8 Class;
+ BOOLEAN SubClassExist;
+ UINT8 SubClass;
+} USB_CLASS_TEXT;
+
+#define USB_CLASS_AUDIO 1
+#define USB_CLASS_CDCCONTROL 2
+#define USB_CLASS_HID 3
+#define USB_CLASS_IMAGE 6
+#define USB_CLASS_PRINTER 7
+#define USB_CLASS_MASS_STORAGE 8
+#define USB_CLASS_HUB 9
+#define USB_CLASS_CDCDATA 10
+#define USB_CLASS_SMART_CARD 11
+#define USB_CLASS_VIDEO 14
+#define USB_CLASS_DIAGNOSTIC 220
+#define USB_CLASS_WIRELESS 224
+
+#define USB_CLASS_RESERVE 254
+#define USB_SUBCLASS_FW_UPDATE 1
+#define USB_SUBCLASS_IRDA_BRIDGE 2
+#define USB_SUBCLASS_TEST 3
+
+#define RFC_1700_UDP_PROTOCOL 17
+#define RFC_1700_TCP_PROTOCOL 6
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Hid;
+ UINT32 Uid;
+ UINT32 Cid;
+ CHAR8 HidUidCidStr[3];
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 NetworkProtocol;
+ UINT16 LoginOption;
+ UINT64 Lun;
+ UINT16 TargetPortalGroupTag;
+ CHAR8 TargetName[1];
+} ISCSI_DEVICE_PATH_WITH_NAME;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEVICE_PATH_WITH_DATA;
+
+#pragma pack()
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+UefiDevicePathLibGetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibDuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ );
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ );
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibGetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ );
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibCreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+UefiDevicePathLibIsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ );
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+ EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+BOOLEAN
+IsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ );
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+UINTN
+GetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+CHAR16 *
+ConvertDeviceNodeToText (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ BOOLEAN DisplayOnly,
+ BOOLEAN AllowShortcuts
+ );
+
+CHAR16 *
+ConvertDevicePathToText (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ BOOLEAN DisplayOnly,
+ BOOLEAN AllowShortcuts
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ );
+
+
+#endif
diff --git a/BaseTools/Source/C/GNUmakefile b/BaseTools/Source/C/GNUmakefile
index 0dc7482..37421ad 100644
--- a/BaseTools/Source/C/GNUmakefile
+++ b/BaseTools/Source/C/GNUmakefile
@@ -65,11 +65,12 @@ APPLICATIONS = \
GenCrc32 \
GenVtf \
LzmaCompress \
Split \
TianoCompress \
- VolInfo
+ VolInfo \
+ DevicePath
SUBDIRS := $(LIBRARIES) $(APPLICATIONS)
$(LIBRARIES): $(MAKEROOT)/libs
$(APPLICATIONS): $(LIBRARIES) $(MAKEROOT)/bin $(VFRAUTOGEN)
diff --git a/BaseTools/Source/C/Makefile b/BaseTools/Source/C/Makefile
index 50be773..5428180 100644
--- a/BaseTools/Source/C/Makefile
+++ b/BaseTools/Source/C/Makefile
@@ -1,9 +1,9 @@
## @file
# Windows makefile for C tools build.
#
-# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
@@ -30,11 +30,12 @@ APPLICATIONS = \
GenVtf \
LzmaCompress \
Split \
TianoCompress \
VolInfo \
- VfrCompile
+ VfrCompile \
+ DevicePath
all: libs apps install
libs: $(LIBRARIES)
@echo.
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index c51b685..104a370 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -36,11 +36,11 @@ from CommonDataClass.DataClass import *
from Parsing import GetSplitValueList
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import uuid
from CommonDataClass.Exceptions import BadExpression
-
+import subprocess
## Regular expression used to find out place holders in string template
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
## Dictionary used to store file time stamp for quick re-access
gFileTimeStampCache = {} # {file path : file time stamp}
@@ -1472,11 +1472,42 @@ def AnalyzePcdExpression(Setting):
StartPos = Pos + 1
return FieldList
def ParseDevPathValue (Value):
- pass
+ DevPathList = [ "Path","HardwarePath","Pci","PcCard","MemoryMapped","VenHw","Ctrl","BMC","AcpiPath","Acpi","PciRoot",
+ "PcieRoot","Floppy","Keyboard","Serial","ParallelPort","AcpiEx","AcpiExp","AcpiAdr","Msg","Ata","Scsi",
+ "Fibre","FibreEx","I1394","USB","I2O","Infiniband","VenMsg","VenPcAnsi","VenVt100","VenVt100Plus",
+ "VenUtf8","UartFlowCtrl","SAS","SasEx","NVMe","UFS","SD","eMMC","DebugPort","MAC","IPv4","IPv6","Uart",
+ "UsbClass","UsbAudio","UsbCDCControl","UsbHID","UsbImage","UsbPrinter","UsbMassStorage","UsbHub",
+ "UsbCDCData","UsbSmartCard","UsbVideo","UsbDiagnostic","UsbWireless","UsbDeviceFirmwareUpdate",
+ "UsbIrdaBridge","UsbTestAndMeasurement","UsbWwid","Unit","iSCSI","Vlan","Uri","Bluetooth","Wi-Fi",
+ "MediaPath","HD","CDROM","VenMedia","Media","Fv","FvFile","Offset","RamDisk","VirtualDisk","VirtualCD",
+ "PersistentVirtualDisk","PersistentVirtualCD","BbsPath","BBS","Sata" ]
+ if '\\' in Value:
+ Value.replace('\\', '/').replace(' ', '')
+ for Item in Value.split('/'):
+ Key = Item.strip().split('(')[0]
+ if Key not in DevPathList:
+ pass
+
+ Cmd = 'DevicePath ' + '"' + Value + '"'
+ try:
+ p = subprocess.Popen(Cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ out, err = p.communicate()
+ except Exception, X:
+ raise BadExpression("DevicePath: %s" % (str(X)) )
+ finally:
+ subprocess._cleanup()
+ p.stdout.close()
+ p.stderr.close()
+ if err:
+ raise BadExpression("DevicePath: %s" % str(err))
+ Size = len(out.split())
+ out = ','.join(out.split())
+ return '{' + out + '}', Size
+
def ParseFieldValue (Value):
if type(Value) == type(0):
return Value, (Value.bit_length() + 7) / 8
if type(Value) <> type(''):
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 05b26a3..f9cd429 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -2060,11 +2060,11 @@ class DscBuildData(PlatformBuildClassObject):
ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
if ModuleFile in self._Modules:
continue
ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
PkgSet.update(ModuleData.Packages)
- self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
+ self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
return self._DecPcds
_Macros = property(_GetMacros)
Arch = property(_GetArch, _SetArch)
Platform = property(_GetPlatformName)
PlatformName = property(_GetPlatformName)
--
2.6.1.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Yonghong: For DevicePath definition, please define them in BaseTools\Source\C\Include\Protocol directory to align MdePkg layout. Thanks Liming >-----Original Message----- >From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of >Yonghong Zhu >Sent: Wednesday, December 27, 2017 12:40 AM >To: edk2-devel@lists.01.org >Cc: Feng, YunhuaX <yunhuax.feng@intel.com> >Subject: [edk2] [Patch 2/2] BaseTools: Add DevicePath support for PCD values > >Use C code parse device path to output hex string, and Python >run command when PCD Value need device path parse. > >https://bugzilla.tianocore.org/show_bug.cgi?id=541 > >Contributed-under: TianoCore Contribution Agreement 1.1 >Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com> >Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com> >--- > BaseTools/Source/BinaryFiles.txt | 3 +- > BaseTools/Source/C/DevicePath/DevicePath.c | 188 ++ > BaseTools/Source/C/DevicePath/DevicePath.h | 1404 ++++++++ > BaseTools/Source/C/DevicePath/DevicePathFromText.c | 3503 >++++++++++++++++++++ > BaseTools/Source/C/DevicePath/DevicePathFromText.h | 72 + > .../Source/C/DevicePath/DevicePathUtilities.c | 2352 +++++++++++++ > .../Source/C/DevicePath/DevicePathUtilities.h | 555 ++++ > BaseTools/Source/C/DevicePath/GNUmakefile | 30 + > BaseTools/Source/C/DevicePath/Makefile | 24 + > BaseTools/Source/C/DevicePath/UefiDevicePathLib.c | 298 ++ > BaseTools/Source/C/DevicePath/UefiDevicePathLib.h | 473 +++ > BaseTools/Source/C/GNUmakefile | 3 +- > BaseTools/Source/C/Makefile | 5 +- > BaseTools/Source/Python/Common/Misc.py | 35 +- > BaseTools/Source/Python/Workspace/DscBuildData.py | 2 +- > 15 files changed, 8940 insertions(+), 7 deletions(-) > create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.c > create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.h > create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.c > create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.h > create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.c > create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.h > create mode 100644 BaseTools/Source/C/DevicePath/GNUmakefile > create mode 100644 BaseTools/Source/C/DevicePath/Makefile > create mode 100644 BaseTools/Source/C/DevicePath/UefiDevicePathLib.c > create mode 100644 BaseTools/Source/C/DevicePath/UefiDevicePathLib.h > >diff --git a/BaseTools/Source/BinaryFiles.txt >b/BaseTools/Source/BinaryFiles.txt >index 7b014a7..a5273d4 100644 >--- a/BaseTools/Source/BinaryFiles.txt >+++ b/BaseTools/Source/BinaryFiles.txt >@@ -9,11 +9,11 @@ > # [ExtraFiles.Win32] section. > # The [CxFreeze.Win32] section is maintained by the owner of the Build >Server who > # must ensure that files that are required by the cx_freeze frozen binaries >are > # present in the Bin\Win32 directory. > # >-# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR> >+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR> > # > # This program and the accompanying materials are licensed and made >available under > # the terms and conditions of the BSD License which accompanies this >distribution. > # The full text of the license may be found at: > # http://opensource.org/licenses/bsd-license.php >@@ -57,10 +57,11 @@ TianoCompress.exe > Trim.exe > UPT.exe > VfrCompile.exe > VolInfo.exe > Pkcs7Sign.exe >+DevicePath.exe > > [ExtraFiles.Win32] > TestSigningPrivateKey.pem > config.ini > exception.xml >diff --git a/BaseTools/Source/C/DevicePath/DevicePath.c >b/BaseTools/Source/C/DevicePath/DevicePath.c >new file mode 100644 >index 0000000..6c32ad4 >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/DevicePath.c >@@ -0,0 +1,188 @@ >+/** @file >+ Definition for Device Path Tool. >+ >+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+This program and the accompanying materials >+are licensed and made available under the terms and conditions of the BSD >License >+which accompanies this distribution. The full text of the license may be >found at >+http://opensource.org/licenses/bsd-license.php >+ >+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+ >+**/ >+ >+#include "UefiDevicePathLib.h" >+ >+// >+// Utility Name >+// >+#define UTILITY_NAME "DevicePath" >+ >+// >+// Utility version information >+// >+#define UTILITY_MAJOR_VERSION 0 >+#define UTILITY_MINOR_VERSION 1 >+ >+EFI_GUID gEfiDebugPortDevicePathGuid = >DEVICE_PATH_MESSAGING_DEBUGPORT; >+EFI_GUID gEfiPcAnsiGuid = EFI_PC_ANSI_GUID; >+EFI_GUID gEfiVT100Guid = EFI_VT_100_GUID; >+EFI_GUID gEfiVT100PlusGuid = EFI_VT_100_PLUS_GUID; >+EFI_GUID gEfiVTUTF8Guid = EFI_VT_UTF8_GUID; >+EFI_GUID gEfiUartDevicePathGuid = EFI_UART_DEVICE_PATH_GUID; >+EFI_GUID gEfiSasDevicePathGuid = EFI_SAS_DEVICE_PATH_GUID; >+EFI_GUID gEfiVirtualDiskGuid = { 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, >0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }}; >+EFI_GUID gEfiVirtualCdGuid = { 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, >0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }}; >+EFI_GUID gEfiPersistentVirtualDiskGuid = { 0x5CEA02C9, 0x4D07, 0x69D3, >{0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }}; >+EFI_GUID gEfiPersistentVirtualCdGuid = { 0x08018188, 0x42CD, 0xBB48, {0x10, >0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }}; >+ >+STATIC >+VOID >+Version ( >+ VOID >+) >+/*++ >+ >+Routine Description: >+ >+ Displays the standard utility information to SDTOUT >+ >+Arguments: >+ >+ None >+ >+Returns: >+ >+ None >+ >+--*/ >+{ >+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, >UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION); >+} >+ >+STATIC >+VOID >+Usage ( >+ VOID >+ ) >+/*++ >+ >+Routine Description: >+ >+ Displays the utility usage syntax to STDOUT >+ >+Arguments: >+ >+ None >+ >+Returns: >+ >+ None >+ >+--*/ >+{ >+ // >+ // Summary usage >+ // >+ fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME); >+ >+ // >+ // Copyright declaration >+ // >+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights >reserved.\n\n"); >+ // >+ // Details Option >+ // >+ fprintf (stdout, "Options:\n"); >+ fprintf (stdout, " DevicePathString DevicePathString like as:\n" >+ " \"PciRoot(0)/Pci(0,0)\"\n" >+ " start with \" and end with \"\n" >+ " not support blank in device path string.\n"); >+ >+ fprintf (stdout, " --version Show program's version number and >exit.\n"); >+ fprintf (stdout, " -h, --help Show this help message and exit.\n"); >+} >+ >+ >+void print_mem(void const *vp, size_t n) >+{ >+ unsigned char const *p = vp; >+ for (size_t i=0; i<n; i++) { >+ printf("0x%02x ", p[i]); >+ } >+} >+ >+VOID >+Ascii2UnicodeString ( >+ CHAR8 *String, >+ CHAR16 *UniString >+ ) >+/*++ >+ >+Routine Description: >+ >+ Write ascii string as unicode string format to FILE >+ >+Arguments: >+ >+ String - Pointer to string that is written to FILE. >+ UniString - Pointer to unicode string >+ >+Returns: >+ >+ NULL >+ >+--*/ >+{ >+ while (*String != '\0') { >+ *(UniString++) = (CHAR16) *(String++); >+ } >+ // >+ // End the UniString with a NULL. >+ // >+ *UniString = '\0'; >+} >+ >+int main(int argc, CHAR8 *argv[]) >+{ >+ CHAR8 * Str; >+ CHAR16* Str16; >+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; >+ >+ if (argc == 1) { >+ Error (NULL, 0, 1001, "Missing options", "No input options specified."); >+ Usage (); >+ return STATUS_ERROR; >+ } >+ if ((stricmp (argv[1], "-h") == 0) || (stricmp (argv[1], "--help") == 0)) { >+ Version (); >+ Usage (); >+ return STATUS_SUCCESS; >+ } >+ >+ if (stricmp (argv[1], "--version") == 0) { >+ Version (); >+ return STATUS_SUCCESS; >+ } >+ Str = argv[1]; >+ if (Str == NULL) { >+ fprintf(stderr, "Invalid option value, Device Path can't be NULL"); >+ return STATUS_ERROR; >+ } >+ Str16 = (CHAR16 *)malloc(1024); >+ if (Str16 == NULL) { >+ fprintf(stderr, "Resource, memory cannot be allcoated"); >+ return STATUS_ERROR; >+ } >+ Ascii2UnicodeString(Str, Str16); >+ DevicePath = UefiDevicePathLibConvertTextToDevicePath(Str16); >+ while (!((DevicePath->Type == END_DEVICE_PATH_TYPE) && (DevicePath- >>SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)) ) >+ { >+ print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1] ><< 8)); >+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)DevicePath + >(DevicePath->Length[0] | DevicePath->Length[1] << 8)); >+ } >+ print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1] ><< 8)); >+ putchar('\n'); >+ return STATUS_SUCCESS; >+} >diff --git a/BaseTools/Source/C/DevicePath/DevicePath.h >b/BaseTools/Source/C/DevicePath/DevicePath.h >new file mode 100644 >index 0000000..389c993 >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/DevicePath.h >@@ -0,0 +1,1404 @@ >+/** @file >+ The device path protocol as defined in UEFI 2.0. >+ >+ The device path represents a programmatic path to a device, >+ from a software point of view. The path must persist from boot to boot, so >+ it can not contain things like PCI bus numbers that change from boot to boot. >+ >+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+This program and the accompanying materials are licensed and made >available under >+the terms and conditions of the BSD License that accompanies this >distribution. >+The full text of the license may be found at >+http://opensource.org/licenses/bsd-license.php. >+ >+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+ >+**/ >+ >+#ifndef __EFI_DEVICE_PATH_H__ >+#define __EFI_DEVICE_PATH_H__ >+ >+#include <Guid/PcAnsi.h> >+#include <IndustryStandard/Acpi3_0.h> >+ >+/// >+/// Device Path protocol. >+/// >+#define EFI_DEVICE_PATH_PROTOCOL_GUID \ >+ { \ >+ 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } >\ >+ } >+ >+/// >+/// Device Path guid definition for backward-compatible with EFI1.1. >+/// >+#define DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL_GUID >+ >+#pragma pack(1) >+ >+/** >+ This protocol can be used on any device handle to obtain generic >path/location >+ information concerning the physical device or logical device. If the handle >does >+ not logically map to a physical device, the handle may not necessarily >support >+ the device path protocol. The device path describes the location of the >device >+ the handle is for. The size of the Device Path can be determined from the >structures >+ that make up the Device Path. >+**/ >+typedef struct { >+ UINT8 Type; ///< 0x01 Hardware Device Path. >+ ///< 0x02 ACPI Device Path. >+ ///< 0x03 Messaging Device Path. >+ ///< 0x04 Media Device Path. >+ ///< 0x05 BIOS Boot Specification Device Path. >+ ///< 0x7F End of Hardware Device Path. >+ >+ UINT8 SubType; ///< Varies by Type >+ ///< 0xFF End Entire Device Path, or >+ ///< 0x01 End This Instance of a Device Path and start a new >+ ///< Device Path. >+ >+ UINT8 Length[2]; ///< Specific Device Path data. Type and Sub-Type define >+ ///< type of data. Size of data is included in Length. >+ >+} EFI_DEVICE_PATH_PROTOCOL; >+ >+/// >+/// Device Path protocol definition for backward-compatible with EFI1.1. >+/// >+typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH; >+ >+/// >+/// Hardware Device Paths. >+/// >+#define HARDWARE_DEVICE_PATH 0x01 >+ >+/// >+/// PCI Device Path SubType. >+/// >+#define HW_PCI_DP 0x01 >+ >+/// >+/// PCI Device Path. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// PCI Function Number. >+ /// >+ UINT8 Function; >+ /// >+ /// PCI Device Number. >+ /// >+ UINT8 Device; >+} PCI_DEVICE_PATH; >+ >+/// >+/// PCCARD Device Path SubType. >+/// >+#define HW_PCCARD_DP 0x02 >+ >+/// >+/// PCCARD Device Path. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Function Number (0 = First Function). >+ /// >+ UINT8 FunctionNumber; >+} PCCARD_DEVICE_PATH; >+ >+/// >+/// Memory Mapped Device Path SubType. >+/// >+#define HW_MEMMAP_DP 0x03 >+ >+/// >+/// Memory Mapped Device Path. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// EFI_MEMORY_TYPE >+ /// >+ UINT32 MemoryType; >+ /// >+ /// Starting Memory Address. >+ /// >+ EFI_PHYSICAL_ADDRESS StartingAddress; >+ /// >+ /// Ending Memory Address. >+ /// >+ EFI_PHYSICAL_ADDRESS EndingAddress; >+} MEMMAP_DEVICE_PATH; >+ >+/// >+/// Hardware Vendor Device Path SubType. >+/// >+#define HW_VENDOR_DP 0x04 >+ >+/// >+/// The Vendor Device Path allows the creation of vendor-defined Device >Paths. A vendor must >+/// allocate a Vendor GUID for a Device Path. The Vendor GUID can then be >used to define the >+/// contents on the n bytes that follow in the Vendor Device Path node. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Vendor-assigned GUID that defines the data that follows. >+ /// >+ EFI_GUID Guid; >+ /// >+ /// Vendor-defined variable size data. >+ /// >+} VENDOR_DEVICE_PATH; >+ >+/// >+/// Controller Device Path SubType. >+/// >+#define HW_CONTROLLER_DP 0x05 >+ >+/// >+/// Controller Device Path. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Controller number. >+ /// >+ UINT32 ControllerNumber; >+} CONTROLLER_DEVICE_PATH; >+ >+/// >+/// BMC Device Path SubType. >+/// >+#define HW_BMC_DP 0x06 >+ >+/// >+/// BMC Device Path. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Interface Type. >+ /// >+ UINT8 InterfaceType; >+ /// >+ /// Base Address. >+ /// >+ UINT8 BaseAddress[8]; >+} BMC_DEVICE_PATH; >+ >+/// >+/// ACPI Device Paths. >+/// >+#define ACPI_DEVICE_PATH 0x02 >+ >+/// >+/// ACPI Device Path SubType. >+/// >+#define ACPI_DP 0x01 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Device's PnP hardware ID stored in a numeric 32-bit >+ /// compressed EISA-type ID. This value must match the >+ /// corresponding _HID in the ACPI name space. >+ /// >+ UINT32 HID; >+ /// >+ /// Unique ID that is required by ACPI if two devices have the >+ /// same _HID. This value must also match the corresponding >+ /// _UID/_HID pair in the ACPI name space. Only the 32-bit >+ /// numeric value type of _UID is supported. Thus, strings must >+ /// not be used for the _UID in the ACPI name space. >+ /// >+ UINT32 UID; >+} ACPI_HID_DEVICE_PATH; >+ >+/// >+/// Expanded ACPI Device Path SubType. >+/// >+#define ACPI_EXTENDED_DP 0x02 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Device's PnP hardware ID stored in a numeric 32-bit >+ /// compressed EISA-type ID. This value must match the >+ /// corresponding _HID in the ACPI name space. >+ /// >+ UINT32 HID; >+ /// >+ /// Unique ID that is required by ACPI if two devices have the >+ /// same _HID. This value must also match the corresponding >+ /// _UID/_HID pair in the ACPI name space. >+ /// >+ UINT32 UID; >+ /// >+ /// Device's compatible PnP hardware ID stored in a numeric >+ /// 32-bit compressed EISA-type ID. This value must match at >+ /// least one of the compatible device IDs returned by the >+ /// corresponding _CID in the ACPI name space. >+ /// >+ UINT32 CID; >+ /// >+ /// Optional variable length _HIDSTR. >+ /// Optional variable length _UIDSTR. >+ /// Optional variable length _CIDSTR. >+ /// >+} ACPI_EXTENDED_HID_DEVICE_PATH; >+ >+// >+// EISA ID Macro >+// EISA ID Definition 32-bits >+// bits[15:0] - three character compressed ASCII EISA ID. >+// bits[31:16] - binary number >+// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' >+// >+#define PNP_EISA_ID_CONST 0x41d0 >+#define EISA_ID(_Name, _Num) ((UINT32)((_Name) | (_Num) << 16)) >+#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) >+#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) >+ >+#define PNP_EISA_ID_MASK 0xffff >+#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) >+ >+/// >+/// ACPI _ADR Device Path SubType. >+/// >+#define ACPI_ADR_DP 0x03 >+ >+/// >+/// The _ADR device path is used to contain video output device attributes to >support the Graphics >+/// Output Protocol. The device path can contain multiple _ADR entries if >multiple video output >+/// devices are displaying the same output. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// _ADR value. For video output devices the value of this >+ /// field comes from Table B-2 of the ACPI 3.0 specification. At >+ /// least one _ADR value is required. >+ /// >+ UINT32 ADR; >+ // >+ // This device path may optionally contain more than one _ADR entry. >+ // >+} ACPI_ADR_DEVICE_PATH; >+ >+#define ACPI_ADR_DISPLAY_TYPE_OTHER 0 >+#define ACPI_ADR_DISPLAY_TYPE_VGA 1 >+#define ACPI_ADR_DISPLAY_TYPE_TV 2 >+#define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL 3 >+#define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL 4 >+ >+#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, >_BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \ >+ ((UINT32)( ((UINT32)((_DeviceIdScheme) & 0x1) << 31) | \ >+ (((_HeadId) & 0x7) << 18) | \ >+ (((_NonVgaOutput) & 0x1) << 17) | \ >+ (((_BiosCanDetect) & 0x1) << 16) | \ >+ (((_VendorInfo) & 0xf) << 12) | \ >+ (((_Type) & 0xf) << 8) | \ >+ (((_Port) & 0xf) << 4) | \ >+ ((_Index) & 0xf) )) >+ >+/// >+/// Messaging Device Paths. >+/// This Device Path is used to describe the connection of devices outside >the resource domain of the >+/// system. This Device Path can describe physical messaging information like >SCSI ID, or abstract >+/// information like networking protocol IP addresses. >+/// >+#define MESSAGING_DEVICE_PATH 0x03 >+ >+/// >+/// ATAPI Device Path SubType >+/// >+#define MSG_ATAPI_DP 0x01 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Set to zero for primary, or one for secondary. >+ /// >+ UINT8 PrimarySecondary; >+ /// >+ /// Set to zero for master, or one for slave mode. >+ /// >+ UINT8 SlaveMaster; >+ /// >+ /// Logical Unit Number. >+ /// >+ UINT16 Lun; >+} ATAPI_DEVICE_PATH; >+ >+/// >+/// SCSI Device Path SubType. >+/// >+#define MSG_SCSI_DP 0x02 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Target ID on the SCSI bus (PUN). >+ /// >+ UINT16 Pun; >+ /// >+ /// Logical Unit Number (LUN). >+ /// >+ UINT16 Lun; >+} SCSI_DEVICE_PATH; >+ >+/// >+/// Fibre Channel SubType. >+/// >+#define MSG_FIBRECHANNEL_DP 0x03 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Reserved for the future. >+ /// >+ UINT32 Reserved; >+ /// >+ /// Fibre Channel World Wide Number. >+ /// >+ UINT64 WWN; >+ /// >+ /// Fibre Channel Logical Unit Number. >+ /// >+ UINT64 Lun; >+} FIBRECHANNEL_DEVICE_PATH; >+ >+/// >+/// Fibre Channel Ex SubType. >+/// >+#define MSG_FIBRECHANNELEX_DP 0x15 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Reserved for the future. >+ /// >+ UINT32 Reserved; >+ /// >+ /// 8 byte array containing Fibre Channel End Device Port Name. >+ /// >+ UINT8 WWN[8]; >+ /// >+ /// 8 byte array containing Fibre Channel Logical Unit Number. >+ /// >+ UINT8 Lun[8]; >+} FIBRECHANNELEX_DEVICE_PATH; >+ >+/// >+/// 1394 Device Path SubType >+/// >+#define MSG_1394_DP 0x04 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Reserved for the future. >+ /// >+ UINT32 Reserved; >+ /// >+ /// 1394 Global Unique ID (GUID). >+ /// >+ UINT64 Guid; >+} F1394_DEVICE_PATH; >+ >+/// >+/// USB Device Path SubType. >+/// >+#define MSG_USB_DP 0x05 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// USB Parent Port Number. >+ /// >+ UINT8 ParentPortNumber; >+ /// >+ /// USB Interface Number. >+ /// >+ UINT8 InterfaceNumber; >+} USB_DEVICE_PATH; >+ >+/// >+/// USB Class Device Path SubType. >+/// >+#define MSG_USB_CLASS_DP 0x0f >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Vendor ID assigned by USB-IF. A value of 0xFFFF will >+ /// match any Vendor ID. >+ /// >+ UINT16 VendorId; >+ /// >+ /// Product ID assigned by USB-IF. A value of 0xFFFF will >+ /// match any Product ID. >+ /// >+ UINT16 ProductId; >+ /// >+ /// The class code assigned by the USB-IF. A value of 0xFF >+ /// will match any class code. >+ /// >+ UINT8 DeviceClass; >+ /// >+ /// The subclass code assigned by the USB-IF. A value of >+ /// 0xFF will match any subclass code. >+ /// >+ UINT8 DeviceSubClass; >+ /// >+ /// The protocol code assigned by the USB-IF. A value of >+ /// 0xFF will match any protocol code. >+ /// >+ UINT8 DeviceProtocol; >+} USB_CLASS_DEVICE_PATH; >+ >+/// >+/// USB WWID Device Path SubType. >+/// >+#define MSG_USB_WWID_DP 0x10 >+ >+/// >+/// This device path describes a USB device using its serial number. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// USB interface number. >+ /// >+ UINT16 InterfaceNumber; >+ /// >+ /// USB vendor id of the device. >+ /// >+ UINT16 VendorId; >+ /// >+ /// USB product id of the device. >+ /// >+ UINT16 ProductId; >+ /// >+ /// Last 64-or-fewer UTF-16 characters of the USB >+ /// serial number. The length of the string is >+ /// determined by the Length field less the offset of the >+ /// Serial Number field (10) >+ /// >+ /// CHAR16 SerialNumber[...]; >+} USB_WWID_DEVICE_PATH; >+ >+/// >+/// Device Logical Unit SubType. >+/// >+#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Logical Unit Number for the interface. >+ /// >+ UINT8 Lun; >+} DEVICE_LOGICAL_UNIT_DEVICE_PATH; >+ >+/// >+/// SATA Device Path SubType. >+/// >+#define MSG_SATA_DP 0x12 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// The HBA port number that facilitates the connection to the >+ /// device or a port multiplier. The value 0xFFFF is reserved. >+ /// >+ UINT16 HBAPortNumber; >+ /// >+ /// The Port multiplier port number that facilitates the connection >+ /// to the device. Must be set to 0xFFFF if the device is directly >+ /// connected to the HBA. >+ /// >+ UINT16 PortMultiplierPortNumber; >+ /// >+ /// Logical Unit Number. >+ /// >+ UINT16 Lun; >+} SATA_DEVICE_PATH; >+ >+/// >+/// Flag for if the device is directly connected to the HBA. >+/// >+#define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000 >+ >+/// >+/// I2O Device Path SubType. >+/// >+#define MSG_I2O_DP 0x06 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Target ID (TID) for a device. >+ /// >+ UINT32 Tid; >+} I2O_DEVICE_PATH; >+ >+/// >+/// MAC Address Device Path SubType. >+/// >+#define MSG_MAC_ADDR_DP 0x0b >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// The MAC address for a network interface padded with 0s. >+ /// >+ EFI_MAC_ADDRESS MacAddress; >+ /// >+ /// Network interface type(i.e. 802.3, FDDI). >+ /// >+ UINT8 IfType; >+} MAC_ADDR_DEVICE_PATH; >+ >+/// >+/// IPv4 Device Path SubType >+/// >+#define MSG_IPv4_DP 0x0c >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// The local IPv4 address. >+ /// >+ EFI_IPv4_ADDRESS LocalIpAddress; >+ /// >+ /// The remote IPv4 address. >+ /// >+ EFI_IPv4_ADDRESS RemoteIpAddress; >+ /// >+ /// The local port number. >+ /// >+ UINT16 LocalPort; >+ /// >+ /// The remote port number. >+ /// >+ UINT16 RemotePort; >+ /// >+ /// The network protocol(i.e. UDP, TCP). >+ /// >+ UINT16 Protocol; >+ /// >+ /// 0x00 - The Source IP Address was assigned though DHCP. >+ /// 0x01 - The Source IP Address is statically bound. >+ /// >+ BOOLEAN StaticIpAddress; >+ /// >+ /// The gateway IP address >+ /// >+ EFI_IPv4_ADDRESS GatewayIpAddress; >+ /// >+ /// The subnet mask >+ /// >+ EFI_IPv4_ADDRESS SubnetMask; >+} IPv4_DEVICE_PATH; >+ >+/// >+/// IPv6 Device Path SubType. >+/// >+#define MSG_IPv6_DP 0x0d >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// The local IPv6 address. >+ /// >+ EFI_IPv6_ADDRESS LocalIpAddress; >+ /// >+ /// The remote IPv6 address. >+ /// >+ EFI_IPv6_ADDRESS RemoteIpAddress; >+ /// >+ /// The local port number. >+ /// >+ UINT16 LocalPort; >+ /// >+ /// The remote port number. >+ /// >+ UINT16 RemotePort; >+ /// >+ /// The network protocol(i.e. UDP, TCP). >+ /// >+ UINT16 Protocol; >+ /// >+ /// 0x00 - The Local IP Address was manually configured. >+ /// 0x01 - The Local IP Address is assigned through IPv6 >+ /// stateless auto-configuration. >+ /// 0x02 - The Local IP Address is assigned through IPv6 >+ /// stateful configuration. >+ /// >+ UINT8 IpAddressOrigin; >+ /// >+ /// The prefix length >+ /// >+ UINT8 PrefixLength; >+ /// >+ /// The gateway IP address >+ /// >+ EFI_IPv6_ADDRESS GatewayIpAddress; >+} IPv6_DEVICE_PATH; >+ >+/// >+/// InfiniBand Device Path SubType. >+/// >+#define MSG_INFINIBAND_DP 0x09 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Flags to help identify/manage InfiniBand device path elements: >+ /// Bit 0 - IOC/Service (0b = IOC, 1b = Service). >+ /// Bit 1 - Extend Boot Environment. >+ /// Bit 2 - Console Protocol. >+ /// Bit 3 - Storage Protocol. >+ /// Bit 4 - Network Protocol. >+ /// All other bits are reserved. >+ /// >+ UINT32 ResourceFlags; >+ /// >+ /// 128-bit Global Identifier for remote fabric port. >+ /// >+ UINT8 PortGid[16]; >+ /// >+ /// 64-bit unique identifier to remote IOC or server process. >+ /// Interpretation of field specified by Resource Flags (bit 0). >+ /// >+ UINT64 ServiceId; >+ /// >+ /// 64-bit persistent ID of remote IOC port. >+ /// >+ UINT64 TargetPortId; >+ /// >+ /// 64-bit persistent ID of remote device. >+ /// >+ UINT64 DeviceId; >+} INFINIBAND_DEVICE_PATH; >+ >+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01 >+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT >0x02 >+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04 >+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08 >+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10 >+ >+/// >+/// UART Device Path SubType. >+/// >+#define MSG_UART_DP 0x0e >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Reserved. >+ /// >+ UINT32 Reserved; >+ /// >+ /// The baud rate setting for the UART style device. A value of 0 >+ /// means that the device's default baud rate will be used. >+ /// >+ UINT64 BaudRate; >+ /// >+ /// The number of data bits for the UART style device. A value >+ /// of 0 means that the device's default number of data bits will be used. >+ /// >+ UINT8 DataBits; >+ /// >+ /// The parity setting for the UART style device. >+ /// Parity 0x00 - Default Parity. >+ /// Parity 0x01 - No Parity. >+ /// Parity 0x02 - Even Parity. >+ /// Parity 0x03 - Odd Parity. >+ /// Parity 0x04 - Mark Parity. >+ /// Parity 0x05 - Space Parity. >+ /// >+ UINT8 Parity; >+ /// >+ /// The number of stop bits for the UART style device. >+ /// Stop Bits 0x00 - Default Stop Bits. >+ /// Stop Bits 0x01 - 1 Stop Bit. >+ /// Stop Bits 0x02 - 1.5 Stop Bits. >+ /// Stop Bits 0x03 - 2 Stop Bits. >+ /// >+ UINT8 StopBits; >+} UART_DEVICE_PATH; >+ >+// >+// Use VENDOR_DEVICE_PATH struct >+// >+#define MSG_VENDOR_DP 0x0a >+typedef VENDOR_DEVICE_PATH VENDOR_DEFINED_DEVICE_PATH; >+ >+#define DEVICE_PATH_MESSAGING_PC_ANSI EFI_PC_ANSI_GUID >+#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID >+#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID >+#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID >+ >+/// >+/// A new device path node is defined to declare flow control characteristics. >+/// UART Flow Control Messaging Device Path >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL GUID. >+ /// >+ EFI_GUID Guid; >+ /// >+ /// Bitmap of supported flow control types. >+ /// Bit 0 set indicates hardware flow control. >+ /// Bit 1 set indicates Xon/Xoff flow control. >+ /// All other bits are reserved and are clear. >+ /// >+ UINT32 FlowControlMap; >+} UART_FLOW_CONTROL_DEVICE_PATH; >+ >+#define UART_FLOW_CONTROL_HARDWARE 0x00000001 >+#define UART_FLOW_CONTROL_XON_XOFF 0x00000010 >+ >+#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID >+/// >+/// Serial Attached SCSI (SAS) Device Path. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// DEVICE_PATH_MESSAGING_SAS GUID. >+ /// >+ EFI_GUID Guid; >+ /// >+ /// Reserved for future use. >+ /// >+ UINT32 Reserved; >+ /// >+ /// SAS Address for Serial Attached SCSI Target. >+ /// >+ UINT64 SasAddress; >+ /// >+ /// SAS Logical Unit Number. >+ /// >+ UINT64 Lun; >+ /// >+ /// More Information about the device and its interconnect. >+ /// >+ UINT16 DeviceTopology; >+ /// >+ /// Relative Target Port (RTP). >+ /// >+ UINT16 RelativeTargetPort; >+} SAS_DEVICE_PATH; >+ >+/// >+/// Serial Attached SCSI (SAS) Ex Device Path SubType >+/// >+#define MSG_SASEX_DP 0x16 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// 8-byte array of the SAS Address for Serial Attached SCSI Target Port. >+ /// >+ UINT8 SasAddress[8]; >+ /// >+ /// 8-byte array of the SAS Logical Unit Number. >+ /// >+ UINT8 Lun[8]; >+ /// >+ /// More Information about the device and its interconnect. >+ /// >+ UINT16 DeviceTopology; >+ /// >+ /// Relative Target Port (RTP). >+ /// >+ UINT16 RelativeTargetPort; >+} SASEX_DEVICE_PATH; >+ >+/// >+/// NvmExpress Namespace Device Path SubType. >+/// >+#define MSG_NVME_NAMESPACE_DP 0x17 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ UINT32 NamespaceId; >+ UINT64 NamespaceUuid; >+} NVME_NAMESPACE_DEVICE_PATH; >+ >+/// >+/// DNS Device Path SubType >+/// >+#define MSG_DNS_DP 0x1F >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Indicates the DNS server address is IPv4 or IPv6 address. >+ /// >+ UINT8 IsIPv6; >+ /// >+ /// Instance of the DNS server address. >+ /// >+ EFI_IP_ADDRESS DnsServerIp[1024]; >+} DNS_DEVICE_PATH; >+ >+/// >+/// Uniform Resource Identifiers (URI) Device Path SubType >+/// >+#define MSG_URI_DP 0x18 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Instance of the URI pursuant to RFC 3986. >+ /// >+ CHAR8 Uri[1024]; >+} URI_DEVICE_PATH; >+ >+/// >+/// Universal Flash Storage (UFS) Device Path SubType. >+/// >+#define MSG_UFS_DP 0x19 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Target ID on the UFS bus (PUN). >+ /// >+ UINT8 Pun; >+ /// >+ /// Logical Unit Number (LUN). >+ /// >+ UINT8 Lun; >+} UFS_DEVICE_PATH; >+ >+/// >+/// SD (Secure Digital) Device Path SubType. >+/// >+#define MSG_SD_DP 0x1A >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ UINT8 SlotNumber; >+} SD_DEVICE_PATH; >+ >+/// >+/// EMMC (Embedded MMC) Device Path SubType. >+/// >+#define MSG_EMMC_DP 0x1D >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ UINT8 SlotNumber; >+} EMMC_DEVICE_PATH; >+ >+/// >+/// iSCSI Device Path SubType >+/// >+#define MSG_ISCSI_DP 0x13 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Network Protocol (0 = TCP, 1+ = reserved). >+ /// >+ UINT16 NetworkProtocol; >+ /// >+ /// iSCSI Login Options. >+ /// >+ UINT16 LoginOption; >+ /// >+ /// iSCSI Logical Unit Number. >+ /// >+ UINT64 Lun; >+ /// >+ /// iSCSI Target Portal group tag the initiator intends >+ /// to establish a session with. >+ /// >+ UINT16 TargetPortalGroupTag; >+ /// >+ /// iSCSI NodeTarget Name. The length of the name >+ /// is determined by subtracting the offset of this field from Length. >+ /// >+ /// CHAR8 iSCSI Target Name. >+} ISCSI_DEVICE_PATH; >+ >+#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST 0x0000 >+#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C 0x0002 >+#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST 0x0000 >+#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C 0x0008 >+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP 0x0000 >+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON 0x1000 >+#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000 >+#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000 >+ >+/// >+/// VLAN Device Path SubType. >+/// >+#define MSG_VLAN_DP 0x14 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// VLAN identifier (0-4094). >+ /// >+ UINT16 VlanId; >+} VLAN_DEVICE_PATH; >+ >+/// >+/// BLUETOOTH_ADDRESS >+/// >+typedef struct { >+ /// >+ /// 48bit Bluetooth device address. >+ /// >+ UINT8 Address[6]; >+} BLUETOOTH_ADDRESS; >+ >+/// >+/// Bluetooth Device Path SubType. >+/// >+#define MSG_BLUETOOTH_DP 0x1b >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// 48bit Bluetooth device address. >+ /// >+ BLUETOOTH_ADDRESS BD_ADDR; >+} BLUETOOTH_DEVICE_PATH; >+ >+/// >+/// Wi-Fi Device Path SubType. >+/// >+#define MSG_WIFI_DP 0x1C >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Service set identifier. A 32-byte octets string. >+ /// >+ UINT8 SSId[32]; >+} WIFI_DEVICE_PATH; >+ >+/// >+/// BLUETOOTH_LE_ADDRESS >+/// >+typedef struct { >+ /// >+ /// 48-bit Bluetooth device address >+ /// >+ UINT8 Address[6]; >+ /// >+ /// 0x00 - Public Device Address >+ /// 0x01 - Random Device Address >+ /// >+ UINT8 Type; >+} BLUETOOTH_LE_ADDRESS; >+ >+/// >+/// Bluetooth LE Device Path SubType. >+/// >+#define MSG_BLUETOOTH_LE_DP 0x1E >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ BLUETOOTH_LE_ADDRESS Address; >+} BLUETOOTH_LE_DEVICE_PATH; >+ >+// >+// Media Device Path >+// >+#define MEDIA_DEVICE_PATH 0x04 >+ >+/// >+/// Hard Drive Media Device Path SubType. >+/// >+#define MEDIA_HARDDRIVE_DP 0x01 >+ >+/// >+/// The Hard Drive Media Device Path is used to represent a partition on a >hard drive. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Describes the entry in a partition table, starting with entry 1. >+ /// Partition number zero represents the entire device. Valid >+ /// partition numbers for a MBR partition are [1, 4]. Valid >+ /// partition numbers for a GPT partition are [1, NumberOfPartitionEntries]. >+ /// >+ UINT32 PartitionNumber; >+ /// >+ /// Starting LBA of the partition on the hard drive. >+ /// >+ UINT64 PartitionStart; >+ /// >+ /// Size of the partition in units of Logical Blocks. >+ /// >+ UINT64 PartitionSize; >+ /// >+ /// Signature unique to this partition: >+ /// If SignatureType is 0, this field has to be initialized with 16 zeros. >+ /// If SignatureType is 1, the MBR signature is stored in the first 4 bytes of >this field. >+ /// The other 12 bytes are initialized with zeros. >+ /// If SignatureType is 2, this field contains a 16 byte signature. >+ /// >+ UINT8 Signature[16]; >+ /// >+ /// Partition Format: (Unused values reserved). >+ /// 0x01 - PC-AT compatible legacy MBR. >+ /// 0x02 - GUID Partition Table. >+ /// >+ UINT8 MBRType; >+ /// >+ /// Type of Disk Signature: (Unused values reserved). >+ /// 0x00 - No Disk Signature. >+ /// 0x01 - 32-bit signature from address 0x1b8 of the type 0x01 MBR. >+ /// 0x02 - GUID signature. >+ /// >+ UINT8 SignatureType; >+} HARDDRIVE_DEVICE_PATH; >+ >+#define MBR_TYPE_PCAT 0x01 >+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 >+ >+#define NO_DISK_SIGNATURE 0x00 >+#define SIGNATURE_TYPE_MBR 0x01 >+#define SIGNATURE_TYPE_GUID 0x02 >+ >+/// >+/// CD-ROM Media Device Path SubType. >+/// >+#define MEDIA_CDROM_DP 0x02 >+ >+/// >+/// The CD-ROM Media Device Path is used to define a system partition that >exists on a CD-ROM. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Boot Entry number from the Boot Catalog. The Initial/Default entry is >defined as zero. >+ /// >+ UINT32 BootEntry; >+ /// >+ /// Starting RBA of the partition on the medium. CD-ROMs use Relative >logical Block Addressing. >+ /// >+ UINT64 PartitionStart; >+ /// >+ /// Size of the partition in units of Blocks, also called Sectors. >+ /// >+ UINT64 PartitionSize; >+} CDROM_DEVICE_PATH; >+ >+// >+// Use VENDOR_DEVICE_PATH struct >+// >+#define MEDIA_VENDOR_DP 0x03 ///< Media vendor device path >subtype. >+ >+/// >+/// File Path Media Device Path SubType >+/// >+#define MEDIA_FILEPATH_DP 0x04 >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// A NULL-terminated Path string including directory and file names. >+ /// >+ CHAR16 PathName[1]; >+} FILEPATH_DEVICE_PATH; >+ >+#define SIZE_OF_FILEPATH_DEVICE_PATH >OFFSET_OF(FILEPATH_DEVICE_PATH,PathName) >+ >+/// >+/// Media Protocol Device Path SubType. >+/// >+#define MEDIA_PROTOCOL_DP 0x05 >+ >+/// >+/// The Media Protocol Device Path is used to denote the protocol that is >being >+/// used in a device path at the location of the path specified. >+/// Many protocols are inherent to the style of device path. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// The ID of the protocol. >+ /// >+ EFI_GUID Protocol; >+} MEDIA_PROTOCOL_DEVICE_PATH; >+ >+/// >+/// PIWG Firmware File SubType. >+/// >+#define MEDIA_PIWG_FW_FILE_DP 0x06 >+ >+/// >+/// This device path is used by systems implementing the UEFI PI >Specification 1.0 to describe a firmware file. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Firmware file name >+ /// >+ EFI_GUID FvFileName; >+} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH; >+ >+/// >+/// PIWG Firmware Volume Device Path SubType. >+/// >+#define MEDIA_PIWG_FW_VOL_DP 0x07 >+ >+/// >+/// This device path is used by systems implementing the UEFI PI >Specification 1.0 to describe a firmware volume. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Firmware volume name. >+ /// >+ EFI_GUID FvName; >+} MEDIA_FW_VOL_DEVICE_PATH; >+ >+/// >+/// Media relative offset range device path. >+/// >+#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08 >+ >+/// >+/// Used to describe the offset range of media relative. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ UINT32 Reserved; >+ UINT64 StartingOffset; >+ UINT64 EndingOffset; >+} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH; >+ >+/// >+/// This GUID defines a RAM Disk supporting a raw disk format in volatile >memory. >+/// >+#define EFI_VIRTUAL_DISK_GUID >EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGIO >N_VOLATILE >+ >+extern EFI_GUID gEfiVirtualDiskGuid; >+ >+/// >+/// This GUID defines a RAM Disk supporting an ISO image in volatile memory. >+/// >+#define EFI_VIRTUAL_CD_GUID >EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION >_VOLATILE >+ >+extern EFI_GUID gEfiVirtualCdGuid; >+ >+/// >+/// This GUID defines a RAM Disk supporting a raw disk format in persistent >memory. >+/// >+#define EFI_PERSISTENT_VIRTUAL_DISK_GUID >EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGIO >N_PERSISTENT >+ >+extern EFI_GUID gEfiPersistentVirtualDiskGuid; >+ >+/// >+/// This GUID defines a RAM Disk supporting an ISO image in persistent >memory. >+/// >+#define EFI_PERSISTENT_VIRTUAL_CD_GUID >EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION >_PERSISTENT >+ >+extern EFI_GUID gEfiPersistentVirtualCdGuid; >+ >+/// >+/// Media ram disk device path. >+/// >+#define MEDIA_RAM_DISK_DP 0x09 >+ >+/// >+/// Used to describe the ram disk device path. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Starting Memory Address. >+ /// >+ UINT32 StartingAddr[2]; >+ /// >+ /// Ending Memory Address. >+ /// >+ UINT32 EndingAddr[2]; >+ /// >+ /// GUID that defines the type of the RAM Disk. >+ /// >+ EFI_GUID TypeGuid; >+ /// >+ /// RAM Diskinstance number, if supported. The default value is zero. >+ /// >+ UINT16 Instance; >+} MEDIA_RAM_DISK_DEVICE_PATH; >+ >+/// >+/// BIOS Boot Specification Device Path. >+/// >+#define BBS_DEVICE_PATH 0x05 >+ >+/// >+/// BIOS Boot Specification Device Path SubType. >+/// >+#define BBS_BBS_DP 0x01 >+ >+/// >+/// This Device Path is used to describe the booting of non-EFI-aware >operating systems. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ /// >+ /// Device Type as defined by the BIOS Boot Specification. >+ /// >+ UINT16 DeviceType; >+ /// >+ /// Status Flags as defined by the BIOS Boot Specification. >+ /// >+ UINT16 StatusFlag; >+ /// >+ /// Null-terminated ASCII string that describes the boot device to a user. >+ /// >+ CHAR8 String[1]; >+} BBS_BBS_DEVICE_PATH; >+ >+// >+// DeviceType definitions - from BBS specification >+// >+#define BBS_TYPE_FLOPPY 0x01 >+#define BBS_TYPE_HARDDRIVE 0x02 >+#define BBS_TYPE_CDROM 0x03 >+#define BBS_TYPE_PCMCIA 0x04 >+#define BBS_TYPE_USB 0x05 >+#define BBS_TYPE_EMBEDDED_NETWORK 0x06 >+#define BBS_TYPE_BEV 0x80 >+#define BBS_TYPE_UNKNOWN 0xFF >+ >+ >+/// >+/// Union of all possible Device Paths and pointers to Device Paths. >+/// >+typedef union { >+ EFI_DEVICE_PATH_PROTOCOL DevPath; >+ PCI_DEVICE_PATH Pci; >+ PCCARD_DEVICE_PATH PcCard; >+ MEMMAP_DEVICE_PATH MemMap; >+ VENDOR_DEVICE_PATH Vendor; >+ >+ CONTROLLER_DEVICE_PATH Controller; >+ BMC_DEVICE_PATH Bmc; >+ ACPI_HID_DEVICE_PATH Acpi; >+ ACPI_EXTENDED_HID_DEVICE_PATH ExtendedAcpi; >+ ACPI_ADR_DEVICE_PATH AcpiAdr; >+ >+ ATAPI_DEVICE_PATH Atapi; >+ SCSI_DEVICE_PATH Scsi; >+ ISCSI_DEVICE_PATH Iscsi; >+ FIBRECHANNEL_DEVICE_PATH FibreChannel; >+ FIBRECHANNELEX_DEVICE_PATH FibreChannelEx; >+ >+ F1394_DEVICE_PATH F1394; >+ USB_DEVICE_PATH Usb; >+ SATA_DEVICE_PATH Sata; >+ USB_CLASS_DEVICE_PATH UsbClass; >+ USB_WWID_DEVICE_PATH UsbWwid; >+ DEVICE_LOGICAL_UNIT_DEVICE_PATH LogicUnit; >+ I2O_DEVICE_PATH I2O; >+ MAC_ADDR_DEVICE_PATH MacAddr; >+ IPv4_DEVICE_PATH Ipv4; >+ IPv6_DEVICE_PATH Ipv6; >+ VLAN_DEVICE_PATH Vlan; >+ INFINIBAND_DEVICE_PATH InfiniBand; >+ UART_DEVICE_PATH Uart; >+ UART_FLOW_CONTROL_DEVICE_PATH UartFlowControl; >+ SAS_DEVICE_PATH Sas; >+ SASEX_DEVICE_PATH SasEx; >+ NVME_NAMESPACE_DEVICE_PATH NvmeNamespace; >+ DNS_DEVICE_PATH Dns; >+ URI_DEVICE_PATH Uri; >+ BLUETOOTH_DEVICE_PATH Bluetooth; >+ WIFI_DEVICE_PATH WiFi; >+ UFS_DEVICE_PATH Ufs; >+ SD_DEVICE_PATH Sd; >+ EMMC_DEVICE_PATH Emmc; >+ HARDDRIVE_DEVICE_PATH HardDrive; >+ CDROM_DEVICE_PATH CD; >+ >+ FILEPATH_DEVICE_PATH FilePath; >+ MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; >+ >+ MEDIA_FW_VOL_DEVICE_PATH FirmwareVolume; >+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FirmwareFile; >+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH Offset; >+ MEDIA_RAM_DISK_DEVICE_PATH RamDisk; >+ BBS_BBS_DEVICE_PATH Bbs; >+} EFI_DEV_PATH; >+ >+ >+ >+typedef union { >+ EFI_DEVICE_PATH_PROTOCOL *DevPath; >+ PCI_DEVICE_PATH *Pci; >+ PCCARD_DEVICE_PATH *PcCard; >+ MEMMAP_DEVICE_PATH *MemMap; >+ VENDOR_DEVICE_PATH *Vendor; >+ >+ CONTROLLER_DEVICE_PATH *Controller; >+ BMC_DEVICE_PATH *Bmc; >+ ACPI_HID_DEVICE_PATH *Acpi; >+ ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi; >+ ACPI_ADR_DEVICE_PATH *AcpiAdr; >+ >+ ATAPI_DEVICE_PATH *Atapi; >+ SCSI_DEVICE_PATH *Scsi; >+ ISCSI_DEVICE_PATH *Iscsi; >+ FIBRECHANNEL_DEVICE_PATH *FibreChannel; >+ FIBRECHANNELEX_DEVICE_PATH *FibreChannelEx; >+ >+ F1394_DEVICE_PATH *F1394; >+ USB_DEVICE_PATH *Usb; >+ SATA_DEVICE_PATH *Sata; >+ USB_CLASS_DEVICE_PATH *UsbClass; >+ USB_WWID_DEVICE_PATH *UsbWwid; >+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicUnit; >+ I2O_DEVICE_PATH *I2O; >+ MAC_ADDR_DEVICE_PATH *MacAddr; >+ IPv4_DEVICE_PATH *Ipv4; >+ IPv6_DEVICE_PATH *Ipv6; >+ VLAN_DEVICE_PATH *Vlan; >+ INFINIBAND_DEVICE_PATH *InfiniBand; >+ UART_DEVICE_PATH *Uart; >+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl; >+ SAS_DEVICE_PATH *Sas; >+ SASEX_DEVICE_PATH *SasEx; >+ NVME_NAMESPACE_DEVICE_PATH *NvmeNamespace; >+ DNS_DEVICE_PATH *Dns; >+ URI_DEVICE_PATH *Uri; >+ BLUETOOTH_DEVICE_PATH *Bluetooth; >+ WIFI_DEVICE_PATH *WiFi; >+ UFS_DEVICE_PATH *Ufs; >+ SD_DEVICE_PATH *Sd; >+ EMMC_DEVICE_PATH *Emmc; >+ HARDDRIVE_DEVICE_PATH *HardDrive; >+ CDROM_DEVICE_PATH *CD; >+ >+ FILEPATH_DEVICE_PATH *FilePath; >+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; >+ >+ MEDIA_FW_VOL_DEVICE_PATH *FirmwareVolume; >+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FirmwareFile; >+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset; >+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; >+ BBS_BBS_DEVICE_PATH *Bbs; >+ UINT8 *Raw; >+} EFI_DEV_PATH_PTR; >+ >+#define EFI_DEBUGPORT_PROTOCOL_GUID \ >+ { \ >+ 0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, >0xD0 } \ >+ } >+// >+// DEBUGPORT variable definitions... >+// >+#define EFI_DEBUGPORT_VARIABLE_NAME L"DEBUGPORT" >+#define EFI_DEBUGPORT_VARIABLE_GUID >EFI_DEBUGPORT_PROTOCOL_GUID >+extern EFI_GUID gEfiDebugPortVariableGuid; >+ >+// >+// DebugPort device path definitions... >+// >+#define DEVICE_PATH_MESSAGING_DEBUGPORT >EFI_DEBUGPORT_PROTOCOL_GUID >+extern EFI_GUID gEfiDebugPortDevicePathGuid; >+ >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ EFI_GUID Guid; >+} DEBUGPORT_DEVICE_PATH; >+ >+#pragma pack() >+ >+#define END_DEVICE_PATH_TYPE 0x7f >+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF >+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 >+ >+extern EFI_GUID gEfiDevicePathProtocolGuid; >+ >+#endif >diff --git a/BaseTools/Source/C/DevicePath/DevicePathFromText.c >b/BaseTools/Source/C/DevicePath/DevicePathFromText.c >new file mode 100644 >index 0000000..fb5b09b >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.c >@@ -0,0 +1,3503 @@ >+/** @file >+ DevicePathFromText protocol as defined in the UEFI 2.0 specification. >+ >+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+This program and the accompanying materials >+are licensed and made available under the terms and conditions of the BSD >License >+which accompanies this distribution. The full text of the license may be >found at >+http://opensource.org/licenses/bsd-license.php >+ >+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+ >+**/ >+ >+#include "UefiDevicePathLib.h" >+ >+/** >+ >+ Duplicates a string. >+ >+ @param Src Source string. >+ >+ @return The duplicated string. >+ >+**/ >+CHAR16 * >+UefiDevicePathLibStrDuplicate ( >+ CONST CHAR16 *Src >+ ) >+{ >+ return AllocateCopyPool (StrSize (Src), Src); >+} >+ >+/** >+ >+ Get parameter in a pair of parentheses follow the given node name. >+ For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1". >+ >+ @param Str Device Path Text. >+ @param NodeName Name of the node. >+ >+ @return Parameter text for the node. >+ >+**/ >+CHAR16 * >+GetParamByNodeName ( >+ CHAR16 *Str, >+ CHAR16 *NodeName >+ ) >+{ >+ CHAR16 *ParamStr; >+ CHAR16 *StrPointer; >+ UINTN NodeNameLength; >+ UINTN ParameterLength; >+ >+ // >+ // Check whether the node name matchs >+ // >+ NodeNameLength = StrLen (NodeName); >+ if (StrnCmp (Str, NodeName, NodeNameLength) != 0) { >+ return NULL; >+ } >+ >+ ParamStr = Str + NodeNameLength; >+ if (!IS_LEFT_PARENTH (*ParamStr)) { >+ return NULL; >+ } >+ >+ // >+ // Skip the found '(' and find first occurrence of ')' >+ // >+ ParamStr++; >+ ParameterLength = 0; >+ StrPointer = ParamStr; >+ while (!IS_NULL (*StrPointer)) { >+ if (IS_RIGHT_PARENTH (*StrPointer)) { >+ break; >+ } >+ StrPointer++; >+ ParameterLength++; >+ } >+ if (IS_NULL (*StrPointer)) { >+ // >+ // ')' not found >+ // >+ return NULL; >+ } >+ >+ ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), >ParamStr); >+ if (ParamStr == NULL) { >+ return NULL; >+ } >+ // >+ // Terminate the parameter string >+ // >+ ParamStr[ParameterLength] = L'\0'; >+ >+ return ParamStr; >+} >+ >+/** >+ Gets current sub-string from a string list, before return >+ the list header is moved to next sub-string. The sub-string is separated >+ by the specified character. For example, the separator is ',', the string >+ list is "2,0,3", it returns "2", the remain list move to "0,3" >+ >+ @param List A string list separated by the specified separator >+ @param Separator The separator character >+ >+ @return A pointer to the current sub-string >+ >+**/ >+CHAR16 * >+SplitStr ( >+ CHAR16 **List, >+ CHAR16 Separator >+ ) >+{ >+ CHAR16 *Str; >+ CHAR16 *ReturnStr; >+ >+ Str = *List; >+ ReturnStr = Str; >+ >+ if (IS_NULL (*Str)) { >+ return ReturnStr; >+ } >+ >+ // >+ // Find first occurrence of the separator >+ // >+ while (!IS_NULL (*Str)) { >+ if (*Str == Separator) { >+ break; >+ } >+ Str++; >+ } >+ >+ if (*Str == Separator) { >+ // >+ // Find a sub-string, terminate it >+ // >+ *Str = L'\0'; >+ Str++; >+ } >+ >+ // >+ // Move to next sub-string >+ // >+ *List = Str; >+ return ReturnStr; >+} >+ >+/** >+ Gets the next parameter string from the list. >+ >+ @param List A string list separated by the specified separator >+ >+ @return A pointer to the current sub-string >+ >+**/ >+CHAR16 * >+GetNextParamStr ( >+ CHAR16 **List >+ ) >+{ >+ // >+ // The separator is comma >+ // >+ return SplitStr (List, L','); >+} >+ >+/** >+ Get one device node from entire device path text. >+ >+ @param DevicePath On input, the current Device Path node; on output, >the next device path node >+ @param IsInstanceEnd This node is the end of a device path instance >+ >+ @return A device node text or NULL if no more device node available >+ >+**/ >+CHAR16 * >+GetNextDeviceNodeStr ( >+ CHAR16 **DevicePath, >+ BOOLEAN *IsInstanceEnd >+ ) >+{ >+ CHAR16 *Str; >+ CHAR16 *ReturnStr; >+ UINTN ParenthesesStack; >+ >+ Str = *DevicePath; >+ if (IS_NULL (*Str)) { >+ return NULL; >+ } >+ >+ // >+ // Skip the leading '/', '(', ')' and ',' >+ // >+ while (!IS_NULL (*Str)) { >+ if (!IS_SLASH (*Str) && >+ !IS_COMMA (*Str) && >+ !IS_LEFT_PARENTH (*Str) && >+ !IS_RIGHT_PARENTH (*Str)) { >+ break; >+ } >+ Str++; >+ } >+ >+ ReturnStr = Str; >+ >+ // >+ // Scan for the separator of this device node, '/' or ',' >+ // >+ ParenthesesStack = 0; >+ while (!IS_NULL (*Str)) { >+ if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) { >+ break; >+ } >+ >+ if (IS_LEFT_PARENTH (*Str)) { >+ ParenthesesStack++; >+ } else if (IS_RIGHT_PARENTH (*Str)) { >+ ParenthesesStack--; >+ } >+ >+ Str++; >+ } >+ >+ if (ParenthesesStack != 0) { >+ // >+ // The '(' doesn't pair with ')', invalid device path text >+ // >+ return NULL; >+ } >+ >+ if (IS_COMMA (*Str)) { >+ *IsInstanceEnd = TRUE; >+ *Str = L'\0'; >+ Str++; >+ } else { >+ *IsInstanceEnd = FALSE; >+ if (!IS_NULL (*Str)) { >+ *Str = L'\0'; >+ Str++; >+ } >+ } >+ >+ *DevicePath = Str; >+ >+ return ReturnStr; >+} >+ >+ >+/** >+ Return whether the integer string is a hex string. >+ >+ @param Str The integer string >+ >+ @retval TRUE Hex string >+ @retval FALSE Decimal string >+ >+**/ >+BOOLEAN >+IsHexStr ( >+ CHAR16 *Str >+ ) >+{ >+ // >+ // skip preceeding white space >+ // >+ while ((*Str != 0) && *Str == L' ') { >+ Str ++; >+ } >+ // >+ // skip preceeding zeros >+ // >+ while ((*Str != 0) && *Str == L'0') { >+ Str ++; >+ } >+ >+ return (BOOLEAN) (*Str == L'x' || *Str == L'X'); >+} >+ >+/** >+ >+ Convert integer string to uint. >+ >+ @param Str The integer string. If leading with "0x" or "0X", it's >hexadecimal. >+ >+ @return A UINTN value represented by Str >+ >+**/ >+UINTN >+Strtoi ( >+ CHAR16 *Str >+ ) >+{ >+ if (IsHexStr (Str)) { >+ return StrHexToUintn (Str); >+ } else { >+ return StrDecimalToUintn (Str); >+ } >+} >+ >+/** >+ >+ Convert integer string to 64 bit data. >+ >+ @param Str The integer string. If leading with "0x" or "0X", it's >hexadecimal. >+ @param Data A pointer to the UINT64 value represented by Str >+ >+**/ >+VOID >+Strtoi64 ( >+ CHAR16 *Str, >+ UINT64 *Data >+ ) >+{ >+ if (IsHexStr (Str)) { >+ *Data = StrHexToUint64 (Str); >+ } else { >+ *Data = StrDecimalToUint64 (Str); >+ } >+} >+ >+/** >+ Converts a Unicode string to ASCII string. >+ >+ @param Str The equivalent Unicode string >+ @param AsciiStr On input, it points to destination ASCII string buffer; on >output, it points >+ to the next ASCII string next to it >+ >+**/ >+VOID >+StrToAscii ( >+ CHAR16 *Str, >+ CHAR8 **AsciiStr >+ ) >+{ >+ CHAR8 *Dest; >+ >+ Dest = *AsciiStr; >+ while (!IS_NULL (*Str)) { >+ *(Dest++) = (CHAR8) *(Str++); >+ } >+ *Dest = 0; >+ >+ // >+ // Return the string next to it >+ // >+ *AsciiStr = Dest + 1; >+} >+ >+/** >+ Converts a generic text device path node to device path structure. >+ >+ @param Type The type of the device path node. >+ @param TextDeviceNode The input text device path node. >+ >+ @return A pointer to device path structure. >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextGenericPath ( >+ UINT8 Type, >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ EFI_DEVICE_PATH_PROTOCOL *Node; >+ CHAR16 *SubtypeStr; >+ CHAR16 *DataStr; >+ UINTN DataLength; >+ >+ SubtypeStr = GetNextParamStr (&TextDeviceNode); >+ DataStr = GetNextParamStr (&TextDeviceNode); >+ >+ if (DataStr == NULL) { >+ DataLength = 0; >+ } else { >+ DataLength = StrLen (DataStr) / 2; >+ } >+ Node = CreateDeviceNode ( >+ Type, >+ (UINT8) Strtoi (SubtypeStr), >+ (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength) >+ ); >+ >+ StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength); >+ return Node; >+} >+ >+/** >+ Converts a generic text device path node to device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextPath ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *TypeStr; >+ >+ TypeStr = GetNextParamStr (&TextDeviceNode); >+ >+ return DevPathFromTextGenericPath ((UINT8) Strtoi (TypeStr), >TextDeviceNode); >+} >+ >+/** >+ Converts a generic hardware text device path node to Hardware device >path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to Hardware device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextHardwarePath ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, >TextDeviceNode); >+} >+ >+/** >+ Converts a text device path node to Hardware PCI device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to Hardware PCI device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextPci ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *FunctionStr; >+ CHAR16 *DeviceStr; >+ PCI_DEVICE_PATH *Pci; >+ >+ DeviceStr = GetNextParamStr (&TextDeviceNode); >+ FunctionStr = GetNextParamStr (&TextDeviceNode); >+ Pci = (PCI_DEVICE_PATH *) CreateDeviceNode ( >+ HARDWARE_DEVICE_PATH, >+ HW_PCI_DP, >+ (UINT16) sizeof (PCI_DEVICE_PATH) >+ ); >+ >+ Pci->Function = (UINT8) Strtoi (FunctionStr); >+ Pci->Device = (UINT8) Strtoi (DeviceStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Pci; >+} >+ >+/** >+ Converts a text device path node to Hardware PC card device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to Hardware PC card device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextPcCard ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *FunctionNumberStr; >+ PCCARD_DEVICE_PATH *Pccard; >+ >+ FunctionNumberStr = GetNextParamStr (&TextDeviceNode); >+ Pccard = (PCCARD_DEVICE_PATH *) CreateDeviceNode ( >+ HARDWARE_DEVICE_PATH, >+ HW_PCCARD_DP, >+ (UINT16) sizeof (PCCARD_DEVICE_PATH) >+ ); >+ >+ Pccard->FunctionNumber = (UINT8) Strtoi (FunctionNumberStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Pccard; >+} >+ >+/** >+ Converts a text device path node to Hardware memory map device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to Hardware memory map device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextMemoryMapped ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *MemoryTypeStr; >+ CHAR16 *StartingAddressStr; >+ CHAR16 *EndingAddressStr; >+ MEMMAP_DEVICE_PATH *MemMap; >+ >+ MemoryTypeStr = GetNextParamStr (&TextDeviceNode); >+ StartingAddressStr = GetNextParamStr (&TextDeviceNode); >+ EndingAddressStr = GetNextParamStr (&TextDeviceNode); >+ MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode ( >+ HARDWARE_DEVICE_PATH, >+ HW_MEMMAP_DP, >+ (UINT16) sizeof (MEMMAP_DEVICE_PATH) >+ ); >+ >+ MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr); >+ Strtoi64 (StartingAddressStr, &MemMap->StartingAddress); >+ Strtoi64 (EndingAddressStr, &MemMap->EndingAddress); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) MemMap; >+} >+ >+/** >+ Converts a text device path node to Vendor device path structure based on >the input Type >+ and SubType. >+ >+ @param TextDeviceNode The input Text device path node. >+ @param Type The type of device path node. >+ @param SubType The subtype of device path node. >+ >+ @return A pointer to the newly-created Vendor device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+ConvertFromTextVendor ( >+ CHAR16 *TextDeviceNode, >+ UINT8 Type, >+ UINT8 SubType >+ ) >+{ >+ CHAR16 *GuidStr; >+ CHAR16 *DataStr; >+ UINTN Length; >+ VENDOR_DEVICE_PATH *Vendor; >+ >+ GuidStr = GetNextParamStr (&TextDeviceNode); >+ >+ DataStr = GetNextParamStr (&TextDeviceNode); >+ Length = StrLen (DataStr); >+ // >+ // Two hex characters make up 1 buffer byte >+ // >+ Length = (Length + 1) / 2; >+ >+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( >+ Type, >+ SubType, >+ (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length) >+ ); >+ >+ StrToGuid (GuidStr, &Vendor->Guid); >+ StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; >+} >+ >+/** >+ Converts a text device path node to Vendor Hardware device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Vendor Hardware device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVenHw ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextVendor ( >+ TextDeviceNode, >+ HARDWARE_DEVICE_PATH, >+ HW_VENDOR_DP >+ ); >+} >+ >+/** >+ Converts a text device path node to Hardware Controller device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Hardware Controller device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextCtrl ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *ControllerStr; >+ CONTROLLER_DEVICE_PATH *Controller; >+ >+ ControllerStr = GetNextParamStr (&TextDeviceNode); >+ Controller = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode ( >+ HARDWARE_DEVICE_PATH, >+ HW_CONTROLLER_DP, >+ (UINT16) sizeof (CONTROLLER_DEVICE_PATH) >+ ); >+ Controller->ControllerNumber = (UINT32) Strtoi (ControllerStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Controller; >+} >+ >+/** >+ Converts a text device path node to BMC device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created BMC device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextBmc ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *InterfaceTypeStr; >+ CHAR16 *BaseAddressStr; >+ BMC_DEVICE_PATH *BmcDp; >+ >+ InterfaceTypeStr = GetNextParamStr (&TextDeviceNode); >+ BaseAddressStr = GetNextParamStr (&TextDeviceNode); >+ BmcDp = (BMC_DEVICE_PATH *) CreateDeviceNode ( >+ HARDWARE_DEVICE_PATH, >+ HW_BMC_DP, >+ (UINT16) sizeof (BMC_DEVICE_PATH) >+ ); >+ >+ BmcDp->InterfaceType = (UINT8) Strtoi (InterfaceTypeStr); >+ WriteUnaligned64 ( >+ (UINT64 *) (&BmcDp->BaseAddress), >+ StrHexToUint64 (BaseAddressStr) >+ ); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) BmcDp; >+} >+ >+/** >+ Converts a generic ACPI text device path node to ACPI device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to ACPI device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextAcpiPath ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, >TextDeviceNode); >+} >+ >+/** >+ Converts a string to EisaId. >+ >+ @param Text The input string. >+ >+ @return UINT32 EISA ID. >+**/ >+UINT32 >+EisaIdFromText ( >+ CHAR16 *Text >+ ) >+{ >+ return (((Text[0] - 'A' + 1) & 0x1f) << 10) >+ + (((Text[1] - 'A' + 1) & 0x1f) << 5) >+ + (((Text[2] - 'A' + 1) & 0x1f) << 0) >+ + (UINT32) (StrHexToUintn (&Text[3]) << 16) >+ ; >+} >+ >+/** >+ Converts a text device path node to ACPI HID device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created ACPI HID device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextAcpi ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *HIDStr; >+ CHAR16 *UIDStr; >+ ACPI_HID_DEVICE_PATH *Acpi; >+ >+ HIDStr = GetNextParamStr (&TextDeviceNode); >+ UIDStr = GetNextParamStr (&TextDeviceNode); >+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode ( >+ ACPI_DEVICE_PATH, >+ ACPI_DP, >+ (UINT16) sizeof (ACPI_HID_DEVICE_PATH) >+ ); >+ >+ Acpi->HID = EisaIdFromText (HIDStr); >+ Acpi->UID = (UINT32) Strtoi (UIDStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi; >+} >+ >+/** >+ Converts a text device path node to ACPI HID device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ @param PnPId The input plug and play identification. >+ >+ @return A pointer to the newly-created ACPI HID device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+ConvertFromTextAcpi ( >+ CHAR16 *TextDeviceNode, >+ UINT32 PnPId >+ ) >+{ >+ CHAR16 *UIDStr; >+ ACPI_HID_DEVICE_PATH *Acpi; >+ >+ UIDStr = GetNextParamStr (&TextDeviceNode); >+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode ( >+ ACPI_DEVICE_PATH, >+ ACPI_DP, >+ (UINT16) sizeof (ACPI_HID_DEVICE_PATH) >+ ); >+ >+ Acpi->HID = EFI_PNP_ID (PnPId); >+ Acpi->UID = (UINT32) Strtoi (UIDStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi; >+} >+ >+/** >+ Converts a text device path node to PCI root device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created PCI root device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextPciRoot ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a03); >+} >+ >+/** >+ Converts a text device path node to PCIE root device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created PCIE root device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextPcieRoot ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a08); >+} >+ >+/** >+ Converts a text device path node to Floppy device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Floppy device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextFloppy ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextAcpi (TextDeviceNode, 0x0604); >+} >+ >+/** >+ Converts a text device path node to Keyboard device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Keyboard device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextKeyboard ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextAcpi (TextDeviceNode, 0x0301); >+} >+ >+/** >+ Converts a text device path node to Serial device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Serial device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextSerial ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextAcpi (TextDeviceNode, 0x0501); >+} >+ >+/** >+ Converts a text device path node to Parallel Port device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Parallel Port device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextParallelPort ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextAcpi (TextDeviceNode, 0x0401); >+} >+ >+/** >+ Converts a text device path node to ACPI extension device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created ACPI extension device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextAcpiEx ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *HIDStr; >+ CHAR16 *CIDStr; >+ CHAR16 *UIDStr; >+ CHAR16 *HIDSTRStr; >+ CHAR16 *CIDSTRStr; >+ CHAR16 *UIDSTRStr; >+ CHAR8 *AsciiStr; >+ UINT16 Length; >+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; >+ >+ HIDStr = GetNextParamStr (&TextDeviceNode); >+ CIDStr = GetNextParamStr (&TextDeviceNode); >+ UIDStr = GetNextParamStr (&TextDeviceNode); >+ HIDSTRStr = GetNextParamStr (&TextDeviceNode); >+ CIDSTRStr = GetNextParamStr (&TextDeviceNode); >+ UIDSTRStr = GetNextParamStr (&TextDeviceNode); >+ >+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen >(HIDSTRStr) + 1); >+ Length = (UINT16) (Length + StrLen (UIDSTRStr) + 1); >+ Length = (UINT16) (Length + StrLen (CIDSTRStr) + 1); >+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode ( >+ ACPI_DEVICE_PATH, >+ ACPI_EXTENDED_DP, >+ Length >+ ); >+ >+ AcpiEx->HID = EisaIdFromText (HIDStr); >+ AcpiEx->CID = EisaIdFromText (CIDStr); >+ AcpiEx->UID = (UINT32) Strtoi (UIDStr); >+ >+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof >(ACPI_EXTENDED_HID_DEVICE_PATH)); >+ StrToAscii (HIDSTRStr, &AsciiStr); >+ StrToAscii (UIDSTRStr, &AsciiStr); >+ StrToAscii (CIDSTRStr, &AsciiStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx; >+} >+ >+/** >+ Converts a text device path node to ACPI extension device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created ACPI extension device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextAcpiExp ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *HIDStr; >+ CHAR16 *CIDStr; >+ CHAR16 *UIDSTRStr; >+ CHAR8 *AsciiStr; >+ UINT16 Length; >+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; >+ >+ HIDStr = GetNextParamStr (&TextDeviceNode); >+ CIDStr = GetNextParamStr (&TextDeviceNode); >+ UIDSTRStr = GetNextParamStr (&TextDeviceNode); >+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen >(UIDSTRStr) + 3); >+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode ( >+ ACPI_DEVICE_PATH, >+ ACPI_EXTENDED_DP, >+ Length >+ ); >+ >+ AcpiEx->HID = EisaIdFromText (HIDStr); >+ AcpiEx->CID = EisaIdFromText (CIDStr); >+ AcpiEx->UID = 0; >+ >+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof >(ACPI_EXTENDED_HID_DEVICE_PATH)); >+ // >+ // HID string is NULL >+ // >+ *AsciiStr = '\0'; >+ // >+ // Convert UID string >+ // >+ AsciiStr++; >+ StrToAscii (UIDSTRStr, &AsciiStr); >+ // >+ // CID string is NULL >+ // >+ *AsciiStr = '\0'; >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx; >+} >+ >+/** >+ Converts a text device path node to ACPI _ADR device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created ACPI _ADR device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextAcpiAdr ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *DisplayDeviceStr; >+ ACPI_ADR_DEVICE_PATH *AcpiAdr; >+ UINTN Index; >+ UINTN Length; >+ >+ AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode ( >+ ACPI_DEVICE_PATH, >+ ACPI_ADR_DP, >+ (UINT16) sizeof (ACPI_ADR_DEVICE_PATH) >+ ); >+ ASSERT (AcpiAdr != NULL); >+ >+ for (Index = 0; ; Index++) { >+ DisplayDeviceStr = GetNextParamStr (&TextDeviceNode); >+ if (IS_NULL (*DisplayDeviceStr)) { >+ break; >+ } >+ if (Index > 0) { >+ Length = DevicePathNodeLength (AcpiAdr); >+ AcpiAdr = ReallocatePool ( >+ Length, >+ Length + sizeof (UINT32), >+ AcpiAdr >+ ); >+ ASSERT (AcpiAdr != NULL); >+ SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32)); >+ } >+ >+ (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr); >+ } >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr; >+} >+ >+/** >+ Converts a generic messaging text device path node to messaging device >path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to messaging device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextMsg ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, >TextDeviceNode); >+} >+ >+/** >+ Converts a text device path node to Parallel Port device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Parallel Port device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextAta ( >+ CHAR16 *TextDeviceNode >+) >+{ >+ CHAR16 *PrimarySecondaryStr; >+ CHAR16 *SlaveMasterStr; >+ CHAR16 *LunStr; >+ ATAPI_DEVICE_PATH *Atapi; >+ >+ Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_ATAPI_DP, >+ (UINT16) sizeof (ATAPI_DEVICE_PATH) >+ ); >+ >+ PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode); >+ SlaveMasterStr = GetNextParamStr (&TextDeviceNode); >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ >+ if (StrCmp (PrimarySecondaryStr, L"Primary") == 0) { >+ Atapi->PrimarySecondary = 0; >+ } else if (StrCmp (PrimarySecondaryStr, L"Secondary") == 0) { >+ Atapi->PrimarySecondary = 1; >+ } else { >+ Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr); >+ } >+ if (StrCmp (SlaveMasterStr, L"Master") == 0) { >+ Atapi->SlaveMaster = 0; >+ } else if (StrCmp (SlaveMasterStr, L"Slave") == 0) { >+ Atapi->SlaveMaster = 1; >+ } else { >+ Atapi->SlaveMaster = (UINT8) Strtoi (SlaveMasterStr); >+ } >+ >+ Atapi->Lun = (UINT16) Strtoi (LunStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Atapi; >+} >+ >+/** >+ Converts a text device path node to SCSI device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created SCSI device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextScsi ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *PunStr; >+ CHAR16 *LunStr; >+ SCSI_DEVICE_PATH *Scsi; >+ >+ PunStr = GetNextParamStr (&TextDeviceNode); >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ Scsi = (SCSI_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_SCSI_DP, >+ (UINT16) sizeof (SCSI_DEVICE_PATH) >+ ); >+ >+ Scsi->Pun = (UINT16) Strtoi (PunStr); >+ Scsi->Lun = (UINT16) Strtoi (LunStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Scsi; >+} >+ >+/** >+ Converts a text device path node to Fibre device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Fibre device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextFibre ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *WWNStr; >+ CHAR16 *LunStr; >+ FIBRECHANNEL_DEVICE_PATH *Fibre; >+ >+ WWNStr = GetNextParamStr (&TextDeviceNode); >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ Fibre = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_FIBRECHANNEL_DP, >+ (UINT16) sizeof (FIBRECHANNEL_DEVICE_PATH) >+ ); >+ >+ Fibre->Reserved = 0; >+ Strtoi64 (WWNStr, &Fibre->WWN); >+ Strtoi64 (LunStr, &Fibre->Lun); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Fibre; >+} >+ >+/** >+ Converts a text device path node to FibreEx device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created FibreEx device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextFibreEx ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *WWNStr; >+ CHAR16 *LunStr; >+ FIBRECHANNELEX_DEVICE_PATH *FibreEx; >+ >+ WWNStr = GetNextParamStr (&TextDeviceNode); >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_FIBRECHANNELEX_DP, >+ (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH) >+ ); >+ >+ FibreEx->Reserved = 0; >+ Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN)); >+ Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun)); >+ >+ *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx- >>WWN)); >+ *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun)); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx; >+} >+ >+/** >+ Converts a text device path node to 1394 device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created 1394 device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromText1394 ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *GuidStr; >+ F1394_DEVICE_PATH *F1394DevPath; >+ >+ GuidStr = GetNextParamStr (&TextDeviceNode); >+ F1394DevPath = (F1394_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_1394_DP, >+ (UINT16) sizeof (F1394_DEVICE_PATH) >+ ); >+ >+ F1394DevPath->Reserved = 0; >+ F1394DevPath->Guid = StrHexToUint64 (GuidStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath; >+} >+ >+/** >+ Converts a text device path node to USB device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsb ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *PortStr; >+ CHAR16 *InterfaceStr; >+ USB_DEVICE_PATH *Usb; >+ >+ PortStr = GetNextParamStr (&TextDeviceNode); >+ InterfaceStr = GetNextParamStr (&TextDeviceNode); >+ Usb = (USB_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_USB_DP, >+ (UINT16) sizeof (USB_DEVICE_PATH) >+ ); >+ >+ Usb->ParentPortNumber = (UINT8) Strtoi (PortStr); >+ Usb->InterfaceNumber = (UINT8) Strtoi (InterfaceStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Usb; >+} >+ >+/** >+ Converts a text device path node to I20 device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created I20 device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextI2O ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *TIDStr; >+ I2O_DEVICE_PATH *I2ODevPath; >+ >+ TIDStr = GetNextParamStr (&TextDeviceNode); >+ I2ODevPath = (I2O_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_I2O_DP, >+ (UINT16) sizeof (I2O_DEVICE_PATH) >+ ); >+ >+ I2ODevPath->Tid = (UINT32) Strtoi (TIDStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath; >+} >+ >+/** >+ Converts a text device path node to Infini Band device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Infini Band device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextInfiniband ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *FlagsStr; >+ CHAR16 *GuidStr; >+ CHAR16 *SidStr; >+ CHAR16 *TidStr; >+ CHAR16 *DidStr; >+ INFINIBAND_DEVICE_PATH *InfiniBand; >+ >+ FlagsStr = GetNextParamStr (&TextDeviceNode); >+ GuidStr = GetNextParamStr (&TextDeviceNode); >+ SidStr = GetNextParamStr (&TextDeviceNode); >+ TidStr = GetNextParamStr (&TextDeviceNode); >+ DidStr = GetNextParamStr (&TextDeviceNode); >+ InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_INFINIBAND_DP, >+ (UINT16) sizeof (INFINIBAND_DEVICE_PATH) >+ ); >+ >+ InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr); >+ StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid); >+ Strtoi64 (SidStr, &InfiniBand->ServiceId); >+ Strtoi64 (TidStr, &InfiniBand->TargetPortId); >+ Strtoi64 (DidStr, &InfiniBand->DeviceId); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand; >+} >+ >+/** >+ Converts a text device path node to Vendor-Defined Messaging device >path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Vendor-Defined Messaging device >path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVenMsg ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextVendor ( >+ TextDeviceNode, >+ MESSAGING_DEVICE_PATH, >+ MSG_VENDOR_DP >+ ); >+} >+ >+/** >+ Converts a text device path node to Vendor defined PC-ANSI device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Vendor defined PC-ANSI device >path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVenPcAnsi ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ VENDOR_DEVICE_PATH *Vendor; >+ >+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_VENDOR_DP, >+ (UINT16) sizeof (VENDOR_DEVICE_PATH)); >+ CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; >+} >+ >+/** >+ Converts a text device path node to Vendor defined VT100 device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Vendor defined VT100 device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVenVt100 ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ VENDOR_DEVICE_PATH *Vendor; >+ >+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_VENDOR_DP, >+ (UINT16) sizeof (VENDOR_DEVICE_PATH)); >+ CopyGuid (&Vendor->Guid, &gEfiVT100Guid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; >+} >+ >+/** >+ Converts a text device path node to Vendor defined VT100 Plus device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Vendor defined VT100 Plus device >path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVenVt100Plus ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ VENDOR_DEVICE_PATH *Vendor; >+ >+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_VENDOR_DP, >+ (UINT16) sizeof (VENDOR_DEVICE_PATH)); >+ CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; >+} >+ >+/** >+ Converts a text device path node to Vendor defined UTF8 device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Vendor defined UTF8 device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVenUtf8 ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ VENDOR_DEVICE_PATH *Vendor; >+ >+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_VENDOR_DP, >+ (UINT16) sizeof (VENDOR_DEVICE_PATH)); >+ CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; >+} >+ >+/** >+ Converts a text device path node to UART Flow Control device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created UART Flow Control device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUartFlowCtrl ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *ValueStr; >+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl; >+ >+ ValueStr = GetNextParamStr (&TextDeviceNode); >+ UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) >CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_VENDOR_DP, >+ (UINT16) sizeof >(UART_FLOW_CONTROL_DEVICE_PATH) >+ ); >+ >+ CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid); >+ if (StrCmp (ValueStr, L"XonXoff") == 0) { >+ UartFlowControl->FlowControlMap = 2; >+ } else if (StrCmp (ValueStr, L"Hardware") == 0) { >+ UartFlowControl->FlowControlMap = 1; >+ } else { >+ UartFlowControl->FlowControlMap = 0; >+ } >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl; >+} >+ >+/** >+ Converts a text device path node to Serial Attached SCSI device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Serial Attached SCSI device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextSAS ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *AddressStr; >+ CHAR16 *LunStr; >+ CHAR16 *RTPStr; >+ CHAR16 *SASSATAStr; >+ CHAR16 *LocationStr; >+ CHAR16 *ConnectStr; >+ CHAR16 *DriveBayStr; >+ CHAR16 *ReservedStr; >+ UINT16 Info; >+ UINT16 Uint16; >+ SAS_DEVICE_PATH *Sas; >+ >+ AddressStr = GetNextParamStr (&TextDeviceNode); >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ RTPStr = GetNextParamStr (&TextDeviceNode); >+ SASSATAStr = GetNextParamStr (&TextDeviceNode); >+ LocationStr = GetNextParamStr (&TextDeviceNode); >+ ConnectStr = GetNextParamStr (&TextDeviceNode); >+ DriveBayStr = GetNextParamStr (&TextDeviceNode); >+ ReservedStr = GetNextParamStr (&TextDeviceNode); >+ Sas = (SAS_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_VENDOR_DP, >+ (UINT16) sizeof (SAS_DEVICE_PATH) >+ ); >+ >+ CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid); >+ Strtoi64 (AddressStr, &Sas->SasAddress); >+ Strtoi64 (LunStr, &Sas->Lun); >+ Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr); >+ >+ if (StrCmp (SASSATAStr, L"NoTopology") == 0) { >+ Info = 0x0; >+ >+ } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, >L"SAS") == 0)) { >+ >+ Uint16 = (UINT16) Strtoi (DriveBayStr); >+ if (Uint16 == 0) { >+ Info = 0x1; >+ } else { >+ Info = (UINT16) (0x2 | ((Uint16 - 1) << 8)); >+ } >+ >+ if (StrCmp (SASSATAStr, L"SATA") == 0) { >+ Info |= BIT4; >+ } >+ >+ // >+ // Location is an integer between 0 and 1 or else >+ // the keyword Internal (0) or External (1). >+ // >+ if (StrCmp (LocationStr, L"External") == 0) { >+ Uint16 = 1; >+ } else if (StrCmp (LocationStr, L"Internal") == 0) { >+ Uint16 = 0; >+ } else { >+ Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0); >+ } >+ Info |= (Uint16 << 5); >+ >+ // >+ // Connect is an integer between 0 and 3 or else >+ // the keyword Direct (0) or Expanded (1). >+ // >+ if (StrCmp (ConnectStr, L"Expanded") == 0) { >+ Uint16 = 1; >+ } else if (StrCmp (ConnectStr, L"Direct") == 0) { >+ Uint16 = 0; >+ } else { >+ Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1)); >+ } >+ Info |= (Uint16 << 6); >+ >+ } else { >+ Info = (UINT16) Strtoi (SASSATAStr); >+ } >+ >+ Sas->DeviceTopology = Info; >+ Sas->Reserved = (UINT32) Strtoi (ReservedStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Sas; >+} >+ >+/** >+ Converts a text device path node to Serial Attached SCSI Ex device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Serial Attached SCSI Ex device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextSasEx ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *AddressStr; >+ CHAR16 *LunStr; >+ CHAR16 *RTPStr; >+ CHAR16 *SASSATAStr; >+ CHAR16 *LocationStr; >+ CHAR16 *ConnectStr; >+ CHAR16 *DriveBayStr; >+ UINT16 Info; >+ UINT16 Uint16; >+ UINT64 SasAddress; >+ UINT64 Lun; >+ SASEX_DEVICE_PATH *SasEx; >+ >+ AddressStr = GetNextParamStr (&TextDeviceNode); >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ RTPStr = GetNextParamStr (&TextDeviceNode); >+ SASSATAStr = GetNextParamStr (&TextDeviceNode); >+ LocationStr = GetNextParamStr (&TextDeviceNode); >+ ConnectStr = GetNextParamStr (&TextDeviceNode); >+ DriveBayStr = GetNextParamStr (&TextDeviceNode); >+ SasEx = (SASEX_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_SASEX_DP, >+ (UINT16) sizeof (SASEX_DEVICE_PATH) >+ ); >+ >+ Strtoi64 (AddressStr, &SasAddress); >+ Strtoi64 (LunStr, &Lun); >+ WriteUnaligned64 ((UINT64 *) &SasEx->SasAddress, SwapBytes64 >(SasAddress)); >+ WriteUnaligned64 ((UINT64 *) &SasEx->Lun, SwapBytes64 (Lun)); >+ SasEx->RelativeTargetPort = (UINT16) Strtoi (RTPStr); >+ >+ if (StrCmp (SASSATAStr, L"NoTopology") == 0) { >+ Info = 0x0; >+ >+ } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, >L"SAS") == 0)) { >+ >+ Uint16 = (UINT16) Strtoi (DriveBayStr); >+ if (Uint16 == 0) { >+ Info = 0x1; >+ } else { >+ Info = (UINT16) (0x2 | ((Uint16 - 1) << 8)); >+ } >+ >+ if (StrCmp (SASSATAStr, L"SATA") == 0) { >+ Info |= BIT4; >+ } >+ >+ // >+ // Location is an integer between 0 and 1 or else >+ // the keyword Internal (0) or External (1). >+ // >+ if (StrCmp (LocationStr, L"External") == 0) { >+ Uint16 = 1; >+ } else if (StrCmp (LocationStr, L"Internal") == 0) { >+ Uint16 = 0; >+ } else { >+ Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0); >+ } >+ Info |= (Uint16 << 5); >+ >+ // >+ // Connect is an integer between 0 and 3 or else >+ // the keyword Direct (0) or Expanded (1). >+ // >+ if (StrCmp (ConnectStr, L"Expanded") == 0) { >+ Uint16 = 1; >+ } else if (StrCmp (ConnectStr, L"Direct") == 0) { >+ Uint16 = 0; >+ } else { >+ Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1)); >+ } >+ Info |= (Uint16 << 6); >+ >+ } else { >+ Info = (UINT16) Strtoi (SASSATAStr); >+ } >+ >+ SasEx->DeviceTopology = Info; >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) SasEx; >+} >+ >+/** >+ Converts a text device path node to NVM Express Namespace device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created NVM Express Namespace device >path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextNVMe ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *NamespaceIdStr; >+ CHAR16 *NamespaceUuidStr; >+ NVME_NAMESPACE_DEVICE_PATH *Nvme; >+ UINT8 *Uuid; >+ UINTN Index; >+ >+ NamespaceIdStr = GetNextParamStr (&TextDeviceNode); >+ NamespaceUuidStr = GetNextParamStr (&TextDeviceNode); >+ Nvme = (NVME_NAMESPACE_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_NVME_NAMESPACE_DP, >+ (UINT16) sizeof (NVME_NAMESPACE_DEVICE_PATH) >+ ); >+ >+ Nvme->NamespaceId = (UINT32) Strtoi (NamespaceIdStr); >+ Uuid = (UINT8 *) &Nvme->NamespaceUuid; >+ >+ Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8); >+ while (Index-- != 0) { >+ Uuid[Index] = (UINT8) StrHexToUintn (SplitStr (&NamespaceUuidStr, L'-')); >+ } >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Nvme; >+} >+ >+/** >+ Converts a text device path node to UFS device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created UFS device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUfs ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *PunStr; >+ CHAR16 *LunStr; >+ UFS_DEVICE_PATH *Ufs; >+ >+ PunStr = GetNextParamStr (&TextDeviceNode); >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ Ufs = (UFS_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_UFS_DP, >+ (UINT16) sizeof (UFS_DEVICE_PATH) >+ ); >+ >+ Ufs->Pun = (UINT8) Strtoi (PunStr); >+ Ufs->Lun = (UINT8) Strtoi (LunStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Ufs; >+} >+ >+/** >+ Converts a text device path node to SD (Secure Digital) device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created SD device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextSd ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *SlotNumberStr; >+ SD_DEVICE_PATH *Sd; >+ >+ SlotNumberStr = GetNextParamStr (&TextDeviceNode); >+ Sd = (SD_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_SD_DP, >+ (UINT16) sizeof (SD_DEVICE_PATH) >+ ); >+ >+ Sd->SlotNumber = (UINT8) Strtoi (SlotNumberStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Sd; >+} >+ >+/** >+ Converts a text device path node to EMMC (Embedded MMC) device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created EMMC device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextEmmc ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *SlotNumberStr; >+ EMMC_DEVICE_PATH *Emmc; >+ >+ SlotNumberStr = GetNextParamStr (&TextDeviceNode); >+ Emmc = (EMMC_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_EMMC_DP, >+ (UINT16) sizeof (EMMC_DEVICE_PATH) >+ ); >+ >+ Emmc->SlotNumber = (UINT8) Strtoi (SlotNumberStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Emmc; >+} >+ >+/** >+ Converts a text device path node to Debug Port device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Debug Port device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextDebugPort ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ VENDOR_DEFINED_MESSAGING_DEVICE_PATH *Vend; >+ >+ Vend = (VENDOR_DEFINED_MESSAGING_DEVICE_PATH *) >CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_VENDOR_DP, >+ (UINT16) sizeof >(VENDOR_DEFINED_MESSAGING_DEVICE_PATH) >+ ); >+ >+ CopyGuid (&Vend->Guid, &gEfiDebugPortDevicePathGuid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Vend; >+} >+ >+/** >+ Converts a text device path node to MAC device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created MAC device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextMAC ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *AddressStr; >+ CHAR16 *IfTypeStr; >+ UINTN Length; >+ MAC_ADDR_DEVICE_PATH *MACDevPath; >+ >+ AddressStr = GetNextParamStr (&TextDeviceNode); >+ IfTypeStr = GetNextParamStr (&TextDeviceNode); >+ MACDevPath = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_MAC_ADDR_DP, >+ (UINT16) sizeof (MAC_ADDR_DEVICE_PATH) >+ ); >+ >+ MACDevPath->IfType = (UINT8) Strtoi (IfTypeStr); >+ >+ Length = sizeof (EFI_MAC_ADDRESS); >+ if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) { >+ Length = 6; >+ } >+ >+ StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, >Length); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath; >+} >+ >+ >+/** >+ Converts a text format to the network protocol ID. >+ >+ @param Text String of protocol field. >+ >+ @return Network protocol ID . >+ >+**/ >+UINTN >+NetworkProtocolFromText ( >+ CHAR16 *Text >+ ) >+{ >+ if (StrCmp (Text, L"UDP") == 0) { >+ return RFC_1700_UDP_PROTOCOL; >+ } >+ >+ if (StrCmp (Text, L"TCP") == 0) { >+ return RFC_1700_TCP_PROTOCOL; >+ } >+ >+ return Strtoi (Text); >+} >+ >+ >+/** >+ Converts a text device path node to IPV4 device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created IPV4 device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextIPv4 ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *RemoteIPStr; >+ CHAR16 *ProtocolStr; >+ CHAR16 *TypeStr; >+ CHAR16 *LocalIPStr; >+ CHAR16 *GatewayIPStr; >+ CHAR16 *SubnetMaskStr; >+ IPv4_DEVICE_PATH *IPv4; >+ >+ RemoteIPStr = GetNextParamStr (&TextDeviceNode); >+ ProtocolStr = GetNextParamStr (&TextDeviceNode); >+ TypeStr = GetNextParamStr (&TextDeviceNode); >+ LocalIPStr = GetNextParamStr (&TextDeviceNode); >+ GatewayIPStr = GetNextParamStr (&TextDeviceNode); >+ SubnetMaskStr = GetNextParamStr (&TextDeviceNode); >+ IPv4 = (IPv4_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_IPv4_DP, >+ (UINT16) sizeof (IPv4_DEVICE_PATH) >+ ); >+ >+ StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL); >+ IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr); >+ if (StrCmp (TypeStr, L"Static") == 0) { >+ IPv4->StaticIpAddress = TRUE; >+ } else { >+ IPv4->StaticIpAddress = FALSE; >+ } >+ >+ StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL); >+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) { >+ StrToIpv4Address (GatewayIPStr, NULL, &IPv4->GatewayIpAddress, >NULL); >+ StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask, NULL); >+ } else { >+ ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress)); >+ ZeroMem (&IPv4->SubnetMask, sizeof (IPv4->SubnetMask)); >+ } >+ >+ IPv4->LocalPort = 0; >+ IPv4->RemotePort = 0; >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv4; >+} >+ >+/** >+ Converts a text device path node to IPV6 device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created IPV6 device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextIPv6 ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *RemoteIPStr; >+ CHAR16 *ProtocolStr; >+ CHAR16 *TypeStr; >+ CHAR16 *LocalIPStr; >+ CHAR16 *GatewayIPStr; >+ CHAR16 *PrefixLengthStr; >+ IPv6_DEVICE_PATH *IPv6; >+ >+ RemoteIPStr = GetNextParamStr (&TextDeviceNode); >+ ProtocolStr = GetNextParamStr (&TextDeviceNode); >+ TypeStr = GetNextParamStr (&TextDeviceNode); >+ LocalIPStr = GetNextParamStr (&TextDeviceNode); >+ PrefixLengthStr = GetNextParamStr (&TextDeviceNode); >+ GatewayIPStr = GetNextParamStr (&TextDeviceNode); >+ IPv6 = (IPv6_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_IPv6_DP, >+ (UINT16) sizeof (IPv6_DEVICE_PATH) >+ ); >+ >+ StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL); >+ IPv6->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr); >+ if (StrCmp (TypeStr, L"Static") == 0) { >+ IPv6->IpAddressOrigin = 0; >+ } else if (StrCmp (TypeStr, L"StatelessAutoConfigure") == 0) { >+ IPv6->IpAddressOrigin = 1; >+ } else { >+ IPv6->IpAddressOrigin = 2; >+ } >+ >+ StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL); >+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) { >+ StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL); >+ IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr); >+ } else { >+ ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress)); >+ IPv6->PrefixLength = 0; >+ } >+ >+ IPv6->LocalPort = 0; >+ IPv6->RemotePort = 0; >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv6; >+} >+ >+/** >+ Converts a text device path node to UART device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created UART device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUart ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *BaudStr; >+ CHAR16 *DataBitsStr; >+ CHAR16 *ParityStr; >+ CHAR16 *StopBitsStr; >+ UART_DEVICE_PATH *Uart; >+ >+ BaudStr = GetNextParamStr (&TextDeviceNode); >+ DataBitsStr = GetNextParamStr (&TextDeviceNode); >+ ParityStr = GetNextParamStr (&TextDeviceNode); >+ StopBitsStr = GetNextParamStr (&TextDeviceNode); >+ Uart = (UART_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_UART_DP, >+ (UINT16) sizeof (UART_DEVICE_PATH) >+ ); >+ >+ if (StrCmp (BaudStr, L"DEFAULT") == 0) { >+ Uart->BaudRate = 115200; >+ } else { >+ Strtoi64 (BaudStr, &Uart->BaudRate); >+ } >+ Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : >Strtoi (DataBitsStr)); >+ switch (*ParityStr) { >+ case L'D': >+ Uart->Parity = 0; >+ break; >+ >+ case L'N': >+ Uart->Parity = 1; >+ break; >+ >+ case L'E': >+ Uart->Parity = 2; >+ break; >+ >+ case L'O': >+ Uart->Parity = 3; >+ break; >+ >+ case L'M': >+ Uart->Parity = 4; >+ break; >+ >+ case L'S': >+ Uart->Parity = 5; >+ break; >+ >+ default: >+ Uart->Parity = (UINT8) Strtoi (ParityStr); >+ break; >+ } >+ >+ if (StrCmp (StopBitsStr, L"D") == 0) { >+ Uart->StopBits = (UINT8) 0; >+ } else if (StrCmp (StopBitsStr, L"1") == 0) { >+ Uart->StopBits = (UINT8) 1; >+ } else if (StrCmp (StopBitsStr, L"1.5") == 0) { >+ Uart->StopBits = (UINT8) 2; >+ } else if (StrCmp (StopBitsStr, L"2") == 0) { >+ Uart->StopBits = (UINT8) 3; >+ } else { >+ Uart->StopBits = (UINT8) Strtoi (StopBitsStr); >+ } >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Uart; >+} >+ >+/** >+ Converts a text device path node to USB class device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ @param UsbClassText A pointer to USB_CLASS_TEXT structure to be >integrated to USB Class Text. >+ >+ @return A pointer to the newly-created USB class device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+ConvertFromTextUsbClass ( >+ CHAR16 *TextDeviceNode, >+ USB_CLASS_TEXT *UsbClassText >+ ) >+{ >+ CHAR16 *VIDStr; >+ CHAR16 *PIDStr; >+ CHAR16 *ClassStr; >+ CHAR16 *SubClassStr; >+ CHAR16 *ProtocolStr; >+ USB_CLASS_DEVICE_PATH *UsbClass; >+ >+ UsbClass = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_USB_CLASS_DP, >+ (UINT16) sizeof (USB_CLASS_DEVICE_PATH) >+ ); >+ >+ VIDStr = GetNextParamStr (&TextDeviceNode); >+ PIDStr = GetNextParamStr (&TextDeviceNode); >+ if (UsbClassText->ClassExist) { >+ ClassStr = GetNextParamStr (&TextDeviceNode); >+ UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr); >+ } else { >+ UsbClass->DeviceClass = UsbClassText->Class; >+ } >+ if (UsbClassText->SubClassExist) { >+ SubClassStr = GetNextParamStr (&TextDeviceNode); >+ UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr); >+ } else { >+ UsbClass->DeviceSubClass = UsbClassText->SubClass; >+ } >+ >+ ProtocolStr = GetNextParamStr (&TextDeviceNode); >+ >+ UsbClass->VendorId = (UINT16) Strtoi (VIDStr); >+ UsbClass->ProductId = (UINT16) Strtoi (PIDStr); >+ UsbClass->DeviceProtocol = (UINT8) Strtoi (ProtocolStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass; >+} >+ >+ >+/** >+ Converts a text device path node to USB class device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB class device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbClass ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = TRUE; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB audio device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB audio device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbAudio ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_AUDIO; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB CDC Control device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB CDC Control device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbCDCControl ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_CDCCONTROL; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB HID device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB HID device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbHID ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_HID; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB Image device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB Image device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbImage ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_IMAGE; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB Print device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB Print device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbPrinter ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_PRINTER; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB mass storage device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB mass storage device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbMassStorage ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_MASS_STORAGE; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB HUB device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB HUB device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbHub ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_HUB; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB CDC data device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB CDC data device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbCDCData ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_CDCDATA; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB smart card device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB smart card device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbSmartCard ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_SMART_CARD; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB video device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB video device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbVideo ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_VIDEO; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB diagnostic device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB diagnostic device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbDiagnostic ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_DIAGNOSTIC; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB wireless device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB wireless device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbWireless ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_WIRELESS; >+ UsbClassText.SubClassExist = TRUE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB device firmware update device >path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB device firmware update >device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbDeviceFirmwareUpdate ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_RESERVE; >+ UsbClassText.SubClassExist = FALSE; >+ UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB IRDA bridge device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB IRDA bridge device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbIrdaBridge ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_RESERVE; >+ UsbClassText.SubClassExist = FALSE; >+ UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB text and measurement device >path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB text and measurement device >path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbTestAndMeasurement ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ USB_CLASS_TEXT UsbClassText; >+ >+ UsbClassText.ClassExist = FALSE; >+ UsbClassText.Class = USB_CLASS_RESERVE; >+ UsbClassText.SubClassExist = FALSE; >+ UsbClassText.SubClass = USB_SUBCLASS_TEST; >+ >+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); >+} >+ >+/** >+ Converts a text device path node to USB WWID device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created USB WWID device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUsbWwid ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *VIDStr; >+ CHAR16 *PIDStr; >+ CHAR16 *InterfaceNumStr; >+ CHAR16 *SerialNumberStr; >+ USB_WWID_DEVICE_PATH *UsbWwid; >+ UINTN SerialNumberStrLen; >+ >+ VIDStr = GetNextParamStr (&TextDeviceNode); >+ PIDStr = GetNextParamStr (&TextDeviceNode); >+ InterfaceNumStr = GetNextParamStr (&TextDeviceNode); >+ SerialNumberStr = GetNextParamStr (&TextDeviceNode); >+ SerialNumberStrLen = StrLen (SerialNumberStr); >+ if (SerialNumberStrLen >= 2 && >+ SerialNumberStr[0] == L'\"' && >+ SerialNumberStr[SerialNumberStrLen - 1] == L'\"' >+ ) { >+ SerialNumberStr[SerialNumberStrLen - 1] = L'\0'; >+ SerialNumberStr++; >+ SerialNumberStrLen -= 2; >+ } >+ UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_USB_WWID_DP, >+ (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + >SerialNumberStrLen * sizeof (CHAR16)) >+ ); >+ UsbWwid->VendorId = (UINT16) Strtoi (VIDStr); >+ UsbWwid->ProductId = (UINT16) Strtoi (PIDStr); >+ UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr); >+ >+ // >+ // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr. >+ // Therefore, the '\0' will not be copied. >+ // >+ memcpy ( >+ (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH), >+ SerialNumberStr, >+ SerialNumberStrLen * sizeof (CHAR16) >+ ); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid; >+} >+ >+/** >+ Converts a text device path node to Logic Unit device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Logic Unit device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUnit ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *LunStr; >+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit; >+ >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode >( >+ MESSAGING_DEVICE_PATH, >+ MSG_DEVICE_LOGICAL_UNIT_DP, >+ (UINT16) sizeof >(DEVICE_LOGICAL_UNIT_DEVICE_PATH) >+ ); >+ >+ LogicalUnit->Lun = (UINT8) Strtoi (LunStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit; >+} >+ >+/** >+ Converts a text device path node to iSCSI device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created iSCSI device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextiSCSI ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ UINT16 Options; >+ CHAR16 *NameStr; >+ CHAR16 *PortalGroupStr; >+ CHAR16 *LunStr; >+ CHAR16 *HeaderDigestStr; >+ CHAR16 *DataDigestStr; >+ CHAR16 *AuthenticationStr; >+ CHAR16 *ProtocolStr; >+ CHAR8 *AsciiStr; >+ ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath; >+ >+ NameStr = GetNextParamStr (&TextDeviceNode); >+ PortalGroupStr = GetNextParamStr (&TextDeviceNode); >+ LunStr = GetNextParamStr (&TextDeviceNode); >+ HeaderDigestStr = GetNextParamStr (&TextDeviceNode); >+ DataDigestStr = GetNextParamStr (&TextDeviceNode); >+ AuthenticationStr = GetNextParamStr (&TextDeviceNode); >+ ProtocolStr = GetNextParamStr (&TextDeviceNode); >+ ISCSIDevPath = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode >( >+ MESSAGING_DEVICE_PATH, >+ MSG_ISCSI_DP, >+ (UINT16) (sizeof >(ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr)) >+ ); >+ >+ AsciiStr = ISCSIDevPath->TargetName; >+ StrToAscii (NameStr, &AsciiStr); >+ >+ ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr); >+ Strtoi64 (LunStr, &ISCSIDevPath->Lun); >+ >+ Options = 0x0000; >+ if (StrCmp (HeaderDigestStr, L"CRC32C") == 0) { >+ Options |= 0x0002; >+ } >+ >+ if (StrCmp (DataDigestStr, L"CRC32C") == 0) { >+ Options |= 0x0008; >+ } >+ >+ if (StrCmp (AuthenticationStr, L"None") == 0) { >+ Options |= 0x0800; >+ } >+ >+ if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) { >+ Options |= 0x1000; >+ } >+ >+ ISCSIDevPath->LoginOption = (UINT16) Options; >+ >+ if (StrCmp (ProtocolStr, L"TCP") == 0) { >+ ISCSIDevPath->NetworkProtocol = 0; >+ } else { >+ // >+ // Undefined and reserved. >+ // >+ ISCSIDevPath->NetworkProtocol = 1; >+ } >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath; >+} >+ >+/** >+ Converts a text device path node to VLAN device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created VLAN device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVlan ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *VlanStr; >+ VLAN_DEVICE_PATH *Vlan; >+ >+ VlanStr = GetNextParamStr (&TextDeviceNode); >+ Vlan = (VLAN_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_VLAN_DP, >+ (UINT16) sizeof (VLAN_DEVICE_PATH) >+ ); >+ >+ Vlan->VlanId = (UINT16) Strtoi (VlanStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Vlan; >+} >+ >+/** >+ Converts a text device path node to Bluetooth device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Bluetooth device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextBluetooth ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *BluetoothStr; >+ BLUETOOTH_DEVICE_PATH *BluetoothDp; >+ >+ BluetoothStr = GetNextParamStr (&TextDeviceNode); >+ BluetoothDp = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_BLUETOOTH_DP, >+ (UINT16) sizeof (BLUETOOTH_DEVICE_PATH) >+ ); >+ StrHexToBytes ( >+ BluetoothStr, >+ sizeof (BLUETOOTH_ADDRESS) * 2, >+ BluetoothDp->BD_ADDR.Address, >+ sizeof (BLUETOOTH_ADDRESS) >+ ); >+ return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp; >+} >+ >+/** >+ Converts a text device path node to Wi-Fi device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Wi-Fi device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextWiFi ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *SSIdStr; >+ CHAR8 AsciiStr[33]; >+ UINTN DataLen; >+ WIFI_DEVICE_PATH *WiFiDp; >+ >+ SSIdStr = GetNextParamStr (&TextDeviceNode); >+ WiFiDp = (WIFI_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_WIFI_DP, >+ (UINT16) sizeof (WIFI_DEVICE_PATH) >+ ); >+ >+ if (NULL != SSIdStr) { >+ DataLen = StrLen (SSIdStr); >+ if (StrLen (SSIdStr) > 32) { >+ SSIdStr[32] = L'\0'; >+ DataLen = 32; >+ } >+ >+ UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr)); >+ memcpy (WiFiDp->SSId, AsciiStr, DataLen); >+ } >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp; >+} >+ >+/** >+ Converts a text device path node to URI device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created URI device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextUri ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *UriStr; >+ UINTN UriLength; >+ URI_DEVICE_PATH *Uri; >+ >+ UriStr = GetNextParamStr (&TextDeviceNode); >+ UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH)); >+ Uri = (URI_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_URI_DP, >+ (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength) >+ ); >+ >+ while (UriLength-- != 0) { >+ Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength]; >+ } >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Uri; >+} >+ >+/** >+ Converts a media text device path node to media device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to media device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextMediaPath ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, >TextDeviceNode); >+} >+ >+/** >+ Converts a text device path node to HD device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created HD device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextHD ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *PartitionStr; >+ CHAR16 *TypeStr; >+ CHAR16 *SignatureStr; >+ CHAR16 *StartStr; >+ CHAR16 *SizeStr; >+ UINT32 Signature32; >+ HARDDRIVE_DEVICE_PATH *Hd; >+ >+ PartitionStr = GetNextParamStr (&TextDeviceNode); >+ TypeStr = GetNextParamStr (&TextDeviceNode); >+ SignatureStr = GetNextParamStr (&TextDeviceNode); >+ StartStr = GetNextParamStr (&TextDeviceNode); >+ SizeStr = GetNextParamStr (&TextDeviceNode); >+ Hd = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_HARDDRIVE_DP, >+ (UINT16) sizeof (HARDDRIVE_DEVICE_PATH) >+ ); >+ >+ Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr); >+ >+ ZeroMem (Hd->Signature, 16); >+ Hd->MBRType = (UINT8) 0; >+ >+ if (StrCmp (TypeStr, L"MBR") == 0) { >+ Hd->SignatureType = SIGNATURE_TYPE_MBR; >+ Hd->MBRType = 0x01; >+ >+ Signature32 = (UINT32) Strtoi (SignatureStr); >+ memcpy (Hd->Signature, &Signature32, sizeof (UINT32)); >+ } else if (StrCmp (TypeStr, L"GPT") == 0) { >+ Hd->SignatureType = SIGNATURE_TYPE_GUID; >+ Hd->MBRType = 0x02; >+ >+ StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature); >+ } else { >+ Hd->SignatureType = (UINT8) Strtoi (TypeStr); >+ } >+ >+ Strtoi64 (StartStr, &Hd->PartitionStart); >+ Strtoi64 (SizeStr, &Hd->PartitionSize); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Hd; >+} >+ >+/** >+ Converts a text device path node to CDROM device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created CDROM device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextCDROM ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *EntryStr; >+ CHAR16 *StartStr; >+ CHAR16 *SizeStr; >+ CDROM_DEVICE_PATH *CDROMDevPath; >+ >+ EntryStr = GetNextParamStr (&TextDeviceNode); >+ StartStr = GetNextParamStr (&TextDeviceNode); >+ SizeStr = GetNextParamStr (&TextDeviceNode); >+ CDROMDevPath = (CDROM_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_CDROM_DP, >+ (UINT16) sizeof (CDROM_DEVICE_PATH) >+ ); >+ >+ CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr); >+ Strtoi64 (StartStr, &CDROMDevPath->PartitionStart); >+ Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath; >+} >+ >+/** >+ Converts a text device path node to Vendor-defined media device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Vendor-defined media device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVenMedia ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return ConvertFromTextVendor ( >+ TextDeviceNode, >+ MEDIA_DEVICE_PATH, >+ MEDIA_VENDOR_DP >+ ); >+} >+ >+/** >+ Converts a text device path node to File device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created File device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextFilePath ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ FILEPATH_DEVICE_PATH *File; >+ >+ File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_FILEPATH_DP, >+ (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen >(TextDeviceNode) * 2) >+ ); >+ >+ StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) File; >+} >+ >+/** >+ Converts a text device path node to Media protocol device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Media protocol device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextMedia ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *GuidStr; >+ MEDIA_PROTOCOL_DEVICE_PATH *Media; >+ >+ GuidStr = GetNextParamStr (&TextDeviceNode); >+ Media = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_PROTOCOL_DP, >+ (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH) >+ ); >+ >+ StrToGuid (GuidStr, &Media->Protocol); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Media; >+} >+ >+/** >+ Converts a text device path node to firmware volume device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created firmware volume device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextFv ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *GuidStr; >+ MEDIA_FW_VOL_DEVICE_PATH *Fv; >+ >+ GuidStr = GetNextParamStr (&TextDeviceNode); >+ Fv = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_PIWG_FW_VOL_DP, >+ (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH) >+ ); >+ >+ StrToGuid (GuidStr, &Fv->FvName); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Fv; >+} >+ >+/** >+ Converts a text device path node to firmware file device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created firmware file device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextFvFile ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *GuidStr; >+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile; >+ >+ GuidStr = GetNextParamStr (&TextDeviceNode); >+ FvFile = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_PIWG_FW_FILE_DP, >+ (UINT16) sizeof >(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) >+ ); >+ >+ StrToGuid (GuidStr, &FvFile->FvFileName); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) FvFile; >+} >+ >+/** >+ Converts a text device path node to text relative offset device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Text device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextRelativeOffsetRange ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *StartingOffsetStr; >+ CHAR16 *EndingOffsetStr; >+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset; >+ >+ StartingOffsetStr = GetNextParamStr (&TextDeviceNode); >+ EndingOffsetStr = GetNextParamStr (&TextDeviceNode); >+ Offset = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) >CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_RELATIVE_OFFSET_RANGE_DP, >+ (UINT16) sizeof >(MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH) >+ ); >+ >+ Strtoi64 (StartingOffsetStr, &Offset->StartingOffset); >+ Strtoi64 (EndingOffsetStr, &Offset->EndingOffset); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Offset; >+} >+ >+/** >+ Converts a text device path node to text ram disk device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Text device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextRamDisk ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *StartingAddrStr; >+ CHAR16 *EndingAddrStr; >+ CHAR16 *TypeGuidStr; >+ CHAR16 *InstanceStr; >+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; >+ UINT64 StartingAddr; >+ UINT64 EndingAddr; >+ >+ StartingAddrStr = GetNextParamStr (&TextDeviceNode); >+ EndingAddrStr = GetNextParamStr (&TextDeviceNode); >+ InstanceStr = GetNextParamStr (&TextDeviceNode); >+ TypeGuidStr = GetNextParamStr (&TextDeviceNode); >+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_RAM_DISK_DP, >+ (UINT16) sizeof >(MEDIA_RAM_DISK_DEVICE_PATH) >+ ); >+ >+ Strtoi64 (StartingAddrStr, &StartingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); >+ Strtoi64 (EndingAddrStr, &EndingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); >+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr); >+ StrToGuid (TypeGuidStr, &RamDisk->TypeGuid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; >+} >+ >+/** >+ Converts a text device path node to text virtual disk device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Text device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVirtualDisk ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *StartingAddrStr; >+ CHAR16 *EndingAddrStr; >+ CHAR16 *InstanceStr; >+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; >+ UINT64 StartingAddr; >+ UINT64 EndingAddr; >+ >+ StartingAddrStr = GetNextParamStr (&TextDeviceNode); >+ EndingAddrStr = GetNextParamStr (&TextDeviceNode); >+ InstanceStr = GetNextParamStr (&TextDeviceNode); >+ >+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_RAM_DISK_DP, >+ (UINT16) sizeof >(MEDIA_RAM_DISK_DEVICE_PATH) >+ ); >+ >+ Strtoi64 (StartingAddrStr, &StartingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); >+ Strtoi64 (EndingAddrStr, &EndingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); >+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr); >+ CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; >+} >+ >+/** >+ Converts a text device path node to text virtual cd device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Text device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextVirtualCd ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *StartingAddrStr; >+ CHAR16 *EndingAddrStr; >+ CHAR16 *InstanceStr; >+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; >+ UINT64 StartingAddr; >+ UINT64 EndingAddr; >+ >+ StartingAddrStr = GetNextParamStr (&TextDeviceNode); >+ EndingAddrStr = GetNextParamStr (&TextDeviceNode); >+ InstanceStr = GetNextParamStr (&TextDeviceNode); >+ >+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_RAM_DISK_DP, >+ (UINT16) sizeof >(MEDIA_RAM_DISK_DEVICE_PATH) >+ ); >+ >+ Strtoi64 (StartingAddrStr, &StartingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); >+ Strtoi64 (EndingAddrStr, &EndingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); >+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr); >+ CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; >+} >+ >+/** >+ Converts a text device path node to text persistent virtual disk device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Text device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextPersistentVirtualDisk ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *StartingAddrStr; >+ CHAR16 *EndingAddrStr; >+ CHAR16 *InstanceStr; >+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; >+ UINT64 StartingAddr; >+ UINT64 EndingAddr; >+ >+ StartingAddrStr = GetNextParamStr (&TextDeviceNode); >+ EndingAddrStr = GetNextParamStr (&TextDeviceNode); >+ InstanceStr = GetNextParamStr (&TextDeviceNode); >+ >+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_RAM_DISK_DP, >+ (UINT16) sizeof >(MEDIA_RAM_DISK_DEVICE_PATH) >+ ); >+ >+ Strtoi64 (StartingAddrStr, &StartingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); >+ Strtoi64 (EndingAddrStr, &EndingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); >+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr); >+ CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; >+} >+ >+/** >+ Converts a text device path node to text persistent virtual cd device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created Text device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextPersistentVirtualCd ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *StartingAddrStr; >+ CHAR16 *EndingAddrStr; >+ CHAR16 *InstanceStr; >+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; >+ UINT64 StartingAddr; >+ UINT64 EndingAddr; >+ >+ StartingAddrStr = GetNextParamStr (&TextDeviceNode); >+ EndingAddrStr = GetNextParamStr (&TextDeviceNode); >+ InstanceStr = GetNextParamStr (&TextDeviceNode); >+ >+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( >+ MEDIA_DEVICE_PATH, >+ MEDIA_RAM_DISK_DP, >+ (UINT16) sizeof >(MEDIA_RAM_DISK_DEVICE_PATH) >+ ); >+ >+ Strtoi64 (StartingAddrStr, &StartingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); >+ Strtoi64 (EndingAddrStr, &EndingAddr); >+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); >+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr); >+ CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; >+} >+ >+/** >+ Converts a BBS text device path node to BBS device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to BBS device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextBbsPath ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ return DevPathFromTextGenericPath (BBS_DEVICE_PATH, >TextDeviceNode); >+} >+ >+/** >+ Converts a text device path node to BIOS Boot Specification device path >structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created BIOS Boot Specification device path >structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextBBS ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ CHAR16 *TypeStr; >+ CHAR16 *IdStr; >+ CHAR16 *FlagsStr; >+ CHAR8 *AsciiStr; >+ BBS_BBS_DEVICE_PATH *Bbs; >+ >+ TypeStr = GetNextParamStr (&TextDeviceNode); >+ IdStr = GetNextParamStr (&TextDeviceNode); >+ FlagsStr = GetNextParamStr (&TextDeviceNode); >+ Bbs = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode ( >+ BBS_DEVICE_PATH, >+ BBS_BBS_DP, >+ (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen >(IdStr)) >+ ); >+ >+ if (StrCmp (TypeStr, L"Floppy") == 0) { >+ Bbs->DeviceType = BBS_TYPE_FLOPPY; >+ } else if (StrCmp (TypeStr, L"HD") == 0) { >+ Bbs->DeviceType = BBS_TYPE_HARDDRIVE; >+ } else if (StrCmp (TypeStr, L"CDROM") == 0) { >+ Bbs->DeviceType = BBS_TYPE_CDROM; >+ } else if (StrCmp (TypeStr, L"PCMCIA") == 0) { >+ Bbs->DeviceType = BBS_TYPE_PCMCIA; >+ } else if (StrCmp (TypeStr, L"USB") == 0) { >+ Bbs->DeviceType = BBS_TYPE_USB; >+ } else if (StrCmp (TypeStr, L"Network") == 0) { >+ Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK; >+ } else { >+ Bbs->DeviceType = (UINT16) Strtoi (TypeStr); >+ } >+ >+ AsciiStr = Bbs->String; >+ StrToAscii (IdStr, &AsciiStr); >+ >+ Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Bbs; >+} >+ >+/** >+ Converts a text device path node to SATA device path structure. >+ >+ @param TextDeviceNode The input Text device path node. >+ >+ @return A pointer to the newly-created SATA device path structure. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DevPathFromTextSata ( >+ CHAR16 *TextDeviceNode >+ ) >+{ >+ SATA_DEVICE_PATH *Sata; >+ CHAR16 *Param1; >+ CHAR16 *Param2; >+ CHAR16 *Param3; >+ >+ Param1 = GetNextParamStr (&TextDeviceNode); >+ Param2 = GetNextParamStr (&TextDeviceNode); >+ Param3 = GetNextParamStr (&TextDeviceNode); >+ >+ Sata = (SATA_DEVICE_PATH *) CreateDeviceNode ( >+ MESSAGING_DEVICE_PATH, >+ MSG_SATA_DP, >+ (UINT16) sizeof (SATA_DEVICE_PATH) >+ ); >+ Sata->HBAPortNumber = (UINT16) Strtoi (Param1); >+ Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2); >+ Sata->Lun = (UINT16) Strtoi (Param3); >+ >+ return (EFI_DEVICE_PATH_PROTOCOL *) Sata; >+} >+ >+DEVICE_PATH_FROM_TEXT_TABLE >mUefiDevicePathLibDevPathFromTextTable[] = { >+ {L"Path", DevPathFromTextPath }, >+ >+ {L"HardwarePath", DevPathFromTextHardwarePath }, >+ {L"Pci", DevPathFromTextPci }, >+ {L"PcCard", DevPathFromTextPcCard }, >+ {L"MemoryMapped", DevPathFromTextMemoryMapped }, >+ {L"VenHw", DevPathFromTextVenHw }, >+ {L"Ctrl", DevPathFromTextCtrl }, >+ {L"BMC", DevPathFromTextBmc }, >+ >+ {L"AcpiPath", DevPathFromTextAcpiPath }, >+ {L"Acpi", DevPathFromTextAcpi }, >+ {L"PciRoot", DevPathFromTextPciRoot }, >+ {L"PcieRoot", DevPathFromTextPcieRoot }, >+ {L"Floppy", DevPathFromTextFloppy }, >+ {L"Keyboard", DevPathFromTextKeyboard }, >+ {L"Serial", DevPathFromTextSerial }, >+ {L"ParallelPort", DevPathFromTextParallelPort }, >+ {L"AcpiEx", DevPathFromTextAcpiEx }, >+ {L"AcpiExp", DevPathFromTextAcpiExp }, >+ {L"AcpiAdr", DevPathFromTextAcpiAdr }, >+ >+ {L"Msg", DevPathFromTextMsg }, >+ {L"Ata", DevPathFromTextAta }, >+ {L"Scsi", DevPathFromTextScsi }, >+ {L"Fibre", DevPathFromTextFibre }, >+ {L"FibreEx", DevPathFromTextFibreEx }, >+ {L"I1394", DevPathFromText1394 }, >+ {L"USB", DevPathFromTextUsb }, >+ {L"I2O", DevPathFromTextI2O }, >+ {L"Infiniband", DevPathFromTextInfiniband }, >+ {L"VenMsg", DevPathFromTextVenMsg }, >+ {L"VenPcAnsi", DevPathFromTextVenPcAnsi }, >+ {L"VenVt100", DevPathFromTextVenVt100 }, >+ {L"VenVt100Plus", DevPathFromTextVenVt100Plus }, >+ {L"VenUtf8", DevPathFromTextVenUtf8 }, >+ {L"UartFlowCtrl", DevPathFromTextUartFlowCtrl }, >+ {L"SAS", DevPathFromTextSAS }, >+ {L"SasEx", DevPathFromTextSasEx }, >+ {L"NVMe", DevPathFromTextNVMe }, >+ {L"UFS", DevPathFromTextUfs }, >+ {L"SD", DevPathFromTextSd }, >+ {L"eMMC", DevPathFromTextEmmc }, >+ {L"DebugPort", DevPathFromTextDebugPort }, >+ {L"MAC", DevPathFromTextMAC }, >+ {L"IPv4", DevPathFromTextIPv4 }, >+ {L"IPv6", DevPathFromTextIPv6 }, >+ {L"Uart", DevPathFromTextUart }, >+ {L"UsbClass", DevPathFromTextUsbClass }, >+ {L"UsbAudio", DevPathFromTextUsbAudio }, >+ {L"UsbCDCControl", DevPathFromTextUsbCDCControl }, >+ {L"UsbHID", DevPathFromTextUsbHID }, >+ {L"UsbImage", DevPathFromTextUsbImage }, >+ {L"UsbPrinter", DevPathFromTextUsbPrinter }, >+ {L"UsbMassStorage", DevPathFromTextUsbMassStorage }, >+ {L"UsbHub", DevPathFromTextUsbHub }, >+ {L"UsbCDCData", DevPathFromTextUsbCDCData }, >+ {L"UsbSmartCard", DevPathFromTextUsbSmartCard }, >+ {L"UsbVideo", DevPathFromTextUsbVideo }, >+ {L"UsbDiagnostic", DevPathFromTextUsbDiagnostic }, >+ {L"UsbWireless", DevPathFromTextUsbWireless }, >+ {L"UsbDeviceFirmwareUpdate", >DevPathFromTextUsbDeviceFirmwareUpdate }, >+ {L"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge }, >+ {L"UsbTestAndMeasurement", >DevPathFromTextUsbTestAndMeasurement }, >+ {L"UsbWwid", DevPathFromTextUsbWwid }, >+ {L"Unit", DevPathFromTextUnit }, >+ {L"iSCSI", DevPathFromTextiSCSI }, >+ {L"Vlan", DevPathFromTextVlan }, >+ {L"Uri", DevPathFromTextUri }, >+ {L"Bluetooth", DevPathFromTextBluetooth }, >+ {L"Wi-Fi", DevPathFromTextWiFi }, >+ {L"MediaPath", DevPathFromTextMediaPath }, >+ {L"HD", DevPathFromTextHD }, >+ {L"CDROM", DevPathFromTextCDROM }, >+ {L"VenMedia", DevPathFromTextVenMedia }, >+ {L"Media", DevPathFromTextMedia }, >+ {L"Fv", DevPathFromTextFv }, >+ {L"FvFile", DevPathFromTextFvFile }, >+ {L"Offset", DevPathFromTextRelativeOffsetRange }, >+ {L"RamDisk", DevPathFromTextRamDisk }, >+ {L"VirtualDisk", DevPathFromTextVirtualDisk }, >+ {L"VirtualCD", DevPathFromTextVirtualCd }, >+ {L"PersistentVirtualDisk", DevPathFromTextPersistentVirtualDisk }, >+ {L"PersistentVirtualCD", DevPathFromTextPersistentVirtualCd }, >+ >+ {L"BbsPath", DevPathFromTextBbsPath }, >+ {L"BBS", DevPathFromTextBBS }, >+ {L"Sata", DevPathFromTextSata }, >+ {NULL, NULL} >+}; >+ >+/** >+ Convert text to the binary representation of a device node. >+ >+ @param TextDeviceNode TextDeviceNode points to the text >representation of a device >+ node. Conversion starts with the first character and continues >+ until the first non-device node character. >+ >+ @return A pointer to the EFI device node or NULL if TextDeviceNode is >NULL or there was >+ insufficient memory or text unsupported. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibConvertTextToDeviceNode ( >+ CONST CHAR16 *TextDeviceNode >+ ) >+{ >+ DEVICE_PATH_FROM_TEXT FromText; >+ CHAR16 *ParamStr; >+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode; >+ CHAR16 *DeviceNodeStr; >+ UINTN Index; >+ >+ if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) { >+ return NULL; >+ } >+ >+ ParamStr = NULL; >+ FromText = NULL; >+ DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode); >+ ASSERT (DeviceNodeStr != NULL); >+ >+ for (Index = 0; >mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; >Index++) { >+ ParamStr = GetParamByNodeName (DeviceNodeStr, >mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText); >+ if (ParamStr != NULL) { >+ FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function; >+ break; >+ } >+ } >+ >+ if (FromText == NULL) { >+ // >+ // A file path >+ // >+ FromText = DevPathFromTextFilePath; >+ DeviceNode = FromText (DeviceNodeStr); >+ } else { >+ DeviceNode = FromText (ParamStr); >+ free (ParamStr); >+ } >+ >+ free (DeviceNodeStr); >+ >+ return DeviceNode; >+} >+ >+/** >+ Convert text to the binary representation of a device path. >+ >+ >+ @param TextDevicePath TextDevicePath points to the text representation >of a device >+ path. Conversion starts with the first character and continues >+ until the first non-device node character. >+ >+ @return A pointer to the allocated device path or NULL if TextDeviceNode >is NULL or >+ there was insufficient memory. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibConvertTextToDevicePath ( >+ CONST CHAR16 *TextDevicePath >+ ) >+{ >+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode; >+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; >+ CHAR16 *DevicePathStr; >+ CHAR16 *Str; >+ CHAR16 *DeviceNodeStr; >+ BOOLEAN IsInstanceEnd; >+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; >+ >+ if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) { >+ return NULL; >+ } >+ >+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool >(END_DEVICE_PATH_LENGTH); >+ ASSERT (DevicePath != NULL); >+ SetDevicePathEndNode (DevicePath); >+ >+ DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath); >+ >+ Str = DevicePathStr; >+ while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != >NULL) { >+ DeviceNode = UefiDevicePathLibConvertTextToDeviceNode >(DeviceNodeStr); >+ >+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode); >+ free (DevicePath); >+ free (DeviceNode); >+ DevicePath = NewDevicePath; >+ >+ if (IsInstanceEnd) { >+ DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool >(END_DEVICE_PATH_LENGTH); >+ ASSERT (DeviceNode != NULL); >+ SetDevicePathEndNode (DeviceNode); >+ DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; >+ >+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode); >+ free (DevicePath); >+ free (DeviceNode); >+ DevicePath = NewDevicePath; >+ } >+ } >+ >+ free (DevicePathStr); >+ return DevicePath; >+} >diff --git a/BaseTools/Source/C/DevicePath/DevicePathFromText.h >b/BaseTools/Source/C/DevicePath/DevicePathFromText.h >new file mode 100644 >index 0000000..4c46921 >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.h >@@ -0,0 +1,72 @@ >+/** @file >+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL as defined in UEFI 2.0. >+ This protocol provides service to convert text to device paths and device >nodes. >+ >+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+ This program and the accompanying materials >+ are licensed and made available under the terms and conditions of the BSD >License >+ which accompanies this distribution. The full text of the license may be >found at >+ http://opensource.org/licenses/bsd-license.php >+ >+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+ >+**/ >+ >+#ifndef __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__ >+#define __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__ >+ >+/// >+/// Device Path From Text protocol >+/// >+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ >+ { \ >+ 0x5c99a21, 0xc70f, 0x4ad2, {0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } >\ >+ } >+ >+/** >+ Convert text to the binary representation of a device node. >+ >+ @param TextDeviceNode TextDeviceNode points to the text >representation of a device >+ node. Conversion starts with the first character and continues >+ until the first non-device node character. >+ >+ @retval a_pointer Pointer to the EFI device node. >+ @retval NULL if TextDeviceNode is NULL or there was insufficient >memory. >+ >+**/ >+typedef >+EFI_DEVICE_PATH_PROTOCOL* >+( *EFI_DEVICE_PATH_FROM_TEXT_NODE)( >+ CONST CHAR16 *TextDeviceNode >+ ); >+ >+ >+/** >+ Convert text to the binary representation of a device node. >+ >+ @param TextDeviceNode TextDevicePath points to the text >representation of a device >+ path. Conversion starts with the first character and continues >+ until the first non-device path character. >+ >+ @retval a_pointer Pointer to the allocated device path. >+ @retval NULL if TextDeviceNode is NULL or there was insufficient >memory. >+ >+**/ >+typedef >+EFI_DEVICE_PATH_PROTOCOL* >+( *EFI_DEVICE_PATH_FROM_TEXT_PATH)( >+ CONST CHAR16 *TextDevicePath >+ ); >+ >+/// >+/// This protocol converts text to device paths and device nodes. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode; >+ EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath; >+} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL; >+ >+extern EFI_GUID gEfiDevicePathFromTextProtocolGuid; >+ >+#endif >diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.c >b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c >new file mode 100644 >index 0000000..07a58ee >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c >@@ -0,0 +1,2352 @@ >+/** @file >+ Device Path services. The thing to remember is device paths are built out of >+ nodes. The device path is terminated by an end node that is length >+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is >sizeof(EFI_DEVICE_PATH_PROTOCOL) >+ all over this file. >+ >+ The only place where multi-instance device paths are supported is in >+ environment varibles. Multi-instance device paths should never be placed >+ on a Handle. >+ >+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+ This program and the accompanying materials >+ are licensed and made available under the terms and conditions of the BSD >License >+ which accompanies this distribution. The full text of the license may be >found at >+ http://opensource.org/licenses/bsd-license.php. >+ >+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+ >+**/ >+ >+#include "UefiDevicePathLib.h" >+#include "DevicePathUtilities.h" >+ >+#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \ >+ do { \ >+ ASSERT (Expression); \ >+ if (!(Expression)) { \ >+ return Status; \ >+ } \ >+ } while (FALSE) >+ >+ >+// >+// Template for an end-of-device path node. >+// >+CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = >{ >+ END_DEVICE_PATH_TYPE, >+ END_ENTIRE_DEVICE_PATH_SUBTYPE, >+ { >+ END_DEVICE_PATH_LENGTH, >+ 0 >+ } >+}; >+ >+/** >+ Determine whether a given device path is valid. >+ If DevicePath is NULL, then ASSERT(). >+ >+ @param DevicePath A pointer to a device path data structure. >+ @param MaxSize The maximum size of the device path data structure. >+ >+ @retval TRUE DevicePath is valid. >+ @retval FALSE The length of any node node in the DevicePath is less >+ than sizeof (EFI_DEVICE_PATH_PROTOCOL). >+ @retval FALSE If MaxSize is not zero, the size of the DevicePath >+ exceeds MaxSize. >+ @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the >node >+ count of the DevicePath exceeds >PcdMaximumDevicePathNodeCount. >+**/ >+BOOLEAN >+IsDevicePathValid ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ UINTN MaxSize >+ ) >+{ >+ UINTN Count; >+ UINTN Size; >+ UINTN NodeLength; >+ >+ ASSERT (DevicePath != NULL); >+ >+ if (MaxSize == 0) { >+ MaxSize = MAX_UINTN; >+ } >+ >+ // >+ // Validate the input size big enough to touch the first node. >+ // >+ if (MaxSize < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { >+ return FALSE; >+ } >+ >+ for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = >NextDevicePathNode (DevicePath)) { >+ NodeLength = DevicePathNodeLength (DevicePath); >+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { >+ return FALSE; >+ } >+ >+ if (NodeLength > MAX_UINTN - Size) { >+ return FALSE; >+ } >+ Size += NodeLength; >+ >+ // >+ // Validate next node before touch it. >+ // >+ if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) { >+ return FALSE; >+ } >+ >+ Count++; >+ if (Count >= MAX_DEVICE_PATH_NODE_COUNT) { >+ return FALSE; >+ } >+ >+ } >+ >+ // >+ // Only return TRUE when the End Device Path node is valid. >+ // >+ return (BOOLEAN) (DevicePathNodeLength (DevicePath) == >END_DEVICE_PATH_LENGTH); >+} >+ >+ >+/** >+ Returns the Type field of a device path node. >+ >+ Returns the Type field of the device path node specified by Node. >+ >+ If Node is NULL, then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ >+ @return The Type field of the device path node specified by Node. >+ >+**/ >+UINT8 >+DevicePathType ( >+ CONST VOID *Node >+ ) >+{ >+ ASSERT (Node != NULL); >+ return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type; >+} >+ >+/** >+ Returns the SubType field of a device path node. >+ >+ Returns the SubType field of the device path node specified by Node. >+ >+ If Node is NULL, then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ >+ @return The SubType field of the device path node specified by Node. >+ >+**/ >+UINT8 >+DevicePathSubType ( >+ CONST VOID *Node >+ ) >+{ >+ ASSERT (Node != NULL); >+ return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType; >+} >+ >+/** >+ Returns the 16-bit Length field of a device path node. >+ >+ Returns the 16-bit Length field of the device path node specified by Node. >+ Node is not required to be aligned on a 16-bit boundary, so it is >recommended >+ that a function such as ReadUnaligned16() be used to extract the contents >of >+ the Length field. >+ >+ If Node is NULL, then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ >+ @return The 16-bit Length field of the device path node specified by Node. >+ >+**/ >+UINTN >+DevicePathNodeLength ( >+ CONST VOID *Node >+ ) >+{ >+ ASSERT (Node != NULL); >+ return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL >*)(Node))->Length[0]); >+} >+ >+/** >+ Returns a pointer to the next node in a device path. >+ >+ Returns a pointer to the device path node that follows the device path >node >+ specified by Node. >+ >+ If Node is NULL, then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ >+ @return a pointer to the device path node that follows the device path >node >+ specified by Node. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+NextDevicePathNode ( >+ CONST VOID *Node >+ ) >+{ >+ ASSERT (Node != NULL); >+ return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + >DevicePathNodeLength(Node)); >+} >+ >+/** >+ Determines if a device path node is an end node of a device path. >+ This includes nodes that are the end of a device path instance and nodes >that >+ are the end of an entire device path. >+ >+ Determines if the device path node specified by Node is an end node of a >device path. >+ This includes nodes that are the end of a device path instance and nodes >that are the >+ end of an entire device path. If Node represents an end node of a device >path, >+ then TRUE is returned. Otherwise, FALSE is returned. >+ >+ If Node is NULL, then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ >+ @retval TRUE The device path node specified by Node is an end node of >a >+ device path. >+ @retval FALSE The device path node specified by Node is not an end >node of >+ a device path. >+ >+**/ >+BOOLEAN >+IsDevicePathEndType ( >+ CONST VOID *Node >+ ) >+{ >+ ASSERT (Node != NULL); >+ return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE); >+} >+ >+/** >+ Determines if a device path node is an end node of an entire device path. >+ >+ Determines if a device path node specified by Node is an end node of an >entire >+ device path. If Node represents the end of an entire device path, then >TRUE is >+ returned. Otherwise, FALSE is returned. >+ >+ If Node is NULL, then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ >+ @retval TRUE The device path node specified by Node is the end of an >entire >+ device path. >+ @retval FALSE The device path node specified by Node is not the end of >an >+ entire device path. >+ >+**/ >+BOOLEAN >+IsDevicePathEnd ( >+ CONST VOID *Node >+ ) >+{ >+ ASSERT (Node != NULL); >+ return (BOOLEAN) (IsDevicePathEndType (Node) && >DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE); >+} >+ >+/** >+ Determines if a device path node is an end node of a device path instance. >+ >+ Determines if a device path node specified by Node is an end node of a >device >+ path instance. If Node represents the end of a device path instance, then >TRUE >+ is returned. Otherwise, FALSE is returned. >+ >+ If Node is NULL, then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ >+ @retval TRUE The device path node specified by Node is the end of a >device >+ path instance. >+ @retval FALSE The device path node specified by Node is not the end of a >+ device path instance. >+ >+**/ >+BOOLEAN >+IsDevicePathEndInstance ( >+ CONST VOID *Node >+ ) >+{ >+ ASSERT (Node != NULL); >+ return (BOOLEAN) (IsDevicePathEndType (Node) && >DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE); >+} >+ >+/** >+ Sets the length, in bytes, of a device path node. >+ >+ Sets the length of the device path node specified by Node to the value >specified >+ by NodeLength. NodeLength is returned. Node is not required to be >aligned on >+ a 16-bit boundary, so it is recommended that a function such as >WriteUnaligned16() >+ be used to set the contents of the Length field. >+ >+ If Node is NULL, then ASSERT(). >+ If NodeLength >= SIZE_64KB, then ASSERT(). >+ If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ @param Length The length, in bytes, of the device path node. >+ >+ @return Length >+ >+**/ >+UINT16 >+SetDevicePathNodeLength ( >+ VOID *Node, >+ UINTN Length >+ ) >+{ >+ ASSERT (Node != NULL); >+ ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < >SIZE_64KB)); >+ return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL >*)(Node))->Length[0], (UINT16)(Length)); >+} >+ >+/** >+ Fills in all the fields of a device path node that is the end of an entire device >path. >+ >+ Fills in all the fields of a device path node specified by Node so Node >represents >+ the end of an entire device path. The Type field of Node is set to >+ END_DEVICE_PATH_TYPE, the SubType field of Node is set to >+ END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set >to >+ END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit >boundary, >+ so it is recommended that a function such as WriteUnaligned16() be used to >set >+ the contents of the Length field. >+ >+ If Node is NULL, then ASSERT(). >+ >+ @param Node A pointer to a device path node data structure. >+ >+**/ >+VOID >+SetDevicePathEndNode ( >+ VOID *Node >+ ) >+{ >+ ASSERT (Node != NULL); >+ memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof >(mUefiDevicePathLibEndDevicePath)); >+} >+ >+/** >+ Returns the size of a device path in bytes. >+ >+ This function returns the size, in bytes, of the device path data structure >+ specified by DevicePath including the end of device path node. >+ If DevicePath is NULL or invalid, then 0 is returned. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval 0 If DevicePath is NULL or invalid. >+ @retval Others The size of a device path in bytes. >+ >+**/ >+UINTN >+UefiDevicePathLibGetDevicePathSize ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ) >+{ >+ CONST EFI_DEVICE_PATH_PROTOCOL *Start; >+ >+ if (DevicePath == NULL) { >+ return 0; >+ } >+ >+ if (!IsDevicePathValid (DevicePath, 0)) { >+ return 0; >+ } >+ >+ // >+ // Search for the end of the device path structure >+ // >+ Start = DevicePath; >+ while (!IsDevicePathEnd (DevicePath)) { >+ DevicePath = NextDevicePathNode (DevicePath); >+ } >+ >+ // >+ // Compute the size and add back in the size of the end device path >structure >+ // >+ return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength >(DevicePath); >+} >+ >+/** >+ Creates a new copy of an existing device path. >+ >+ This function allocates space for a new copy of the device path specified by >DevicePath. >+ If DevicePath is NULL, then NULL is returned. If the memory is successfully >+ allocated, then the contents of DevicePath are copied to the newly >allocated >+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is >returned. >+ The memory for the new device path is allocated from EFI boot services >memory. >+ It is the responsibility of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval NULL DevicePath is NULL or invalid. >+ @retval Others A pointer to the duplicated device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibDuplicateDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ) >+{ >+ UINTN Size; >+ >+ // >+ // Compute the size >+ // >+ Size = GetDevicePathSize (DevicePath); >+ if (Size == 0) { >+ return NULL; >+ } >+ >+ // >+ // Allocate space for duplicate device path >+ // >+ >+ return AllocateCopyPool (Size, DevicePath); >+} >+ >+/** >+ Creates a new device path by appending a second device path to a first >device path. >+ >+ This function creates a new device path by appending a copy of >SecondDevicePath >+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of- >device-path >+ device node from SecondDevicePath is retained. The newly created device >path is >+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of >+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is >ignored, >+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and >+ SecondDevicePath are NULL, then a copy of an end-of-device-path is >returned. >+ >+ If there is not enough memory for the newly allocated buffer, then NULL is >returned. >+ The memory for the new device path is allocated from EFI boot services >memory. >+ It is the responsibility of the caller to free the memory allocated. >+ >+ @param FirstDevicePath A pointer to a device path data structure. >+ @param SecondDevicePath A pointer to a device path data structure. >+ >+ @retval NULL If there is not enough memory for the newly allocated >buffer. >+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid. >+ @retval Others A pointer to the new device path if success. >+ Or a copy an end-of-device-path if both FirstDevicePath and >SecondDevicePath are NULL. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, >+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath >+ ) >+{ >+ UINTN Size; >+ UINTN Size1; >+ UINTN Size2; >+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; >+ EFI_DEVICE_PATH_PROTOCOL *DevicePath2; >+ >+ // >+ // If there's only 1 path, just duplicate it. >+ // >+ if (FirstDevicePath == NULL) { >+ return DuplicateDevicePath ((SecondDevicePath != NULL) ? >SecondDevicePath : &mUefiDevicePathLibEndDevicePath); >+ } >+ >+ if (SecondDevicePath == NULL) { >+ return DuplicateDevicePath (FirstDevicePath); >+ } >+ >+ if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid >(SecondDevicePath, 0)) { >+ return NULL; >+ } >+ >+ // >+ // Allocate space for the combined device path. It only has one end node of >+ // length EFI_DEVICE_PATH_PROTOCOL. >+ // >+ Size1 = GetDevicePathSize (FirstDevicePath); >+ Size2 = GetDevicePathSize (SecondDevicePath); >+ Size = Size1 + Size2 - END_DEVICE_PATH_LENGTH; >+ >+ NewDevicePath = AllocatePool (Size); >+ >+ if (NewDevicePath != NULL) { >+ NewDevicePath = memcpy (NewDevicePath, FirstDevicePath, Size1); >+ // >+ // Over write FirstDevicePath EndNode and do the copy >+ // >+ DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) >NewDevicePath + >+ (Size1 - END_DEVICE_PATH_LENGTH)); >+ memcpy (DevicePath2, SecondDevicePath, Size2); >+ } >+ >+ return NewDevicePath; >+} >+ >+/** >+ Creates a new path by appending the device node to the device path. >+ >+ This function creates a new device path by appending a copy of the device >node >+ specified by DevicePathNode to a copy of the device path specified by >DevicePath >+ in an allocated buffer. The end-of-device-path device node is moved after >the >+ end of the appended device node. >+ If DevicePathNode is NULL then a copy of DevicePath is returned. >+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end- >of-device >+ path device node is returned. >+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of- >device-path >+ device node is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ @param DevicePathNode A pointer to a single device path node. >+ >+ @retval NULL If there is not enough memory for the new device path. >+ @retval Others A pointer to the new device path if success. >+ A copy of DevicePathNode followed by an end-of-device-path >node >+ if both FirstDevicePath and SecondDevicePath are NULL. >+ A copy of an end-of-device-path node if both FirstDevicePath >+ and SecondDevicePath are NULL. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePathNode ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode >+ ) >+{ >+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; >+ EFI_DEVICE_PATH_PROTOCOL *NextNode; >+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; >+ UINTN NodeLength; >+ >+ if (DevicePathNode == NULL) { >+ return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : >&mUefiDevicePathLibEndDevicePath); >+ } >+ // >+ // Build a Node that has a terminator on it >+ // >+ NodeLength = DevicePathNodeLength (DevicePathNode); >+ >+ TempDevicePath = AllocatePool (NodeLength + >END_DEVICE_PATH_LENGTH); >+ if (TempDevicePath == NULL) { >+ return NULL; >+ } >+ TempDevicePath = memcpy (TempDevicePath, DevicePathNode, >NodeLength); >+ // >+ // Add and end device path node to convert Node to device path >+ // >+ NextNode = NextDevicePathNode (TempDevicePath); >+ SetDevicePathEndNode (NextNode); >+ // >+ // Append device paths >+ // >+ NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath); >+ >+ free (TempDevicePath); >+ >+ return NewDevicePath; >+} >+ >+/** >+ Creates a new device path by appending the specified device path instance >to the specified device >+ path. >+ >+ This function creates a new device path by appending a copy of the device >path >+ instance specified by DevicePathInstance to a copy of the device path >specified >+ by DevicePath in a allocated buffer. >+ The end-of-device-path device node is moved after the end of the >appended device >+ path instance and a new end-of-device-path-instance node is inserted >between. >+ If DevicePath is NULL, then a copy if DevicePathInstance is returned. >+ If DevicePathInstance is NULL, then NULL is returned. >+ If DevicePath or DevicePathInstance is invalid, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ @param DevicePathInstance A pointer to a device path instance. >+ >+ @return A pointer to the new device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePathInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance >+ ) >+{ >+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; >+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; >+ UINTN SrcSize; >+ UINTN InstanceSize; >+ >+ if (DevicePath == NULL) { >+ return DuplicateDevicePath (DevicePathInstance); >+ } >+ >+ if (DevicePathInstance == NULL) { >+ return NULL; >+ } >+ >+ if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid >(DevicePathInstance, 0)) { >+ return NULL; >+ } >+ >+ SrcSize = GetDevicePathSize (DevicePath); >+ InstanceSize = GetDevicePathSize (DevicePathInstance); >+ >+ NewDevicePath = AllocatePool (SrcSize + InstanceSize); >+ if (NewDevicePath != NULL) { >+ >+ TempDevicePath = memcpy (NewDevicePath, DevicePath, SrcSize);; >+ >+ while (!IsDevicePathEnd (TempDevicePath)) { >+ TempDevicePath = NextDevicePathNode (TempDevicePath); >+ } >+ >+ TempDevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; >+ TempDevicePath = NextDevicePathNode (TempDevicePath); >+ memcpy (TempDevicePath, DevicePathInstance, InstanceSize); >+ } >+ >+ return NewDevicePath; >+} >+ >+/** >+ Creates a copy of the current device path instance and returns a pointer to >the next device path >+ instance. >+ >+ This function creates a copy of the current device path instance. It also >updates >+ DevicePath to point to the next device path instance in the device path (or >NULL >+ if no more) and updates Size to hold the size of the device path instance >copy. >+ If DevicePath is NULL, then NULL is returned. >+ If DevicePath points to a invalid device path, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ If Size is NULL, then ASSERT(). >+ >+ @param DevicePath On input, this holds the pointer to the current >+ device path instance. On output, this holds >+ the pointer to the next device path instance >+ or NULL if there are no more device path >+ instances in the device path pointer to a >+ device path data structure. >+ @param Size On output, this holds the size of the device >+ path instance, in bytes or zero, if DevicePath >+ is NULL. >+ >+ @return A pointer to the current device path instance. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibGetNextDevicePathInstance ( >+ EFI_DEVICE_PATH_PROTOCOL **DevicePath, >+ UINTN *Size >+ ) >+{ >+ EFI_DEVICE_PATH_PROTOCOL *DevPath; >+ EFI_DEVICE_PATH_PROTOCOL *ReturnValue; >+ UINT8 Temp; >+ >+ ASSERT (Size != NULL); >+ >+ if (DevicePath == NULL || *DevicePath == NULL) { >+ *Size = 0; >+ return NULL; >+ } >+ >+ if (!IsDevicePathValid (*DevicePath, 0)) { >+ return NULL; >+ } >+ >+ // >+ // Find the end of the device path instance >+ // >+ DevPath = *DevicePath; >+ while (!IsDevicePathEndType (DevPath)) { >+ DevPath = NextDevicePathNode (DevPath); >+ } >+ >+ // >+ // Compute the size of the device path instance >+ // >+ *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof >(EFI_DEVICE_PATH_PROTOCOL); >+ >+ // >+ // Make a copy and return the device path instance >+ // >+ Temp = DevPath->SubType; >+ DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; >+ ReturnValue = DuplicateDevicePath (*DevicePath); >+ DevPath->SubType = Temp; >+ >+ // >+ // If DevPath is the end of an entire device path, then another instance >+ // does not follow, so *DevicePath is set to NULL. >+ // >+ if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) >{ >+ *DevicePath = NULL; >+ } else { >+ *DevicePath = NextDevicePathNode (DevPath); >+ } >+ >+ return ReturnValue; >+} >+ >+/** >+ Creates a device node. >+ >+ This function creates a new device node in a newly allocated buffer of size >+ NodeLength and initializes the device path node header with NodeType >and NodeSubType. >+ The new device path node is returned. >+ If NodeLength is smaller than a device path header, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param NodeType The device node type for the new device >node. >+ @param NodeSubType The device node sub-type for the new >device node. >+ @param NodeLength The length of the new device node. >+ >+ @return The new device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibCreateDeviceNode ( >+ UINT8 NodeType, >+ UINT8 NodeSubType, >+ UINT16 NodeLength >+ ) >+{ >+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; >+ >+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { >+ // >+ // NodeLength is less than the size of the header. >+ // >+ return NULL; >+ } >+ >+ DevicePath = AllocateZeroPool (NodeLength); >+ if (DevicePath != NULL) { >+ DevicePath->Type = NodeType; >+ DevicePath->SubType = NodeSubType; >+ SetDevicePathNodeLength (DevicePath, NodeLength); >+ } >+ >+ return DevicePath; >+} >+ >+/** >+ Determines if a device path is single or multi-instance. >+ >+ This function returns TRUE if the device path specified by DevicePath is >+ multi-instance. >+ Otherwise, FALSE is returned. >+ If DevicePath is NULL or invalid, then FALSE is returned. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval TRUE DevicePath is multi-instance. >+ @retval FALSE DevicePath is not multi-instance, or DevicePath >+ is NULL or invalid. >+ >+**/ >+BOOLEAN >+UefiDevicePathLibIsDevicePathMultiInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ) >+{ >+ CONST EFI_DEVICE_PATH_PROTOCOL *Node; >+ >+ if (DevicePath == NULL) { >+ return FALSE; >+ } >+ >+ if (!IsDevicePathValid (DevicePath, 0)) { >+ return FALSE; >+ } >+ >+ Node = DevicePath; >+ while (!IsDevicePathEnd (Node)) { >+ if (IsDevicePathEndInstance (Node)) { >+ return TRUE; >+ } >+ >+ Node = NextDevicePathNode (Node); >+ } >+ >+ return FALSE; >+} >+ >+ >+/** >+ Retrieves the device path protocol from a handle. >+ >+ This function returns the device path protocol from the handle specified by >Handle. >+ If Handle is NULL or Handle does not contain a device path protocol, then >NULL >+ is returned. >+ >+ @param Handle The handle from which to retrieve the device >+ path protocol. >+ >+ @return The device path protocol from the handle specified by Handle. >+ >+**/ >+/* >+EFI_DEVICE_PATH_PROTOCOL * >+DevicePathFromHandle ( >+ EFI_HANDLE Handle >+ ) >+{ >+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; >+ EFI_STATUS Status; >+ >+ Status = gBS->HandleProtocol ( >+ Handle, >+ &gEfiDevicePathProtocolGuid, >+ (VOID *) &DevicePath >+ ); >+ if (EFI_ERROR (Status)) { >+ DevicePath = NULL; >+ } >+ return DevicePath; >+} >+*/ >+/** >+ Allocates a device path for a file and appends it to an existing device path. >+ >+ If Device is a valid device handle that contains a device path protocol, then a >device path for >+ the file specified by FileName is allocated and appended to the device path >associated with the >+ handle Device. The allocated device path is returned. If Device is NULL or >Device is a handle >+ that does not support the device path protocol, then a device path >containing a single device >+ path node for the file specified by FileName is allocated and returned. >+ The memory for the new device path is allocated from EFI boot services >memory. It is the responsibility >+ of the caller to free the memory allocated. >+ >+ If FileName is NULL, then ASSERT(). >+ If FileName is not aligned on a 16-bit boundary, then ASSERT(). >+ >+ @param Device A pointer to a device handle. This parameter >+ is optional and may be NULL. >+ @param FileName A pointer to a Null-terminated Unicode string. >+ >+ @return The allocated device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+FileDevicePath ( >+ EFI_HANDLE Device, OPTIONAL >+ CONST CHAR16 *FileName >+ ) >+{ >+ UINTN Size; >+ FILEPATH_DEVICE_PATH *FilePath; >+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; >+ EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; >+ >+ DevicePath = NULL; >+ >+ Size = StrSize (FileName); >+ FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + >END_DEVICE_PATH_LENGTH); >+ if (FileDevicePath != NULL) { >+ FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath; >+ FilePath->Header.Type = MEDIA_DEVICE_PATH; >+ FilePath->Header.SubType = MEDIA_FILEPATH_DP; >+ memcpy (&FilePath->PathName, FileName, Size); >+ SetDevicePathNodeLength (&FilePath->Header, Size + >SIZE_OF_FILEPATH_DEVICE_PATH); >+ SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header)); >+ >+ //if (Device != NULL) { >+ // DevicePath = DevicePathFromHandle (Device); >+ //} >+ >+ DevicePath = AppendDevicePath (DevicePath, FileDevicePath); >+ free (FileDevicePath); >+ } >+ >+ return DevicePath; >+} >+ >+CHAR16 >+InternalCharToUpper ( >+ CHAR16 Char >+ ) >+{ >+ if (Char >= L'a' && Char <= L'z') { >+ return (CHAR16) (Char - (L'a' - L'A')); >+ } >+ >+ return Char; >+} >+ >+UINTN >+StrnLenS ( >+ CONST CHAR16 *String, >+ UINTN MaxSize >+ ) >+{ >+ UINTN Length; >+ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // If String is a null pointer or MaxSize is 0, then the StrnLenS function >returns zero. >+ // >+ if ((String == NULL) || (MaxSize == 0)) { >+ return 0; >+ } >+ >+ Length = 0; >+ while (String[Length] != 0) { >+ if (Length >= MaxSize - 1) { >+ return MaxSize; >+ } >+ Length++; >+ } >+ return Length; >+} >+ >+ >+VOID * >+InternalAllocatePool ( >+ UINTN AllocationSize >+ ) >+{ >+ VOID * Memory; >+ >+ Memory = malloc(AllocationSize); >+ ASSERT(Memory != NULL); >+ return Memory; >+} >+ >+ >+VOID * >+InternalReallocatePool ( >+ UINTN OldSize, >+ UINTN NewSize, >+ VOID *OldBuffer OPTIONAL >+ ) >+{ >+ VOID *NewBuffer; >+ >+ NewBuffer = AllocateZeroPool (NewSize); >+ if (NewBuffer != NULL && OldBuffer != NULL) { >+ memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); >+ free(OldBuffer); >+ } >+ return NewBuffer; >+} >+ >+VOID * >+ReallocatePool ( >+ UINTN OldSize, >+ UINTN NewSize, >+ VOID *OldBuffer OPTIONAL >+ ) >+{ >+ return InternalReallocatePool (OldSize, NewSize, OldBuffer); >+} >+ >+/** >+ Returns the length of a Null-terminated Unicode string. >+ >+ This function returns the number of Unicode characters in the Null- >terminated >+ Unicode string specified by String. >+ >+ If String is NULL, then ASSERT(). >+ If String is not aligned on a 16-bit boundary, then ASSERT(). >+ If PcdMaximumUnicodeStringLength is not zero, and String contains more >than >+ PcdMaximumUnicodeStringLength Unicode characters, not including the >+ Null-terminator, then ASSERT(). >+ >+ @param String A pointer to a Null-terminated Unicode string. >+ >+ @return The length of String. >+ >+**/ >+UINTN >+StrLen ( >+ CONST CHAR16 *String >+ ) >+{ >+ UINTN Length; >+ >+ ASSERT (String != NULL); >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ for (Length = 0; *String != L'\0'; String++, Length++) { >+ // >+ // If PcdMaximumUnicodeStringLength is not zero, >+ // length should not more than PcdMaximumUnicodeStringLength >+ // >+ } >+ return Length; >+} >+ >+BOOLEAN >+InternalSafeStringIsOverlap ( >+ IN VOID *Base1, >+ IN UINTN Size1, >+ IN VOID *Base2, >+ IN UINTN Size2 >+ ) >+{ >+ if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + >Size2)) || >+ (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + >Size1))) { >+ return TRUE; >+ } >+ return FALSE; >+} >+ >+BOOLEAN >+InternalSafeStringNoStrOverlap ( >+ IN CHAR16 *Str1, >+ IN UINTN Size1, >+ IN CHAR16 *Str2, >+ IN UINTN Size2 >+ ) >+{ >+ return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 >* sizeof(CHAR16)); >+} >+ >+RETURN_STATUS >+StrDecimalToUintnS ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, OPTIONAL >+ UINTN *Data >+ ) >+{ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // 1. Neither String nor Data shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 2. The length of String shall not be greater than RSIZE_MAX. >+ // >+ if (RSIZE_MAX != 0) { >+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= >RSIZE_MAX), RETURN_INVALID_PARAMETER); >+ } >+ >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ >+ // >+ // Ignore the pad spaces (space or tab) >+ // >+ while ((*String == L' ') || (*String == L'\t')) { >+ String++; >+ } >+ >+ // >+ // Ignore leading Zeros after the spaces >+ // >+ while (*String == L'0') { >+ String++; >+ } >+ >+ *Data = 0; >+ >+ while (InternalIsDecimalDigitCharacter (*String)) { >+ // >+ // If the number represented by String overflows according to the range >+ // defined by UINTN, then MAX_UINTN is stored in *Data and >+ // RETURN_UNSUPPORTED is returned. >+ // >+ if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) { >+ *Data = MAX_UINTN; >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ return RETURN_UNSUPPORTED; >+ } >+ >+ *Data = *Data * 10 + (*String - L'0'); >+ String++; >+ } >+ >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ return RETURN_SUCCESS; >+} >+ >+/** >+ Convert a Null-terminated Unicode decimal string to a value of type UINT64. >+ >+ This function outputs a value of type UINT64 by interpreting the contents of >+ the Unicode string specified by String as a decimal number. The format of >the >+ input Unicode string String is: >+ >+ [spaces] [decimal digits]. >+ >+ The valid decimal digit character is in the range [0-9]. The function will >+ ignore the pad space, which includes spaces or tab characters, before >+ [decimal digits]. The running zero in the beginning of [decimal digits] will >+ be ignored. Then, the function stops at the first character that is a not a >+ valid decimal character or a Null-terminator, whichever one comes first. >+ >+ If String is NULL, then ASSERT(). >+ If Data is NULL, then ASSERT(). >+ If String is not aligned in a 16-bit boundary, then ASSERT(). >+ If PcdMaximumUnicodeStringLength is not zero, and String contains more >than >+ PcdMaximumUnicodeStringLength Unicode characters, not including the >+ Null-terminator, then ASSERT(). >+ >+ If String has no valid decimal digits in the above format, then 0 is stored >+ at the location pointed to by Data. >+ If the number represented by String exceeds the range defined by UINT64, >then >+ MAX_UINT64 is stored at the location pointed to by Data. >+ >+ If EndPointer is not NULL, a pointer to the character that stopped the scan >+ is stored at the location pointed to by EndPointer. If String has no valid >+ decimal digits right after the optional pad spaces, the value of String is >+ stored at the location pointed to by EndPointer. >+ >+ @param String Pointer to a Null-terminated Unicode string. >+ @param EndPointer Pointer to character that stops scan. >+ @param Data Pointer to the converted value. >+ >+ @retval RETURN_SUCCESS Value is translated from String. >+ @retval RETURN_INVALID_PARAMETER If String is NULL. >+ If Data is NULL. >+ If PcdMaximumUnicodeStringLength is not >+ zero, and String contains more than >+ PcdMaximumUnicodeStringLength Unicode >+ characters, not including the >+ Null-terminator. >+ @retval RETURN_UNSUPPORTED If the number represented by String >exceeds >+ the range defined by UINT64. >+ >+**/ >+RETURN_STATUS >+StrDecimalToUint64S ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, OPTIONAL >+ UINT64 *Data >+ ) >+{ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // 1. Neither String nor Data shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 2. The length of String shall not be greater than RSIZE_MAX. >+ // >+ if (RSIZE_MAX != 0) { >+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= >RSIZE_MAX), RETURN_INVALID_PARAMETER); >+ } >+ >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ >+ // >+ // Ignore the pad spaces (space or tab) >+ // >+ while ((*String == L' ') || (*String == L'\t')) { >+ String++; >+ } >+ >+ // >+ // Ignore leading Zeros after the spaces >+ // >+ while (*String == L'0') { >+ String++; >+ } >+ >+ *Data = 0; >+ >+ while (InternalIsDecimalDigitCharacter (*String)) { >+ // >+ // If the number represented by String overflows according to the range >+ // defined by UINT64, then MAX_UINT64 is stored in *Data and >+ // RETURN_UNSUPPORTED is returned. >+ // >+ if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) { >+ *Data = MAX_UINT64; >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ return RETURN_UNSUPPORTED; >+ } >+ >+ *Data = (*Data) * 10 + (*String - L'0'); >+ String++; >+ } >+ >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ return RETURN_SUCCESS; >+} >+ >+/** >+ Convert a Null-terminated Unicode hexadecimal string to a value of type >+ UINTN. >+ >+ This function outputs a value of type UINTN by interpreting the contents of >+ the Unicode string specified by String as a hexadecimal number. The format >of >+ the input Unicode string String is: >+ >+ [spaces][zeros][x][hexadecimal digits]. >+ >+ The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. >+ The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. >+ If "x" appears in the input string, it must be prefixed with at least one 0. >+ The function will ignore the pad space, which includes spaces or tab >+ characters, before [zeros], [x] or [hexadecimal digit]. The running zero >+ before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts >+ after [x] or the first valid hexadecimal digit. Then, the function stops at >+ the first character that is a not a valid hexadecimal character or NULL, >+ whichever one comes first. >+ >+ If String is NULL, then ASSERT(). >+ If Data is NULL, then ASSERT(). >+ If String is not aligned in a 16-bit boundary, then ASSERT(). >+ If PcdMaximumUnicodeStringLength is not zero, and String contains more >than >+ PcdMaximumUnicodeStringLength Unicode characters, not including the >+ Null-terminator, then ASSERT(). >+ >+ If String has no valid hexadecimal digits in the above format, then 0 is >+ stored at the location pointed to by Data. >+ If the number represented by String exceeds the range defined by UINTN, >then >+ MAX_UINTN is stored at the location pointed to by Data. >+ >+ If EndPointer is not NULL, a pointer to the character that stopped the scan >+ is stored at the location pointed to by EndPointer. If String has no valid >+ hexadecimal digits right after the optional pad spaces, the value of String >+ is stored at the location pointed to by EndPointer. >+ >+ @param String Pointer to a Null-terminated Unicode string. >+ @param EndPointer Pointer to character that stops scan. >+ @param Data Pointer to the converted value. >+ >+ @retval RETURN_SUCCESS Value is translated from String. >+ @retval RETURN_INVALID_PARAMETER If String is NULL. >+ If Data is NULL. >+ If PcdMaximumUnicodeStringLength is not >+ zero, and String contains more than >+ PcdMaximumUnicodeStringLength Unicode >+ characters, not including the >+ Null-terminator. >+ @retval RETURN_UNSUPPORTED If the number represented by String >exceeds >+ the range defined by UINTN. >+ >+**/ >+RETURN_STATUS >+StrHexToUintnS ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, OPTIONAL >+ UINTN *Data >+ ) >+{ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // 1. Neither String nor Data shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 2. The length of String shall not be greater than RSIZE_MAX. >+ // >+ if (RSIZE_MAX != 0) { >+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= >RSIZE_MAX), RETURN_INVALID_PARAMETER); >+ } >+ >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ >+ // >+ // Ignore the pad spaces (space or tab) >+ // >+ while ((*String == L' ') || (*String == L'\t')) { >+ String++; >+ } >+ >+ // >+ // Ignore leading Zeros after the spaces >+ // >+ while (*String == L'0') { >+ String++; >+ } >+ >+ if (InternalCharToUpper (*String) == L'X') { >+ if (*(String - 1) != L'0') { >+ *Data = 0; >+ return RETURN_SUCCESS; >+ } >+ // >+ // Skip the 'X' >+ // >+ String++; >+ } >+ >+ *Data = 0; >+ >+ while (InternalIsHexaDecimalDigitCharacter (*String)) { >+ // >+ // If the number represented by String overflows according to the range >+ // defined by UINTN, then MAX_UINTN is stored in *Data and >+ // RETURN_UNSUPPORTED is returned. >+ // >+ if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) { >+ *Data = MAX_UINTN; >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ return RETURN_UNSUPPORTED; >+ } >+ >+ *Data = (*Data << 4) + InternalHexCharToUintn (*String); >+ String++; >+ } >+ >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ return RETURN_SUCCESS; >+} >+RETURN_STATUS >+StrHexToUint64S ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, OPTIONAL >+ UINT64 *Data >+ ) >+{ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // 1. Neither String nor Data shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 2. The length of String shall not be greater than RSIZE_MAX. >+ // >+ if (RSIZE_MAX != 0) { >+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= >RSIZE_MAX), RETURN_INVALID_PARAMETER); >+ } >+ >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ >+ // >+ // Ignore the pad spaces (space or tab) >+ // >+ while ((*String == L' ') || (*String == L'\t')) { >+ String++; >+ } >+ >+ // >+ // Ignore leading Zeros after the spaces >+ // >+ while (*String == L'0') { >+ String++; >+ } >+ >+ if (InternalCharToUpper (*String) == L'X') { >+ if (*(String - 1) != L'0') { >+ *Data = 0; >+ return RETURN_SUCCESS; >+ } >+ // >+ // Skip the 'X' >+ // >+ String++; >+ } >+ >+ *Data = 0; >+ >+ while (InternalIsHexaDecimalDigitCharacter (*String)) { >+ // >+ // If the number represented by String overflows according to the range >+ // defined by UINT64, then MAX_UINT64 is stored in *Data and >+ // RETURN_UNSUPPORTED is returned. >+ // >+ if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) { >+ *Data = MAX_UINT64; >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ return RETURN_UNSUPPORTED; >+ } >+ >+ *Data = ((*Data) << 4) + InternalHexCharToUintn (*String); >+ String++; >+ } >+ >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) String; >+ } >+ return RETURN_SUCCESS; >+} >+ >+UINT64 >+StrDecimalToUint64 ( >+ CONST CHAR16 *String >+ ) >+{ >+ UINT64 Result; >+ >+ StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result); >+ return Result; >+} >+ >+ >+UINT64 >+StrHexToUint64 ( >+ CONST CHAR16 *String >+ ) >+{ >+ UINT64 Result; >+ >+ StrHexToUint64S (String, (CHAR16 **) NULL, &Result); >+ return Result; >+} >+ >+UINTN >+StrDecimalToUintn ( >+ CONST CHAR16 *String >+ ) >+{ >+ UINTN Result; >+ >+ StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result); >+ return Result; >+} >+ >+UINTN >+StrHexToUintn ( >+ CONST CHAR16 *String >+ ) >+{ >+ UINTN Result; >+ >+ StrHexToUintnS (String, (CHAR16 **) NULL, &Result); >+ return Result; >+} >+ >+UINTN >+StrSize ( >+ CONST CHAR16 *String >+ ) >+{ >+ return (StrLen (String) + 1) * sizeof (*String); >+} >+ >+ >+UINT64 >+ReadUnaligned64 ( >+ CONST UINT64 *Buffer >+ ) >+{ >+ ASSERT (Buffer != NULL); >+ >+ return *Buffer; >+} >+ >+UINT64 >+WriteUnaligned64 ( >+ UINT64 *Buffer, >+ UINT64 Value >+ ) >+{ >+ ASSERT (Buffer != NULL); >+ >+ return *Buffer = Value; >+} >+ >+ >+EFI_GUID * >+CopyGuid ( >+ EFI_GUID *DestinationGuid, >+ CONST EFI_GUID *SourceGuid >+ ) >+{ >+ WriteUnaligned64 ( >+ (UINT64*)DestinationGuid, >+ ReadUnaligned64 ((CONST UINT64*)SourceGuid) >+ ); >+ WriteUnaligned64 ( >+ (UINT64*)DestinationGuid + 1, >+ ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1) >+ ); >+ return DestinationGuid; >+} >+ >+UINT16 >+SwapBytes16 ( >+ UINT16 Value >+ ) >+{ >+ return (UINT16) ((Value<< 8) | (Value>> 8)); >+} >+ >+ >+UINT32 >+SwapBytes32 ( >+ UINT32 Value >+ ) >+{ >+ UINT32 LowerBytes; >+ UINT32 HigherBytes; >+ >+ LowerBytes = (UINT32) SwapBytes16 ((UINT16) Value); >+ HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16)); >+ return (LowerBytes << 16 | HigherBytes); >+} >+ >+BOOLEAN >+InternalIsDecimalDigitCharacter ( >+ CHAR16 Char >+ ) >+{ >+ return (BOOLEAN) (Char >= L'0' && Char <= L'9'); >+} >+ >+VOID * >+InternalAllocateCopyPool ( >+ UINTN AllocationSize, >+ CONST VOID *Buffer >+ ) >+{ >+ VOID *Memory; >+ >+ ASSERT (Buffer != NULL); >+ ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1)); >+ >+ Memory = malloc (AllocationSize); >+ if (Memory != NULL) { >+ Memory = memcpy (Memory, Buffer, AllocationSize); >+ } >+ return Memory; >+} >+ >+BOOLEAN >+InternalIsHexaDecimalDigitCharacter ( >+ CHAR16 Char >+ ) >+{ >+ >+ return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) || >+ (Char >= L'A' && Char <= L'F') || >+ (Char >= L'a' && Char <= L'f')); >+} >+ >+UINTN >+InternalHexCharToUintn ( >+ CHAR16 Char >+ ) >+{ >+ if (InternalIsDecimalDigitCharacter (Char)) { >+ return Char - L'0'; >+ } >+ >+ return (10 + InternalCharToUpper (Char) - L'A'); >+} >+ >+ >+/** >+ Convert a Null-terminated Unicode hexadecimal string to a byte array. >+ >+ This function outputs a byte array by interpreting the contents of >+ the Unicode string specified by String in hexadecimal format. The format of >+ the input Unicode string String is: >+ >+ [XX]* >+ >+ X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F]. >+ The function decodes every two hexadecimal digit characters as one byte. >The >+ decoding stops after Length of characters and outputs Buffer containing >+ (Length / 2) bytes. >+ >+ If String is not aligned in a 16-bit boundary, then ASSERT(). >+ >+ If String is NULL, then ASSERT(). >+ >+ If Buffer is NULL, then ASSERT(). >+ >+ If Length is not multiple of 2, then ASSERT(). >+ >+ If PcdMaximumUnicodeStringLength is not zero and Length is greater than >+ PcdMaximumUnicodeStringLength, then ASSERT(). >+ >+ If MaxBufferSize is less than (Length / 2), then ASSERT(). >+ >+ @param String Pointer to a Null-terminated Unicode string. >+ @param Length The number of Unicode characters to decode. >+ @param Buffer Pointer to the converted bytes array. >+ @param MaxBufferSize The maximum size of Buffer. >+ >+ @retval RETURN_SUCCESS Buffer is translated from String. >+ @retval RETURN_INVALID_PARAMETER If String is NULL. >+ If Data is NULL. >+ If Length is not multiple of 2. >+ If PcdMaximumUnicodeStringLength is not zero, >+ and Length is greater than >+ PcdMaximumUnicodeStringLength. >+ @retval RETURN_UNSUPPORTED If Length of characters from String >contain >+ a character that is not valid hexadecimal >+ digit characters, or a Null-terminator. >+ @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than >(Length / 2). >+**/ >+RETURN_STATUS >+StrHexToBytes ( >+ CONST CHAR16 *String, >+ UINTN Length, >+ UINT8 *Buffer, >+ UINTN MaxBufferSize >+ ) >+{ >+ UINTN Index; >+ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // 1. None of String or Buffer shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 2. Length shall not be greater than RSIZE_MAX. >+ // >+ if (RSIZE_MAX != 0) { >+ SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), >RETURN_INVALID_PARAMETER); >+ } >+ >+ // >+ // 3. Length shall not be odd. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 4. MaxBufferSize shall equal to or greater than Length / 2. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), >RETURN_BUFFER_TOO_SMALL); >+ >+ // >+ // 5. String shall not contains invalid hexadecimal digits. >+ // >+ for (Index = 0; Index < Length; Index++) { >+ if (!InternalIsHexaDecimalDigitCharacter (String[Index])) { >+ break; >+ } >+ } >+ if (Index != Length) { >+ return RETURN_UNSUPPORTED; >+ } >+ >+ // >+ // Convert the hex string to bytes. >+ // >+ for(Index = 0; Index < Length; Index++) { >+ >+ // >+ // For even characters, write the upper nibble for each buffer byte, >+ // and for even characters, the lower nibble. >+ // >+ if ((Index & BIT0) == 0) { >+ Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4; >+ } else { >+ Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]); >+ } >+ } >+ return RETURN_SUCCESS; >+} >+ >+/** >+ Convert a Null-terminated Unicode GUID string to a value of type >+ EFI_GUID. >+ >+ This function outputs a GUID value by interpreting the contents of >+ the Unicode string specified by String. The format of the input >+ Unicode string String consists of 36 characters, as follows: >+ >+ aabbccdd-eeff-gghh-iijj-kkllmmnnoopp >+ >+ The pairs aa - pp are two characters in the range [0-9], [a-f] and >+ [A-F], with each pair representing a single byte hexadecimal value. >+ >+ The mapping between String and the EFI_GUID structure is as follows: >+ aa Data1[24:31] >+ bb Data1[16:23] >+ cc Data1[8:15] >+ dd Data1[0:7] >+ ee Data2[8:15] >+ ff Data2[0:7] >+ gg Data3[8:15] >+ hh Data3[0:7] >+ ii Data4[0:7] >+ jj Data4[8:15] >+ kk Data4[16:23] >+ ll Data4[24:31] >+ mm Data4[32:39] >+ nn Data4[40:47] >+ oo Data4[48:55] >+ pp Data4[56:63] >+ >+ If String is NULL, then ASSERT(). >+ If Guid is NULL, then ASSERT(). >+ If String is not aligned in a 16-bit boundary, then ASSERT(). >+ >+ @param String Pointer to a Null-terminated Unicode string. >+ @param Guid Pointer to the converted GUID. >+ >+ @retval RETURN_SUCCESS Guid is translated from String. >+ @retval RETURN_INVALID_PARAMETER If String is NULL. >+ If Data is NULL. >+ @retval RETURN_UNSUPPORTED If String is not as the above format. >+ >+**/ >+RETURN_STATUS >+StrToGuid ( >+ CONST CHAR16 *String, >+ EFI_GUID *Guid >+ ) >+{ >+ RETURN_STATUS Status; >+ EFI_GUID LocalGuid; >+ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // 1. None of String or Guid shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // Get aabbccdd in big-endian. >+ // >+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) >&LocalGuid.Data1, sizeof (LocalGuid.Data1)); >+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') { >+ return RETURN_UNSUPPORTED; >+ } >+ // >+ // Convert big-endian to little-endian. >+ // >+ LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1); >+ String += 2 * sizeof (LocalGuid.Data1) + 1; >+ >+ // >+ // Get eeff in big-endian. >+ // >+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) >&LocalGuid.Data2, sizeof (LocalGuid.Data2)); >+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') { >+ return RETURN_UNSUPPORTED; >+ } >+ // >+ // Convert big-endian to little-endian. >+ // >+ LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2); >+ String += 2 * sizeof (LocalGuid.Data2) + 1; >+ >+ // >+ // Get gghh in big-endian. >+ // >+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) >&LocalGuid.Data3, sizeof (LocalGuid.Data3)); >+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') { >+ return RETURN_UNSUPPORTED; >+ } >+ // >+ // Convert big-endian to little-endian. >+ // >+ LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3); >+ String += 2 * sizeof (LocalGuid.Data3) + 1; >+ >+ // >+ // Get iijj. >+ // >+ Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2); >+ if (RETURN_ERROR (Status) || String[2 * 2] != L'-') { >+ return RETURN_UNSUPPORTED; >+ } >+ String += 2 * 2 + 1; >+ >+ // >+ // Get kkllmmnnoopp. >+ // >+ Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6); >+ if (RETURN_ERROR (Status)) { >+ return RETURN_UNSUPPORTED; >+ } >+ >+ CopyGuid (Guid, &LocalGuid); >+ return RETURN_SUCCESS; >+} >+ >+/** >+ Compares up to a specified length the contents of two Null-terminated >Unicode strings, >+ and returns the difference between the first mismatched Unicode >characters. >+ >+ This function compares the Null-terminated Unicode string FirstString to the >+ Null-terminated Unicode string SecondString. At most, Length Unicode >+ characters will be compared. If Length is 0, then 0 is returned. If >+ FirstString is identical to SecondString, then 0 is returned. Otherwise, the >+ value returned is the first mismatched Unicode character in SecondString >+ subtracted from the first mismatched Unicode character in FirstString. >+ >+ If Length > 0 and FirstString is NULL, then ASSERT(). >+ If Length > 0 and FirstString is not aligned on a 16-bit boundary, then >ASSERT(). >+ If Length > 0 and SecondString is NULL, then ASSERT(). >+ If Length > 0 and SecondString is not aligned on a 16-bit boundary, then >ASSERT(). >+ If PcdMaximumUnicodeStringLength is not zero, and Length is greater than >+ PcdMaximumUnicodeStringLength, then ASSERT(). >+ If PcdMaximumUnicodeStringLength is not zero, and FirstString contains >more than >+ PcdMaximumUnicodeStringLength Unicode characters, not including the >Null-terminator, >+ then ASSERT(). >+ If PcdMaximumUnicodeStringLength is not zero, and SecondString contains >more than >+ PcdMaximumUnicodeStringLength Unicode characters, not including the >Null-terminator, >+ then ASSERT(). >+ >+ @param FirstString A pointer to a Null-terminated Unicode string. >+ @param SecondString A pointer to a Null-terminated Unicode string. >+ @param Length The maximum number of Unicode characters to >compare. >+ >+ @retval 0 FirstString is identical to SecondString. >+ @return others FirstString is not identical to SecondString. >+ >+**/ >+INTN >+StrnCmp ( >+ CONST CHAR16 *FirstString, >+ CONST CHAR16 *SecondString, >+ UINTN Length >+ ) >+{ >+ if (Length == 0) { >+ return 0; >+ } >+ >+ // >+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength. >+ // Length tests are performed inside StrLen(). >+ // >+ ASSERT (StrSize (FirstString) != 0); >+ ASSERT (StrSize (SecondString) != 0); >+ >+ while ((*FirstString != L'\0') && >+ (*SecondString != L'\0') && >+ (*FirstString == *SecondString) && >+ (Length > 1)) { >+ FirstString++; >+ SecondString++; >+ Length--; >+ } >+ >+ return *FirstString - *SecondString; >+} >+ >+VOID * >+AllocateCopyPool ( >+ UINTN AllocationSize, >+ CONST VOID *Buffer >+ ) >+{ >+ return InternalAllocateCopyPool (AllocationSize, Buffer); >+} >+ >+INTN >+StrCmp ( >+ CONST CHAR16 *FirstString, >+ CONST CHAR16 *SecondString >+ ) >+{ >+ // >+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength >+ // >+ ASSERT (StrSize (FirstString) != 0); >+ ASSERT (StrSize (SecondString) != 0); >+ >+ while ((*FirstString != L'\0') && (*FirstString == *SecondString)) { >+ FirstString++; >+ SecondString++; >+ } >+ return *FirstString - *SecondString; >+} >+ >+UINT64 >+SwapBytes64 ( >+ UINT64 Value >+ ) >+{ >+ return InternalMathSwapBytes64 (Value); >+} >+ >+UINT64 >+InternalMathSwapBytes64 ( >+ UINT64 Operand >+ ) >+{ >+ UINT64 LowerBytes; >+ UINT64 HigherBytes; >+ >+ LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand); >+ HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32)); >+ >+ return (LowerBytes << 32 | HigherBytes); >+} >+ >+RETURN_STATUS >+StrToIpv4Address ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, >+ EFI_IPv4_ADDRESS *Address, >+ UINT8 *PrefixLength >+ ) >+{ >+ RETURN_STATUS Status; >+ UINTN AddressIndex; >+ UINTN Uintn; >+ EFI_IPv4_ADDRESS LocalAddress; >+ UINT8 LocalPrefixLength; >+ CHAR16 *Pointer; >+ >+ LocalPrefixLength = MAX_UINT8; >+ LocalAddress.Addr[0] = 0; >+ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // 1. None of String or Guid shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), >RETURN_INVALID_PARAMETER); >+ >+ for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < >ARRAY_SIZE (Address->Addr) + 1;) { >+ if (!InternalIsDecimalDigitCharacter (*Pointer)) { >+ // >+ // D or P contains invalid characters. >+ // >+ break; >+ } >+ >+ // >+ // Get D or P. >+ // >+ Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer, >&Uintn); >+ if (RETURN_ERROR (Status)) { >+ return RETURN_UNSUPPORTED; >+ } >+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) { >+ // >+ // It's P. >+ // >+ if (Uintn > 32) { >+ return RETURN_UNSUPPORTED; >+ } >+ LocalPrefixLength = (UINT8) Uintn; >+ } else { >+ // >+ // It's D. >+ // >+ if (Uintn > MAX_UINT8) { >+ return RETURN_UNSUPPORTED; >+ } >+ LocalAddress.Addr[AddressIndex] = (UINT8) Uintn; >+ AddressIndex++; >+ } >+ >+ // >+ // Check the '.' or '/', depending on the AddressIndex. >+ // >+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) { >+ if (*Pointer == L'/') { >+ // >+ // '/P' is in the String. >+ // Skip "/" and get P in next loop. >+ // >+ Pointer++; >+ } else { >+ // >+ // '/P' is not in the String. >+ // >+ break; >+ } >+ } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) { >+ if (*Pointer == L'.') { >+ // >+ // D should be followed by '.' >+ // >+ Pointer++; >+ } else { >+ return RETURN_UNSUPPORTED; >+ } >+ } >+ } >+ >+ if (AddressIndex < ARRAY_SIZE (Address->Addr)) { >+ return RETURN_UNSUPPORTED; >+ } >+ >+ memcpy (Address, &LocalAddress, sizeof (*Address)); >+ if (PrefixLength != NULL) { >+ *PrefixLength = LocalPrefixLength; >+ } >+ if (EndPointer != NULL) { >+ *EndPointer = Pointer; >+ } >+ >+ return RETURN_SUCCESS; >+} >+ >+RETURN_STATUS >+StrToIpv6Address ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, >+ EFI_IPv6_ADDRESS *Address, >+ UINT8 *PrefixLength >+ ) >+{ >+ RETURN_STATUS Status; >+ UINTN AddressIndex; >+ UINTN Uintn; >+ EFI_IPv6_ADDRESS LocalAddress; >+ UINT8 LocalPrefixLength; >+ CONST CHAR16 *Pointer; >+ CHAR16 *End; >+ UINTN CompressStart; >+ BOOLEAN ExpectPrefix; >+ >+ LocalPrefixLength = MAX_UINT8; >+ CompressStart = ARRAY_SIZE (Address->Addr); >+ ExpectPrefix = FALSE; >+ >+ ASSERT (((UINTN) String & BIT0) == 0); >+ >+ // >+ // 1. None of String or Guid shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), >RETURN_INVALID_PARAMETER); >+ >+ for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE >(Address->Addr) + 1;) { >+ if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) { >+ if (*Pointer != L':') { >+ // >+ // ":" or "/" should be followed by digit characters. >+ // >+ return RETURN_UNSUPPORTED; >+ } >+ >+ // >+ // Meet second ":" after previous ":" or "/" >+ // or meet first ":" in the beginning of String. >+ // >+ if (ExpectPrefix) { >+ // >+ // ":" shall not be after "/" >+ // >+ return RETURN_UNSUPPORTED; >+ } >+ >+ if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == >ARRAY_SIZE (Address->Addr)) { >+ // >+ // "::" can only appear once. >+ // "::" can only appear when address is not full length. >+ // >+ return RETURN_UNSUPPORTED; >+ } else { >+ // >+ // Remember the start of zero compressing. >+ // >+ CompressStart = AddressIndex; >+ Pointer++; >+ >+ if (CompressStart == 0) { >+ if (*Pointer != L':') { >+ // >+ // Single ":" shall not be in the beginning of String. >+ // >+ return RETURN_UNSUPPORTED; >+ } >+ Pointer++; >+ } >+ } >+ } >+ >+ if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) { >+ if (*Pointer == L'/') { >+ // >+ // Might be optional "/P" after "::". >+ // >+ if (CompressStart != AddressIndex) { >+ return RETURN_UNSUPPORTED; >+ } >+ } else { >+ break; >+ } >+ } else { >+ if (!ExpectPrefix) { >+ // >+ // Get X. >+ // >+ Status = StrHexToUintnS (Pointer, &End, &Uintn); >+ if (RETURN_ERROR (Status) || End - Pointer > 4) { >+ // >+ // Number of hexadecimal digit characters is no more than 4. >+ // >+ return RETURN_UNSUPPORTED; >+ } >+ Pointer = End; >+ // >+ // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit >characters is no more than 4. >+ // >+ ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr)); >+ LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8); >+ LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn; >+ AddressIndex += 2; >+ } else { >+ // >+ // Get P, then exit the loop. >+ // >+ Status = StrDecimalToUintnS (Pointer, &End, &Uintn); >+ if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) { >+ // >+ // Prefix length should not exceed 128. >+ // >+ return RETURN_UNSUPPORTED; >+ } >+ LocalPrefixLength = (UINT8) Uintn; >+ Pointer = End; >+ break; >+ } >+ } >+ >+ // >+ // Skip ':' or "/" >+ // >+ if (*Pointer == L'/') { >+ ExpectPrefix = TRUE; >+ } else if (*Pointer == L':') { >+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) { >+ // >+ // Meet additional ":" after all 8 16-bit address >+ // >+ break; >+ } >+ } else { >+ // >+ // Meet other character that is not "/" or ":" after all 8 16-bit address >+ // >+ break; >+ } >+ Pointer++; >+ } >+ >+ if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != >ARRAY_SIZE (Address->Addr)) || >+ (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == >ARRAY_SIZE (Address->Addr)) >+ ) { >+ // >+ // Full length of address shall not have compressing zeros. >+ // Non-full length of address shall have compressing zeros. >+ // >+ return RETURN_UNSUPPORTED; >+ } >+ memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart); >+ memset (&Address->Addr[CompressStart], 0, ARRAY_SIZE (Address->Addr) >- AddressIndex); >+ if (AddressIndex > CompressStart) { >+ memcpy ( >+ &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - >AddressIndex], >+ &LocalAddress.Addr[CompressStart], >+ AddressIndex - CompressStart >+ ); >+ } >+ >+ if (PrefixLength != NULL) { >+ *PrefixLength = LocalPrefixLength; >+ } >+ if (EndPointer != NULL) { >+ *EndPointer = (CHAR16 *) Pointer; >+ } >+ >+ return RETURN_SUCCESS; >+} >+ >+ >+RETURN_STATUS >+UnicodeStrToAsciiStrS ( >+ CONST CHAR16 *Source, >+ CHAR8 *Destination, >+ UINTN DestMax >+ ) >+{ >+ UINTN SourceLen; >+ >+ ASSERT (((UINTN) Source & BIT0) == 0); >+ >+ // >+ // 1. Neither Destination nor Source shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX. >+ // >+ if (ASCII_RSIZE_MAX != 0) { >+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), >RETURN_INVALID_PARAMETER); >+ } >+ if (RSIZE_MAX != 0) { >+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), >RETURN_INVALID_PARAMETER); >+ } >+ >+ // >+ // 3. DestMax shall not equal zero. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 4. DestMax shall be greater than StrnLenS (Source, DestMax). >+ // >+ SourceLen = StrnLenS (Source, DestMax); >+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), >RETURN_BUFFER_TOO_SMALL); >+ >+ // >+ // 5. Copying shall not take place between objects that overlap. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap >(Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), >RETURN_ACCESS_DENIED); >+ >+ // >+ // convert string >+ // >+ while (*Source != '\0') { >+ // >+ // If any Unicode characters in Source contain >+ // non-zero value in the upper 8 bits, then ASSERT(). >+ // >+ ASSERT (*Source < 0x100); >+ *(Destination++) = (CHAR8) *(Source++); >+ } >+ *Destination = '\0'; >+ >+ return RETURN_SUCCESS; >+} >+ >+RETURN_STATUS >+StrCpyS ( >+ CHAR16 *Destination, >+ UINTN DestMax, >+ CONST CHAR16 *Source >+ ) >+{ >+ UINTN SourceLen; >+ >+ ASSERT (((UINTN) Destination & BIT0) == 0); >+ ASSERT (((UINTN) Source & BIT0) == 0); >+ >+ // >+ // 1. Neither Destination nor Source shall be a null pointer. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), >RETURN_INVALID_PARAMETER); >+ SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 2. DestMax shall not be greater than RSIZE_MAX. >+ // >+ if (RSIZE_MAX != 0) { >+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), >RETURN_INVALID_PARAMETER); >+ } >+ >+ // >+ // 3. DestMax shall not equal zero. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), >RETURN_INVALID_PARAMETER); >+ >+ // >+ // 4. DestMax shall be greater than StrnLenS(Source, DestMax). >+ // >+ SourceLen = StrnLenS (Source, DestMax); >+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), >RETURN_BUFFER_TOO_SMALL); >+ >+ // >+ // 5. Copying shall not take place between objects that overlap. >+ // >+ SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap >(Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), >RETURN_ACCESS_DENIED); >+ >+ // >+ // The StrCpyS function copies the string pointed to by Source (including the >terminating >+ // null character) into the array pointed to by Destination. >+ // >+ while (*Source != 0) { >+ *(Destination++) = *(Source++); >+ } >+ *Destination = 0; >+ >+ return RETURN_SUCCESS; >+} >+ >+VOID * >+AllocateZeroPool ( >+ UINTN AllocationSize >+ ) >+{ >+ VOID * Memory; >+ Memory = malloc(AllocationSize); >+ ASSERT (Memory != NULL); >+ if (Memory == NULL) { >+ fprintf(stderr, "Not memory for malloc\n"); >+ } >+ memset(Memory, 0, AllocationSize); >+ return Memory; >+} >+ >+VOID * >+AllocatePool ( >+ UINTN AllocationSize >+ ) >+{ >+ return InternalAllocatePool (AllocationSize); >+} >+ >+UINT16 >+WriteUnaligned16 ( >+ UINT16 *Buffer, >+ UINT16 Value >+ ) >+{ >+ ASSERT (Buffer != NULL); >+ >+ return *Buffer = Value; >+} >+ >+UINT16 >+ReadUnaligned16 ( >+ CONST UINT16 *Buffer >+ ) >+{ >+ ASSERT (Buffer != NULL); >+ >+ return *Buffer; >+} >diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.h >b/BaseTools/Source/C/DevicePath/DevicePathUtilities.h >new file mode 100644 >index 0000000..418615f >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.h >@@ -0,0 +1,555 @@ >+/** @file >+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0. >+ Use to create and manipulate device paths and device nodes. >+ >+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+ This program and the accompanying materials >+ are licensed and made available under the terms and conditions of the BSD >License >+ which accompanies this distribution. The full text of the license may be >found at >+ http://opensource.org/licenses/bsd-license.php >+ >+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+ >+**/ >+ >+#ifndef __DEVICE_PATH_UTILITIES_H__ >+#define __DEVICE_PATH_UTILITIES_H__ >+ >+/// >+/// Device Path Utilities protocol >+/// >+#define EFI_DEVICE_PATH_UTILITIES_GUID \ >+ { \ >+ 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, >0xa4 } \ >+ } >+ >+/** >+ Returns the size of the device path, in bytes. >+ >+ @param DevicePath Points to the start of the EFI device path. >+ >+ @return Size Size of the specified device path, in bytes, including the end- >of-path tag. >+ @retval 0 DevicePath is NULL >+ >+**/ >+typedef >+UINTN >+( *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+ >+/** >+ Create a duplicate of the specified path. >+ >+ @param DevicePath Points to the source EFI device path. >+ >+ @retval Pointer A pointer to the duplicate device path. >+ @retval NULL insufficient memory or DevicePath is NULL >+ >+**/ >+typedef >+EFI_DEVICE_PATH_PROTOCOL* >+( *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+/** >+ Create a new path by appending the second device path to the first. >+ If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned. >+ If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned. >+ If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is >returned. >+ >+ @param Src1 Points to the first device path. >+ @param Src2 Points to the second device path. >+ >+ @retval Pointer A pointer to the newly created device path. >+ @retval NULL Memory could not be allocated >+ >+**/ >+typedef >+EFI_DEVICE_PATH_PROTOCOL* >+( *EFI_DEVICE_PATH_UTILS_APPEND_PATH)( >+ CONST EFI_DEVICE_PATH_PROTOCOL *Src1, >+ CONST EFI_DEVICE_PATH_PROTOCOL *Src2 >+ ); >+ >+/** >+ Creates a new path by appending the device node to the device path. >+ If DeviceNode is NULL then a copy of DevicePath is returned. >+ If DevicePath is NULL then a copy of DeviceNode, followed by an end-of- >device path device node is returned. >+ If both DeviceNode and DevicePath are NULL then a copy of an end-of- >device-path device node is returned. >+ >+ @param DevicePath Points to the device path. >+ @param DeviceNode Points to the device node. >+ >+ @retval Pointer A pointer to the allocated device node. >+ @retval NULL There was insufficient memory. >+ >+**/ >+typedef >+EFI_DEVICE_PATH_PROTOCOL* >+( *EFI_DEVICE_PATH_UTILS_APPEND_NODE)( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode >+ ); >+ >+/** >+ Creates a new path by appending the specified device path instance to the >specified device path. >+ >+ @param DevicePath Points to the device path. If NULL, then ignored. >+ @param DevicePathInstance Points to the device path instance. >+ >+ @retval Pointer A pointer to the newly created device path >+ @retval NULL Memory could not be allocated or DevicePathInstance >is NULL. >+ >+**/ >+typedef >+EFI_DEVICE_PATH_PROTOCOL* >+( *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance >+ ); >+ >+/** >+ Creates a copy of the current device path instance and returns a pointer to >the next device path >+ instance. >+ >+ @param DevicePathInstance On input, this holds the pointer to the >current device path >+ instance. On output, this holds the pointer to the next >+ device path instance or NULL if there are no more device >+ path instances in the device path. >+ @param DevicePathInstanceSize On output, this holds the size of the >device path instance, >+ in bytes or zero, if DevicePathInstance is NULL. >+ If NULL, then the instance size is not output. >+ >+ @retval Pointer A pointer to the copy of the current device path >instance. >+ @retval NULL DevicePathInstace was NULL on entry or there was >insufficient memory. >+ >+**/ >+typedef >+EFI_DEVICE_PATH_PROTOCOL* >+( *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)( >+ EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance, >+ UINTN *DevicePathInstanceSize >+ ); >+ >+/** >+ Creates a device node >+ >+ @param NodeType NodeType is the device node type >(EFI_DEVICE_PATH.Type) for >+ the new device node. >+ @param NodeSubType NodeSubType is the device node sub-type >+ EFI_DEVICE_PATH.SubType) for the new device node. >+ @param NodeLength NodeLength is the length of the device node >+ (EFI_DEVICE_PATH.Length) for the new device node. >+ >+ @retval Pointer A pointer to the newly created device node. >+ @retval NULL NodeLength is less than >+ the size of the header or there was insufficient memory. >+ >+**/ >+typedef >+EFI_DEVICE_PATH_PROTOCOL* >+( *EFI_DEVICE_PATH_UTILS_CREATE_NODE)( >+ UINT8 NodeType, >+ UINT8 NodeSubType, >+ UINT16 NodeLength >+); >+ >+/** >+ Returns whether a device path is multi-instance. >+ >+ @param DevicePath Points to the device path. If NULL, then ignored. >+ >+ @retval TRUE The device path has more than one instance >+ @retval FALSE The device path is empty or contains only a single instance. >+ >+**/ >+typedef >+BOOLEAN >+( *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+/// >+/// This protocol is used to creates and manipulates device paths and device >nodes. >+/// >+typedef struct { >+ EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize; >+ EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath; >+ EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath; >+ EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode; >+ EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE >AppendDevicePathInstance; >+ EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE >GetNextDevicePathInstance; >+ EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE >IsDevicePathMultiInstance; >+ EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode; >+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL; >+ >+extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid; >+ >+UINTN >+StrLen ( >+ CONST CHAR16 *String >+ ); >+ >+VOID * >+AllocateCopyPool ( >+ UINTN AllocationSize, >+ CONST VOID *Buffer >+ ); >+ >+INTN >+StrnCmp ( >+ CONST CHAR16 *FirstString, >+ CONST CHAR16 *SecondString, >+ UINTN Length >+ ); >+ >+RETURN_STATUS >+StrToGuid ( >+ CONST CHAR16 *String, >+ EFI_GUID *Guid >+ ); >+ >+RETURN_STATUS >+StrHexToBytes ( >+ CONST CHAR16 *String, >+ UINTN Length, >+ UINT8 *Buffer, >+ UINTN MaxBufferSize >+ ); >+ >+UINTN >+InternalHexCharToUintn ( >+ CHAR16 Char >+ ); >+ >+VOID * >+InternalAllocateCopyPool ( >+ UINTN AllocationSize, >+ CONST VOID *Buffer >+ ); >+ >+BOOLEAN >+InternalIsDecimalDigitCharacter ( >+ CHAR16 Char >+ ); >+ >+UINT32 >+SwapBytes32 ( >+ UINT32 Value >+ ); >+ >+UINT16 >+SwapBytes16 ( >+ UINT16 Value >+ ); >+ >+EFI_GUID * >+CopyGuid ( >+ EFI_GUID *DestinationGuid, >+ CONST EFI_GUID *SourceGuid >+ ); >+ >+UINT64 >+WriteUnaligned64 ( >+ UINT64 *Buffer, >+ UINT64 Value >+ ); >+ >+UINT64 >+ReadUnaligned64 ( >+ CONST UINT64 *Buffer >+ ); >+ >+UINTN >+StrSize ( >+ CONST CHAR16 *String >+ ); >+ >+UINTN >+StrHexToUintn ( >+ CONST CHAR16 *String >+ ); >+ >+UINTN >+StrDecimalToUintn ( >+ CONST CHAR16 *String >+ ); >+ >+UINT64 >+StrHexToUint64 ( >+ CONST CHAR16 *String >+ ); >+ >+UINT64 >+StrDecimalToUint64 ( >+ CONST CHAR16 *String >+ ); >+ >+RETURN_STATUS >+StrHexToUint64S ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, >+ UINT64 *Data >+ ); >+ >+RETURN_STATUS >+StrHexToUintnS ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, OPTIONAL >+ UINTN *Data >+ ); >+ >+RETURN_STATUS >+StrDecimalToUint64S ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, OPTIONAL >+ UINT64 *Data >+ ); >+ >+RETURN_STATUS >+StrDecimalToUintnS ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, OPTIONAL >+ UINTN *Data >+ ); >+ >+VOID * >+ReallocatePool ( >+ UINTN OldSize, >+ UINTN NewSize, >+ VOID *OldBuffer OPTIONAL >+ ); >+ >+VOID * >+InternalReallocatePool ( >+ UINTN OldSize, >+ UINTN NewSize, >+ VOID *OldBuffer OPTIONAL >+ ); >+ >+VOID * >+InternalAllocateZeroPool ( >+ UINTN AllocationSize >+ ) ; >+ >+VOID * >+InternalAllocatePool ( >+ UINTN AllocationSize >+ ); >+ >+UINTN >+StrnLenS ( >+ CONST CHAR16 *String, >+ UINTN MaxSize >+ ); >+ >+CHAR16 >+InternalCharToUpper ( >+ CHAR16 Char >+ ); >+ >+UINTN >+DevicePathNodeLength ( >+ CONST VOID *Node >+ ); >+ >+UINT16 >+SetDevicePathNodeLength ( >+ VOID *Node, >+ UINTN Length >+ ); >+ >+INTN >+StrCmp ( >+ CONST CHAR16 *FirstString, >+ CONST CHAR16 *SecondString >+ ); >+ >+UINT64 >+SwapBytes64 ( >+ UINT64 Value >+ ); >+ >+UINT64 >+InternalMathSwapBytes64 ( >+ UINT64 Operand >+ ); >+ >+RETURN_STATUS >+StrToIpv4Address ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, >+ EFI_IPv4_ADDRESS *Address, >+ UINT8 *PrefixLength >+ ); >+ >+RETURN_STATUS >+StrToIpv6Address ( >+ CONST CHAR16 *String, >+ CHAR16 **EndPointer, >+ EFI_IPv6_ADDRESS *Address, >+ UINT8 *PrefixLength >+ ); >+ >+RETURN_STATUS >+StrCpyS ( >+ CHAR16 *Destination, >+ UINTN DestMax, >+ CONST CHAR16 *Source >+ ); >+ >+RETURN_STATUS >+UnicodeStrToAsciiStrS ( >+ CONST CHAR16 *Source, >+ CHAR8 *Destination, >+ UINTN DestMax >+ ); >+VOID * >+AllocatePool ( >+ UINTN AllocationSize >+ ); >+ >+VOID >+SetDevicePathEndNode ( >+ VOID *Node >+ ); >+ >+BOOLEAN >+IsDevicePathValid ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ UINTN MaxSize >+ ); >+ >+UINT8 >+DevicePathType ( >+ CONST VOID *Node >+ ); >+ >+UINT8 >+DevicePathSubType ( >+ CONST VOID *Node >+ ); >+ >+UINTN >+DevicePathNodeLength ( >+ CONST VOID *Node >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+NextDevicePathNode ( >+ CONST VOID *Node >+ ); >+ >+BOOLEAN >+IsDevicePathEndType ( >+ CONST VOID *Node >+ ); >+ >+BOOLEAN >+IsDevicePathEnd ( >+ CONST VOID *Node >+ ); >+BOOLEAN >+IsDevicePathEndInstance ( >+ CONST VOID *Node >+ ); >+ >+UINT16 >+SetDevicePathNodeLength ( >+ VOID *Node, >+ UINTN Length >+ ); >+ >+VOID >+SetDevicePathEndNode ( >+ VOID *Node >+ ); >+ >+UINTN >+UefiDevicePathLibGetDevicePathSize ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibDuplicateDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, >+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePathNode ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePathInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibGetNextDevicePathInstance ( >+ EFI_DEVICE_PATH_PROTOCOL **DevicePath, >+ UINTN *Size >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibCreateDeviceNode ( >+ UINT8 NodeType, >+ UINT8 NodeSubType, >+ UINT16 NodeLength >+ ); >+ >+BOOLEAN >+UefiDevicePathLibIsDevicePathMultiInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+UINT16 >+WriteUnaligned16 ( >+ UINT16 *Buffer, >+ UINT16 Value >+ ); >+ >+UINT16 >+ReadUnaligned16 ( >+ CONST UINT16 *Buffer >+ ); >+ >+VOID * >+AllocateZeroPool ( >+ UINTN AllocationSize >+ ); >+ >+BOOLEAN >+InternalIsHexaDecimalDigitCharacter ( >+ CHAR16 Char >+ ); >+ >+BOOLEAN >+InternalSafeStringIsOverlap ( >+ IN VOID *Base1, >+ IN UINTN Size1, >+ IN VOID *Base2, >+ IN UINTN Size2 >+ ); >+ >+BOOLEAN >+InternalSafeStringNoStrOverlap ( >+ IN CHAR16 *Str1, >+ IN UINTN Size1, >+ IN CHAR16 *Str2, >+ IN UINTN Size2 >+ ); >+ >+#endif >diff --git a/BaseTools/Source/C/DevicePath/GNUmakefile >b/BaseTools/Source/C/DevicePath/GNUmakefile >new file mode 100644 >index 0000000..27f6fa1 >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/GNUmakefile >@@ -0,0 +1,30 @@ >+## @file >+# GNU/Linux makefile for 'DevicePath' module build. >+# >+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+# This program and the accompanying materials >+# are licensed and made available under the terms and conditions of the BSD >License >+# which accompanies this distribution. The full text of the license may be >found at >+# http://opensource.org/licenses/bsd-license.php >+# >+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+# >+ARCH ?= IA32 >+MAKEROOT ?= .. >+ >+APPNAME = DevicePath >+ >+OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o >DevicePathUtilities.o >+ >+include $(MAKEROOT)/Makefiles/app.makefile >+ >+LIBS = -lCommon >+ifeq ($(CYGWIN), CYGWIN) >+ LIBS += -L/lib/e2fsprogs -luuid >+endif >+ >+ifeq ($(LINUX), Linux) >+ LIBS += -luuid >+endif >+ >diff --git a/BaseTools/Source/C/DevicePath/Makefile >b/BaseTools/Source/C/DevicePath/Makefile >new file mode 100644 >index 0000000..a069c22 >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/Makefile >@@ -0,0 +1,24 @@ >+## @file >+# Windows makefile for 'DevicePath' module build. >+# >+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+# This program and the accompanying materials >+# are licensed and made available under the terms and conditions of the BSD >License >+# which accompanies this distribution. The full text of the license may be >found at >+# http://opensource.org/licenses/bsd-license.php >+# >+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+# >+!INCLUDE ..\Makefiles\ms.common >+ >+APPNAME = DevicePath >+ >+LIBS = $(LIB_PATH)\Common.lib >+ >+OBJECTS = DevicePath.obj UefiDevicePathLib.obj DevicePathFromText.obj >DevicePathUtilities.obj >+ >+#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib >+ >+!INCLUDE ..\Makefiles\ms.app >+ >diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c >b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c >new file mode 100644 >index 0000000..a2e0322 >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c >@@ -0,0 +1,298 @@ >+/** @file >+ Device Path services. The thing to remember is device paths are built out of >+ nodes. The device path is terminated by an end node that is length >+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is >sizeof(EFI_DEVICE_PATH_PROTOCOL) >+ all over this file. >+ >+ The only place where multi-instance device paths are supported is in >+ environment varibles. Multi-instance device paths should never be placed >+ on a Handle. >+ >+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+ This program and the accompanying materials >+ are licensed and made available under the terms and conditions of the BSD >License >+ which accompanies this distribution. The full text of the license may be >found at >+ http://opensource.org/licenses/bsd-license.php. >+ >+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+ >+**/ >+ >+ >+#include "UefiDevicePathLib.h" >+ >+/** >+ Returns the size of a device path in bytes. >+ >+ This function returns the size, in bytes, of the device path data structure >+ specified by DevicePath including the end of device path node. >+ If DevicePath is NULL or invalid, then 0 is returned. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval 0 If DevicePath is NULL or invalid. >+ @retval Others The size of a device path in bytes. >+ >+**/ >+UINTN >+GetDevicePathSize ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ) >+{ >+ return UefiDevicePathLibGetDevicePathSize (DevicePath); >+} >+ >+/** >+ Creates a new copy of an existing device path. >+ >+ This function allocates space for a new copy of the device path specified by >DevicePath. >+ If DevicePath is NULL, then NULL is returned. If the memory is successfully >+ allocated, then the contents of DevicePath are copied to the newly >allocated >+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is >returned. >+ The memory for the new device path is allocated from EFI boot services >memory. >+ It is the responsibility of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval NULL DevicePath is NULL or invalid. >+ @retval Others A pointer to the duplicated device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+DuplicateDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ) >+{ >+ return UefiDevicePathLibDuplicateDevicePath (DevicePath); >+} >+ >+/** >+ Creates a new device path by appending a second device path to a first >device path. >+ >+ This function creates a new device path by appending a copy of >SecondDevicePath >+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of- >device-path >+ device node from SecondDevicePath is retained. The newly created device >path is >+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of >+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is >ignored, >+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and >+ SecondDevicePath are NULL, then a copy of an end-of-device-path is >returned. >+ >+ If there is not enough memory for the newly allocated buffer, then NULL is >returned. >+ The memory for the new device path is allocated from EFI boot services >memory. >+ It is the responsibility of the caller to free the memory allocated. >+ >+ @param FirstDevicePath A pointer to a device path data structure. >+ @param SecondDevicePath A pointer to a device path data structure. >+ >+ @retval NULL If there is not enough memory for the newly allocated >buffer. >+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid. >+ @retval Others A pointer to the new device path if success. >+ Or a copy an end-of-device-path if both FirstDevicePath and >SecondDevicePath are NULL. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+AppendDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL >+ ) >+{ >+ return UefiDevicePathLibAppendDevicePath (FirstDevicePath, >SecondDevicePath); >+} >+ >+/** >+ Creates a new path by appending the device node to the device path. >+ >+ This function creates a new device path by appending a copy of the device >node >+ specified by DevicePathNode to a copy of the device path specified by >DevicePath >+ in an allocated buffer. The end-of-device-path device node is moved after >the >+ end of the appended device node. >+ If DevicePathNode is NULL then a copy of DevicePath is returned. >+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end- >of-device >+ path device node is returned. >+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of- >device-path >+ device node is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ @param DevicePathNode A pointer to a single device path node. >+ >+ @retval NULL If there is not enough memory for the new device path. >+ @retval Others A pointer to the new device path if success. >+ A copy of DevicePathNode followed by an end-of-device-path >node >+ if both FirstDevicePath and SecondDevicePath are NULL. >+ A copy of an end-of-device-path node if both FirstDevicePath >+ and SecondDevicePath are NULL. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+AppendDevicePathNode ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL >+ ) >+{ >+ return UefiDevicePathLibAppendDevicePathNode (DevicePath, >DevicePathNode); >+} >+ >+/** >+ Creates a new device path by appending the specified device path instance >to the specified device >+ path. >+ >+ This function creates a new device path by appending a copy of the device >path >+ instance specified by DevicePathInstance to a copy of the device path >specified >+ by DevicePath in a allocated buffer. >+ The end-of-device-path device node is moved after the end of the >appended device >+ path instance and a new end-of-device-path-instance node is inserted >between. >+ If DevicePath is NULL, then a copy if DevicePathInstance is returned. >+ If DevicePathInstance is NULL, then NULL is returned. >+ If DevicePath or DevicePathInstance is invalid, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ @param DevicePathInstance A pointer to a device path instance. >+ >+ @return A pointer to the new device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+AppendDevicePathInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL >+ ) >+{ >+ return UefiDevicePathLibAppendDevicePathInstance (DevicePath, >DevicePathInstance); >+} >+ >+/** >+ Creates a copy of the current device path instance and returns a pointer to >the next device path >+ instance. >+ >+ This function creates a copy of the current device path instance. It also >updates >+ DevicePath to point to the next device path instance in the device path (or >NULL >+ if no more) and updates Size to hold the size of the device path instance >copy. >+ If DevicePath is NULL, then NULL is returned. >+ If DevicePath points to a invalid device path, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ If Size is NULL, then ASSERT(). >+ >+ @param DevicePath On input, this holds the pointer to the current >+ device path instance. On output, this holds >+ the pointer to the next device path instance >+ or NULL if there are no more device path >+ instances in the device path pointer to a >+ device path data structure. >+ @param Size On output, this holds the size of the device >+ path instance, in bytes or zero, if DevicePath >+ is NULL. >+ >+ @return A pointer to the current device path instance. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+GetNextDevicePathInstance ( >+ EFI_DEVICE_PATH_PROTOCOL **DevicePath, >+ UINTN *Size >+ ) >+{ >+ return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size); >+} >+ >+/** >+ Creates a device node. >+ >+ This function creates a new device node in a newly allocated buffer of size >+ NodeLength and initializes the device path node header with NodeType >and NodeSubType. >+ The new device path node is returned. >+ If NodeLength is smaller than a device path header, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param NodeType The device node type for the new device >node. >+ @param NodeSubType The device node sub-type for the new >device node. >+ @param NodeLength The length of the new device node. >+ >+ @return The new device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+CreateDeviceNode ( >+ UINT8 NodeType, >+ UINT8 NodeSubType, >+ UINT16 NodeLength >+ ) >+{ >+ return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, >NodeLength); >+} >+ >+/** >+ Determines if a device path is single or multi-instance. >+ >+ This function returns TRUE if the device path specified by DevicePath is >+ multi-instance. >+ Otherwise, FALSE is returned. >+ If DevicePath is NULL or invalid, then FALSE is returned. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval TRUE DevicePath is multi-instance. >+ @retval FALSE DevicePath is not multi-instance, or DevicePath >+ is NULL or invalid. >+ >+**/ >+BOOLEAN >+IsDevicePathMultiInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ) >+{ >+ return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath); >+} >+ >+/** >+ Convert text to the binary representation of a device node. >+ >+ @param TextDeviceNode TextDeviceNode points to the text >representation of a device >+ node. Conversion starts with the first character and continues >+ until the first non-device node character. >+ >+ @return A pointer to the EFI device node or NULL if TextDeviceNode is >NULL or there was >+ insufficient memory or text unsupported. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+ConvertTextToDeviceNode ( >+ CONST CHAR16 *TextDeviceNode >+ ) >+{ >+ return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode); >+} >+ >+/** >+ Convert text to the binary representation of a device path. >+ >+ >+ @param TextDevicePath TextDevicePath points to the text representation >of a device >+ path. Conversion starts with the first character and continues >+ until the first non-device node character. >+ >+ @return A pointer to the allocated device path or NULL if TextDeviceNode >is NULL or >+ there was insufficient memory. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+ConvertTextToDevicePath ( >+ CONST CHAR16 *TextDevicePath >+ ) >+{ >+ return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath); >+} >diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h >b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h >new file mode 100644 >index 0000000..e03fbd0 >--- /dev/null >+++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h >@@ -0,0 +1,473 @@ >+/** @file >+ Definition for Device Path library. >+ >+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> >+This program and the accompanying materials >+are licensed and made available under the terms and conditions of the BSD >License >+which accompanies this distribution. The full text of the license may be >found at >+http://opensource.org/licenses/bsd-license.php >+ >+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+ >+**/ >+#ifndef _UEFI_DEVICE_PATH_LIB_H_ >+#define _UEFI_DEVICE_PATH_LIB_H_ >+ >+#include <stdio.h> >+#include <stdlib.h> >+#include <string.h> >+#include <ctype.h> >+#include <assert.h> >+#ifdef __GNUC__ >+#include <unistd.h> >+#else >+#include <direct.h> >+#endif >+#include <Common/UefiBaseTypes.h> >+#include "CommonLib.h" >+#include "EfiUtilityMsgs.h" >+#include "DevicePath.h" >+#include "DevicePathUtilities.h" >+#include "DevicePathFromText.h" >+ >+ >+#define IS_COMMA(a) ((a) == L',') >+#define IS_HYPHEN(a) ((a) == L'-') >+#define IS_DOT(a) ((a) == L'.') >+#define IS_LEFT_PARENTH(a) ((a) == L'(') >+#define IS_RIGHT_PARENTH(a) ((a) == L')') >+#define IS_SLASH(a) ((a) == L'/') >+#define IS_NULL(a) ((a) == L'\0') >+ >+#define MAX_UINTN MAX_ADDRESS >+#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL) >+#define MAX_UINT16 ((UINT16)0xFFFF) >+#define MAX_UINT8 ((UINT8)0xFF) >+ >+#define END_DEVICE_PATH_LENGTH (sizeof >(EFI_DEVICE_PATH_PROTOCOL)) >+#define MAX_DEVICE_PATH_NODE_COUNT 1024 >+#define SIZE_64KB 0x00010000 >+#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0])) >+#define ASCII_RSIZE_MAX 1000000 >+#ifndef RSIZE_MAX >+#define RSIZE_MAX 1000000 >+#endif >+ >+// >+// Private Data structure >+// >+typedef >+EFI_DEVICE_PATH_PROTOCOL * >+(*DEVICE_PATH_FROM_TEXT) ( >+ IN CHAR16 *Str >+ ); >+ >+typedef struct { >+ CHAR16 *Str; >+ UINTN Count; >+ UINTN Capacity; >+} POOL_PRINT; >+ >+ >+typedef struct { >+ CHAR16 *DevicePathNodeText; >+ DEVICE_PATH_FROM_TEXT Function; >+} DEVICE_PATH_FROM_TEXT_TABLE; >+ >+typedef struct { >+ BOOLEAN ClassExist; >+ UINT8 Class; >+ BOOLEAN SubClassExist; >+ UINT8 SubClass; >+} USB_CLASS_TEXT; >+ >+#define USB_CLASS_AUDIO 1 >+#define USB_CLASS_CDCCONTROL 2 >+#define USB_CLASS_HID 3 >+#define USB_CLASS_IMAGE 6 >+#define USB_CLASS_PRINTER 7 >+#define USB_CLASS_MASS_STORAGE 8 >+#define USB_CLASS_HUB 9 >+#define USB_CLASS_CDCDATA 10 >+#define USB_CLASS_SMART_CARD 11 >+#define USB_CLASS_VIDEO 14 >+#define USB_CLASS_DIAGNOSTIC 220 >+#define USB_CLASS_WIRELESS 224 >+ >+#define USB_CLASS_RESERVE 254 >+#define USB_SUBCLASS_FW_UPDATE 1 >+#define USB_SUBCLASS_IRDA_BRIDGE 2 >+#define USB_SUBCLASS_TEST 3 >+ >+#define RFC_1700_UDP_PROTOCOL 17 >+#define RFC_1700_TCP_PROTOCOL 6 >+ >+#pragma pack(1) >+ >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ EFI_GUID Guid; >+ UINT8 VendorDefinedData[1]; >+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH; >+ >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ EFI_GUID Guid; >+ UINT8 VendorDefinedData[1]; >+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH; >+ >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ EFI_GUID Guid; >+ UINT8 VendorDefinedData[1]; >+} VENDOR_DEFINED_MEDIA_DEVICE_PATH; >+ >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ UINT32 Hid; >+ UINT32 Uid; >+ UINT32 Cid; >+ CHAR8 HidUidCidStr[3]; >+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR; >+ >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ UINT16 NetworkProtocol; >+ UINT16 LoginOption; >+ UINT64 Lun; >+ UINT16 TargetPortalGroupTag; >+ CHAR8 TargetName[1]; >+} ISCSI_DEVICE_PATH_WITH_NAME; >+ >+typedef struct { >+ EFI_DEVICE_PATH_PROTOCOL Header; >+ EFI_GUID Guid; >+ UINT8 VendorDefinedData[1]; >+} VENDOR_DEVICE_PATH_WITH_DATA; >+ >+#pragma pack() >+ >+/** >+ Returns the size of a device path in bytes. >+ >+ This function returns the size, in bytes, of the device path data structure >+ specified by DevicePath including the end of device path node. >+ If DevicePath is NULL or invalid, then 0 is returned. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval 0 If DevicePath is NULL or invalid. >+ @retval Others The size of a device path in bytes. >+ >+**/ >+UINTN >+UefiDevicePathLibGetDevicePathSize ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+/** >+ Creates a new copy of an existing device path. >+ >+ This function allocates space for a new copy of the device path specified by >DevicePath. >+ If DevicePath is NULL, then NULL is returned. If the memory is successfully >+ allocated, then the contents of DevicePath are copied to the newly >allocated >+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is >returned. >+ The memory for the new device path is allocated from EFI boot services >memory. >+ It is the responsibility of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval NULL DevicePath is NULL or invalid. >+ @retval Others A pointer to the duplicated device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibDuplicateDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+/** >+ Creates a new device path by appending a second device path to a first >device path. >+ >+ This function creates a new device path by appending a copy of >SecondDevicePath >+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of- >device-path >+ device node from SecondDevicePath is retained. The newly created device >path is >+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of >+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is >ignored, >+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and >+ SecondDevicePath are NULL, then a copy of an end-of-device-path is >returned. >+ >+ If there is not enough memory for the newly allocated buffer, then NULL is >returned. >+ The memory for the new device path is allocated from EFI boot services >memory. >+ It is the responsibility of the caller to free the memory allocated. >+ >+ @param FirstDevicePath A pointer to a device path data structure. >+ @param SecondDevicePath A pointer to a device path data structure. >+ >+ @retval NULL If there is not enough memory for the newly allocated >buffer. >+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid. >+ @retval Others A pointer to the new device path if success. >+ Or a copy an end-of-device-path if both FirstDevicePath and >SecondDevicePath are NULL. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL >+ ); >+ >+/** >+ Creates a new path by appending the device node to the device path. >+ >+ This function creates a new device path by appending a copy of the device >node >+ specified by DevicePathNode to a copy of the device path specified by >DevicePath >+ in an allocated buffer. The end-of-device-path device node is moved after >the >+ end of the appended device node. >+ If DevicePathNode is NULL then a copy of DevicePath is returned. >+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end- >of-device >+ path device node is returned. >+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of- >device-path >+ device node is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ @param DevicePathNode A pointer to a single device path node. >+ >+ @retval NULL If there is not enough memory for the new device path. >+ @retval Others A pointer to the new device path if success. >+ A copy of DevicePathNode followed by an end-of-device-path >node >+ if both FirstDevicePath and SecondDevicePath are NULL. >+ A copy of an end-of-device-path node if both FirstDevicePath >+ and SecondDevicePath are NULL. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePathNode ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL >+ ); >+ >+/** >+ Creates a new device path by appending the specified device path instance >to the specified device >+ path. >+ >+ This function creates a new device path by appending a copy of the device >path >+ instance specified by DevicePathInstance to a copy of the device path >specified >+ by DevicePath in a allocated buffer. >+ The end-of-device-path device node is moved after the end of the >appended device >+ path instance and a new end-of-device-path-instance node is inserted >between. >+ If DevicePath is NULL, then a copy if DevicePathInstance is returned. >+ If DevicePathInstance is NULL, then NULL is returned. >+ If DevicePath or DevicePathInstance is invalid, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param DevicePath A pointer to a device path data structure. >+ @param DevicePathInstance A pointer to a device path instance. >+ >+ @return A pointer to the new device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibAppendDevicePathInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL >+ ); >+ >+/** >+ Creates a copy of the current device path instance and returns a pointer to >the next device path >+ instance. >+ >+ This function creates a copy of the current device path instance. It also >updates >+ DevicePath to point to the next device path instance in the device path (or >NULL >+ if no more) and updates Size to hold the size of the device path instance >copy. >+ If DevicePath is NULL, then NULL is returned. >+ If DevicePath points to a invalid device path, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ If Size is NULL, then ASSERT(). >+ >+ @param DevicePath On input, this holds the pointer to the current >+ device path instance. On output, this holds >+ the pointer to the next device path instance >+ or NULL if there are no more device path >+ instances in the device path pointer to a >+ device path data structure. >+ @param Size On output, this holds the size of the device >+ path instance, in bytes or zero, if DevicePath >+ is NULL. >+ >+ @return A pointer to the current device path instance. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibGetNextDevicePathInstance ( >+ EFI_DEVICE_PATH_PROTOCOL **DevicePath, >+ UINTN *Size >+ ); >+ >+/** >+ Creates a device node. >+ >+ This function creates a new device node in a newly allocated buffer of size >+ NodeLength and initializes the device path node header with NodeType >and NodeSubType. >+ The new device path node is returned. >+ If NodeLength is smaller than a device path header, then NULL is returned. >+ If there is not enough memory to allocate space for the new device path, >then >+ NULL is returned. >+ The memory is allocated from EFI boot services memory. It is the >responsibility >+ of the caller to free the memory allocated. >+ >+ @param NodeType The device node type for the new device >node. >+ @param NodeSubType The device node sub-type for the new >device node. >+ @param NodeLength The length of the new device node. >+ >+ @return The new device path. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibCreateDeviceNode ( >+ UINT8 NodeType, >+ UINT8 NodeSubType, >+ UINT16 NodeLength >+ ); >+ >+/** >+ Determines if a device path is single or multi-instance. >+ >+ This function returns TRUE if the device path specified by DevicePath is >+ multi-instance. >+ Otherwise, FALSE is returned. >+ If DevicePath is NULL or invalid, then FALSE is returned. >+ >+ @param DevicePath A pointer to a device path data structure. >+ >+ @retval TRUE DevicePath is multi-instance. >+ @retval FALSE DevicePath is not multi-instance, or DevicePath >+ is NULL or invalid. >+ >+**/ >+BOOLEAN >+UefiDevicePathLibIsDevicePathMultiInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+/** >+ Convert text to the binary representation of a device node. >+ >+ @param TextDeviceNode TextDeviceNode points to the text >representation of a device >+ node. Conversion starts with the first character and continues >+ until the first non-device node character. >+ >+ @return A pointer to the EFI device node or NULL if TextDeviceNode is >NULL or there was >+ insufficient memory or text unsupported. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibConvertTextToDeviceNode ( >+ CONST CHAR16 *TextDeviceNode >+ ); >+ >+/** >+ Convert text to the binary representation of a device path. >+ >+ >+ @param TextDevicePath TextDevicePath points to the text representation >of a device >+ path. Conversion starts with the first character and continues >+ until the first non-device node character. >+ >+ @return A pointer to the allocated device path or NULL if TextDeviceNode >is NULL or >+ there was insufficient memory. >+ >+**/ >+EFI_DEVICE_PATH_PROTOCOL * >+UefiDevicePathLibConvertTextToDevicePath ( >+ CONST CHAR16 *TextDevicePath >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+CreateDeviceNode ( >+ UINT8 NodeType, >+ UINT8 NodeSubType, >+ UINT16 NodeLength >+ ); >+ >+ EFI_DEVICE_PATH_PROTOCOL * >+CreateDeviceNode ( >+ UINT8 NodeType, >+ UINT8 NodeSubType, >+ UINT16 NodeLength >+ ); >+ >+BOOLEAN >+IsDevicePathMultiInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+GetNextDevicePathInstance ( >+ EFI_DEVICE_PATH_PROTOCOL **DevicePath, >+ UINTN *Size >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+AppendDevicePathInstance ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+AppendDevicePathNode ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL >+ ); >+EFI_DEVICE_PATH_PROTOCOL * >+AppendDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL >+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+DuplicateDevicePath ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+UINTN >+GetDevicePathSize ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath >+ ); >+ >+CHAR16 * >+ConvertDeviceNodeToText ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode, >+ BOOLEAN DisplayOnly, >+ BOOLEAN AllowShortcuts >+ ); >+ >+CHAR16 * >+ConvertDevicePathToText ( >+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, >+ BOOLEAN DisplayOnly, >+ BOOLEAN AllowShortcuts >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+ConvertTextToDeviceNode ( >+ CONST CHAR16 *TextDeviceNode >+ ); >+ >+EFI_DEVICE_PATH_PROTOCOL * >+ConvertTextToDevicePath ( >+ CONST CHAR16 *TextDevicePath >+ ); >+ >+ >+#endif >diff --git a/BaseTools/Source/C/GNUmakefile >b/BaseTools/Source/C/GNUmakefile >index 0dc7482..37421ad 100644 >--- a/BaseTools/Source/C/GNUmakefile >+++ b/BaseTools/Source/C/GNUmakefile >@@ -65,11 +65,12 @@ APPLICATIONS = \ > GenCrc32 \ > GenVtf \ > LzmaCompress \ > Split \ > TianoCompress \ >- VolInfo >+ VolInfo \ >+ DevicePath > > SUBDIRS := $(LIBRARIES) $(APPLICATIONS) > > $(LIBRARIES): $(MAKEROOT)/libs > $(APPLICATIONS): $(LIBRARIES) $(MAKEROOT)/bin $(VFRAUTOGEN) >diff --git a/BaseTools/Source/C/Makefile b/BaseTools/Source/C/Makefile >index 50be773..5428180 100644 >--- a/BaseTools/Source/C/Makefile >+++ b/BaseTools/Source/C/Makefile >@@ -1,9 +1,9 @@ > ## @file > # Windows makefile for C tools build. > # >-# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> >+# Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR> > # This program and the accompanying materials > # are licensed and made available under the terms and conditions of the BSD >License > # which accompanies this distribution. The full text of the license may be >found at > # http://opensource.org/licenses/bsd-license.php > # >@@ -30,11 +30,12 @@ APPLICATIONS = \ > GenVtf \ > LzmaCompress \ > Split \ > TianoCompress \ > VolInfo \ >- VfrCompile >+ VfrCompile \ >+ DevicePath > > all: libs apps install > > libs: $(LIBRARIES) > @echo. >diff --git a/BaseTools/Source/Python/Common/Misc.py >b/BaseTools/Source/Python/Common/Misc.py >index c51b685..104a370 100644 >--- a/BaseTools/Source/Python/Common/Misc.py >+++ b/BaseTools/Source/Python/Common/Misc.py >@@ -36,11 +36,11 @@ from CommonDataClass.DataClass import * > from Parsing import GetSplitValueList > from Common.LongFilePathSupport import OpenLongFilePath as open > from Common.MultipleWorkspace import MultipleWorkspace as mws > import uuid > from CommonDataClass.Exceptions import BadExpression >- >+import subprocess > ## Regular expression used to find out place holders in string template > gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | >re.UNICODE) > > ## Dictionary used to store file time stamp for quick re-access > gFileTimeStampCache = {} # {file path : file time stamp} >@@ -1472,11 +1472,42 @@ def AnalyzePcdExpression(Setting): > StartPos = Pos + 1 > > return FieldList > > def ParseDevPathValue (Value): >- pass >+ DevPathList = >[ "Path","HardwarePath","Pci","PcCard","MemoryMapped","VenHw","Ctrl"," >BMC","AcpiPath","Acpi","PciRoot", >+ >"PcieRoot","Floppy","Keyboard","Serial","ParallelPort","AcpiEx","AcpiExp","A >cpiAdr","Msg","Ata","Scsi", >+ >"Fibre","FibreEx","I1394","USB","I2O","Infiniband","VenMsg","VenPcAnsi","V >enVt100","VenVt100Plus", >+ >"VenUtf8","UartFlowCtrl","SAS","SasEx","NVMe","UFS","SD","eMMC","Debu >gPort","MAC","IPv4","IPv6","Uart", >+ >"UsbClass","UsbAudio","UsbCDCControl","UsbHID","UsbImage","UsbPrinter" >,"UsbMassStorage","UsbHub", >+ >"UsbCDCData","UsbSmartCard","UsbVideo","UsbDiagnostic","UsbWireless"," >UsbDeviceFirmwareUpdate", >+ >"UsbIrdaBridge","UsbTestAndMeasurement","UsbWwid","Unit","iSCSI","Vla >n","Uri","Bluetooth","Wi-Fi", >+ >"MediaPath","HD","CDROM","VenMedia","Media","Fv","FvFile","Offset","Ra >mDisk","VirtualDisk","VirtualCD", >+ >"PersistentVirtualDisk","PersistentVirtualCD","BbsPath","BBS","Sata" ] >+ if '\\' in Value: >+ Value.replace('\\', '/').replace(' ', '') >+ for Item in Value.split('/'): >+ Key = Item.strip().split('(')[0] >+ if Key not in DevPathList: >+ pass >+ >+ Cmd = 'DevicePath ' + '"' + Value + '"' >+ try: >+ p = subprocess.Popen(Cmd, stdout=subprocess.PIPE, >stderr=subprocess.PIPE, shell=True) >+ out, err = p.communicate() >+ except Exception, X: >+ raise BadExpression("DevicePath: %s" % (str(X)) ) >+ finally: >+ subprocess._cleanup() >+ p.stdout.close() >+ p.stderr.close() >+ if err: >+ raise BadExpression("DevicePath: %s" % str(err)) >+ Size = len(out.split()) >+ out = ','.join(out.split()) >+ return '{' + out + '}', Size >+ > > def ParseFieldValue (Value): > if type(Value) == type(0): > return Value, (Value.bit_length() + 7) / 8 > if type(Value) <> type(''): >diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py >b/BaseTools/Source/Python/Workspace/DscBuildData.py >index 05b26a3..f9cd429 100644 >--- a/BaseTools/Source/Python/Workspace/DscBuildData.py >+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py >@@ -2060,11 +2060,11 @@ class DscBuildData(PlatformBuildClassObject): > ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, >Arch=self._Arch) > if ModuleFile in self._Modules: > continue > ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, >self._Toolchain] > PkgSet.update(ModuleData.Packages) >- self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, >self._Target, self._Toolchain,PkgSet) >+ self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, >self._Arch, self._Target, self._Toolchain,PkgSet) > return self._DecPcds > _Macros = property(_GetMacros) > Arch = property(_GetArch, _SetArch) > Platform = property(_GetPlatformName) > PlatformName = property(_GetPlatformName) >-- >2.6.1.windows.1 > >_______________________________________________ >edk2-devel mailing list >edk2-devel@lists.01.org >https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2025 Red Hat, Inc.