public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	Yunhua Feng <yunhuax.feng@intel.com>,
	Joakim Bech <joakim.bech@linaro.org>
Subject: Re: [Patch] BaseTools: Add DevicePath support for PCD values
Date: Tue, 2 Jan 2018 09:23:30 +0000	[thread overview]
Message-ID: <CAKv+Gu_zTbB7uxD+RYx87bhkrw5nmHzNDmiGpxM0sqZfXZYH0A@mail.gmail.com> (raw)
In-Reply-To: <1514427485-4112-1-git-send-email-yonghong.zhu@intel.com>

Hello Yonghong,

This patch breaks the build on some toolchains. Please see below.

On 28 December 2017 at 02:18, Yonghong Zhu <yonghong.zhu@intel.com> wrote:
> 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/BinWrappers/PosixLike/DevicePath         |   29 +
>  BaseTools/Source/BinaryFiles.txt                   |    3 +-
>  BaseTools/Source/C/Common/CommonLib.c              | 1629 ++++++++++
>  BaseTools/Source/C/Common/CommonLib.h              |  304 +-
>  BaseTools/Source/C/DevicePath/DevicePath.c         |  186 ++
>  BaseTools/Source/C/DevicePath/DevicePathFromText.c | 3349 ++++++++++++++++++++
>  .../Source/C/DevicePath/DevicePathUtilities.c      |  875 +++++
>  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  |  452 +++
>  BaseTools/Source/C/GNUmakefile                     |    3 +-
>  .../Source/C/Include/IndustryStandard/Bluetooth.h  |   62 +
>  BaseTools/Source/C/Include/Protocol/DevicePath.h   | 1391 ++++++++
>  .../C/Include/Protocol/DevicePathUtilities.h       |  294 ++
>  BaseTools/Source/C/Makefile                        |    5 +-
>  BaseTools/Source/Python/Common/Misc.py             |   34 +-
>  17 files changed, 8959 insertions(+), 9 deletions(-)
>  create mode 100755 BaseTools/BinWrappers/PosixLike/DevicePath
>  create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.c
>  create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.c
>  create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.c
>  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
>  create mode 100644 BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h
>  create mode 100644 BaseTools/Source/C/Include/Protocol/DevicePath.h
>  create mode 100644 BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h
>
...
> diff --git a/BaseTools/Source/C/DevicePath/DevicePath.c b/BaseTools/Source/C/DevicePath/DevicePath.c
> new file mode 100644
> index 0000000..4c87163
> --- /dev/null
> +++ b/BaseTools/Source/C/DevicePath/DevicePath.c
> @@ -0,0 +1,186 @@
> +/** @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 = EFI_VIRTUAL_DISK_GUID;
> +EFI_GUID gEfiVirtualCdGuid = EFI_VIRTUAL_CD_GUID;
> +EFI_GUID gEfiPersistentVirtualDiskGuid = EFI_PERSISTENT_VIRTUAL_DISK_GUID;
> +EFI_GUID gEfiPersistentVirtualCdGuid = EFI_PERSISTENT_VIRTUAL_CD_GUID;
> +
> +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) 2017, Intel Corporation. All rights reserved.\n\n");
> +  //
> +  // Details Option
> +  //
> +  fprintf (stdout, "Options:\n");
> +  fprintf (stdout, "  DevicePathString      Device Path string is specified, no space character.\n"
> +                   "                        Example: \"PciRoot(0)/Pci(0,0)\"\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++) {

This violates the coding standard, and results in the following error on GCC:

DevicePath.c: In function `print_mem`:
DevicePath.c:109:5: error: `for` loop initial declarations are only
allowed in C99 mode
     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/DevicePathFromText.c b/BaseTools/Source/C/DevicePath/DevicePathFromText.c
> new file mode 100644
> index 0000000..3d2f5a8
> --- /dev/null
> +++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.c
> @@ -0,0 +1,3349 @@
> +/** @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 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;
> +}
> +
> +/**
> +  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/DevicePathUtilities.c b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
> new file mode 100644
> index 0000000..d4ec274
> --- /dev/null
> +++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
> @@ -0,0 +1,875 @@
> +/** @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 <Protocol/DevicePathUtilities.h>
> +
> +//
> +// 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;
> +}
> 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..7bc974d
> --- /dev/null
> +++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
> @@ -0,0 +1,452 @@
> +/** @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 <Protocol/DevicePath.h>
> +#include <Protocol/DevicePathUtilities.h>
> +#include "CommonLib.h"
> +#include "EfiUtilityMsgs.h"
> +
> +#define END_DEVICE_PATH_LENGTH               (sizeof (EFI_DEVICE_PATH_PROTOCOL))
> +#define MAX_DEVICE_PATH_NODE_COUNT   1024
> +#define SIZE_64KB   0x00010000
> +
> +//
> +// 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/Include/IndustryStandard/Bluetooth.h b/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h
> new file mode 100644
> index 0000000..d6e6d75
> --- /dev/null
> +++ b/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h
> @@ -0,0 +1,62 @@
> +/** @file
> +  This file contains the Bluetooth definitions that are consumed by drivers.
> +  These definitions are from Bluetooth Core Specification Version 4.0 June, 2010
> +
> +  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 _BLUETOOTH_H_
> +#define _BLUETOOTH_H_
> +
> +#pragma pack(1)
> +
> +///
> +/// BLUETOOTH_ADDRESS
> +///
> +typedef struct {
> +  ///
> +  /// 48bit Bluetooth device address.
> +  ///
> +  UINT8      Address[6];
> +} BLUETOOTH_ADDRESS;
> +
> +///
> +/// BLUETOOTH_CLASS_OF_DEVICE. See Bluetooth specification for detail.
> +///
> +typedef struct {
> +  UINT8      FormatType:2;
> +  UINT8      MinorDeviceClass: 6;
> +  UINT16     MajorDeviceClass: 5;
> +  UINT16     MajorServiceClass:11;
> +} BLUETOOTH_CLASS_OF_DEVICE;
> +
> +///
> +/// 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;
> +
> +#pragma pack()
> +
> +#define BLUETOOTH_HCI_COMMAND_LOCAL_READABLE_NAME_MAX_SIZE    248
> +
> +#define BLUETOOTH_HCI_LINK_KEY_SIZE                           16
> +
> +#endif
> diff --git a/BaseTools/Source/C/Include/Protocol/DevicePath.h b/BaseTools/Source/C/Include/Protocol/DevicePath.h
> new file mode 100644
> index 0000000..a5d8eea
> --- /dev/null
> +++ b/BaseTools/Source/C/Include/Protocol/DevicePath.h
> @@ -0,0 +1,1391 @@
> +/** @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>
> +#include <IndustryStandard/Bluetooth.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 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 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 \
> +  { \
> +    0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E } \
> +  }
> +
> +extern  EFI_GUID                            gEfiVirtualDiskGuid;
> +
> +///
> +/// This GUID defines a RAM Disk supporting an ISO image in volatile memory.
> +///
> +#define EFI_VIRTUAL_CD_GUID \
> +  { \
> +    0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB } \
> +  }
> +extern  EFI_GUID                            gEfiVirtualCdGuid;
> +
> +///
> +/// This GUID defines a RAM Disk supporting a raw disk format in persistent memory.
> +///
> +#define EFI_PERSISTENT_VIRTUAL_DISK_GUID \
> +  { \
> +    0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 } \
> +  }
> +
> +extern  EFI_GUID                            gEfiPersistentVirtualDiskGuid;
> +
> +///
> +/// This GUID defines a RAM Disk supporting an ISO image in persistent memory.
> +///
> +#define EFI_PERSISTENT_VIRTUAL_CD_GUID \
> +  { \
> +    0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D } \
> +  }
> +
> +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/Include/Protocol/DevicePathUtilities.h b/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h
> new file mode 100644
> index 0000000..d046c86
> --- /dev/null
> +++ b/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h
> @@ -0,0 +1,294 @@
> +/** @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;
> +
> +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
> +  );
> +
> +#endif
> 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 59d1ba2..15ad9e4 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,41 @@ 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(''):
> --
> 2.6.1.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


  reply	other threads:[~2018-01-02  9:18 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-28  2:18 [Patch] BaseTools: Add DevicePath support for PCD values Yonghong Zhu
2018-01-02  9:23 ` Ard Biesheuvel [this message]
2018-01-02  9:49   ` Zhu, Yonghong
2018-01-02  9:53     ` Zhu, Yonghong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAKv+Gu_zTbB7uxD+RYx87bhkrw5nmHzNDmiGpxM0sqZfXZYH0A@mail.gmail.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox