[edk2] [Patch] BaseTools: Add DevicePath support for PCD values

Yonghong Zhu posted 1 patch 6 years, 12 months ago
Failed in applying to current master (apply log)
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
[edk2] [Patch] BaseTools: Add DevicePath support for PCD values
Posted by Yonghong Zhu 6 years, 12 months ago
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/BinWrappers/PosixLike/DevicePath b/BaseTools/BinWrappers/PosixLike/DevicePath
new file mode 100755
index 0000000..0945d86
--- /dev/null
+++ b/BaseTools/BinWrappers/PosixLike/DevicePath
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
+dir=$(dirname "$full_cmd")
+cmd=${full_cmd##*/}
+
+if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
+then
+  exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
+elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
+then
+  if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
+  then
+    echo "BaseTools C Tool binary was not found ($cmd)"
+    echo "You may need to run:"
+    echo "  make -C $EDK_TOOLS_PATH/Source/C"
+  else
+    exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
+  fi
+elif [ -e "$dir/../../Source/C/bin/$cmd" ]
+then
+  exec "$dir/../../Source/C/bin/$cmd" "$@"
+else
+  echo "Unable to find the real '$cmd' to run"
+  echo "This message was printed by"
+  echo "  $0"
+  exit 127
+fi
+
diff --git a/BaseTools/Source/BinaryFiles.txt b/BaseTools/Source/BinaryFiles.txt
index 7b014a7..a5273d4 100644
--- a/BaseTools/Source/BinaryFiles.txt
+++ b/BaseTools/Source/BinaryFiles.txt
@@ -9,11 +9,11 @@
 # [ExtraFiles.Win32] section.
 # The [CxFreeze.Win32] section is maintained by the owner of the Build Server who
 # must ensure that files that are required by the cx_freeze frozen binaries are 
 # present in the Bin\Win32 directory.
 #
-# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 # This program and the accompanying materials are licensed and made available under
 # the terms and conditions of the BSD License which accompanies this distribution.
 # The full text of the license may be found at:
 #   http://opensource.org/licenses/bsd-license.php
@@ -57,10 +57,11 @@ TianoCompress.exe
 Trim.exe
 UPT.exe
 VfrCompile.exe
 VolInfo.exe
 Pkcs7Sign.exe
+DevicePath.exe
 
 [ExtraFiles.Win32]
 TestSigningPrivateKey.pem
 config.ini
 exception.xml
diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c
index 4a62bec..90cc578 100644
--- a/BaseTools/Source/C/Common/CommonLib.c
+++ b/BaseTools/Source/C/Common/CommonLib.c
@@ -22,10 +22,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <direct.h>
 #endif
 #include "CommonLib.h"
 #include "EfiUtilityMsgs.h"
 
+#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status)  \
+  do { \
+    ASSERT (Expression); \
+    if (!(Expression)) { \
+      return Status; \
+    } \
+  } while (FALSE)
+
 VOID
 PeiZeroMem (
   IN VOID   *Buffer,
   IN UINTN  Size
   )
@@ -729,5 +737,1626 @@ Returns:
   }
   
   return PathPointer;
 #endif
 }
+
+CHAR16
+InternalCharToUpper (
+        CHAR16                    Char
+  )
+{
+  if (Char >= L'a' && Char <= L'z') {
+    return (CHAR16) (Char - (L'a' - L'A'));
+  }
+
+  return Char;
+}
+
+UINTN
+StrnLenS (
+   CONST CHAR16              *String,
+   UINTN                     MaxSize
+  )
+{
+  UINTN     Length;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
+  //
+  if ((String == NULL) || (MaxSize == 0)) {
+    return 0;
+  }
+
+  Length = 0;
+  while (String[Length] != 0) {
+    if (Length >= MaxSize - 1) {
+      return MaxSize;
+    }
+    Length++;
+  }
+  return Length;
+}
+
+
+VOID *
+InternalAllocatePool (
+   UINTN   AllocationSize
+  )
+{
+  VOID * Memory;
+
+  Memory = malloc(AllocationSize);
+  ASSERT(Memory != NULL);
+  return Memory;
+}
+
+
+VOID *
+InternalReallocatePool (
+   UINTN            OldSize,
+   UINTN            NewSize,
+   VOID             *OldBuffer  OPTIONAL
+  )
+{
+  VOID  *NewBuffer;
+
+  NewBuffer = AllocateZeroPool (NewSize);
+  if (NewBuffer != NULL && OldBuffer != NULL) {
+    memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
+    free(OldBuffer);
+  }
+  return NewBuffer;
+}
+
+VOID *
+ReallocatePool (
+   UINTN  OldSize,
+   UINTN  NewSize,
+   VOID   *OldBuffer  OPTIONAL
+  )
+{
+  return InternalReallocatePool (OldSize, NewSize, OldBuffer);
+}
+
+/**
+  Returns the length of a Null-terminated Unicode string.
+
+  This function returns the number of Unicode characters in the Null-terminated
+  Unicode string specified by String.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned on a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  @param  String  A pointer to a Null-terminated Unicode string.
+
+  @return The length of String.
+
+**/
+UINTN
+StrLen (
+  CONST CHAR16              *String
+  )
+{
+  UINTN   Length;
+
+  ASSERT (String != NULL);
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  for (Length = 0; *String != L'\0'; String++, Length++) {
+    //
+    // If PcdMaximumUnicodeStringLength is not zero,
+    // length should not more than PcdMaximumUnicodeStringLength
+    //
+  }
+  return Length;
+}
+
+BOOLEAN
+InternalSafeStringIsOverlap (
+  IN VOID    *Base1,
+  IN UINTN   Size1,
+  IN VOID    *Base2,
+  IN UINTN   Size2
+  )
+{
+  if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
+      (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+BOOLEAN
+InternalSafeStringNoStrOverlap (
+  IN CHAR16  *Str1,
+  IN UINTN   Size1,
+  IN CHAR16  *Str2,
+  IN UINTN   Size2
+  )
+{
+  return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
+}
+
+RETURN_STATUS
+StrDecimalToUintnS (
+    CONST CHAR16             *String,
+         CHAR16             **EndPointer,  OPTIONAL
+         UINTN              *Data
+  )
+{
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. Neither String nor Data shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. The length of String shall not be greater than RSIZE_MAX.
+  //
+  if (RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) String;
+  }
+
+  //
+  // Ignore the pad spaces (space or tab)
+  //
+  while ((*String == L' ') || (*String == L'\t')) {
+    String++;
+  }
+
+  //
+  // Ignore leading Zeros after the spaces
+  //
+  while (*String == L'0') {
+    String++;
+  }
+
+  *Data = 0;
+
+  while (InternalIsDecimalDigitCharacter (*String)) {
+    //
+    // If the number represented by String overflows according to the range
+    // defined by UINTN, then MAX_UINTN is stored in *Data and
+    // RETURN_UNSUPPORTED is returned.
+    //
+    if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {
+      *Data = MAX_UINTN;
+      if (EndPointer != NULL) {
+        *EndPointer = (CHAR16 *) String;
+      }
+      return RETURN_UNSUPPORTED;
+    }
+
+    *Data = *Data * 10 + (*String - L'0');
+    String++;
+  }
+
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) String;
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated Unicode decimal string to a value of type UINT64.
+
+  This function outputs a value of type UINT64 by interpreting the contents of
+  the Unicode string specified by String as a decimal number. The format of the
+  input Unicode string String is:
+
+                  [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The function will
+  ignore the pad space, which includes spaces or tab characters, before
+  [decimal digits]. The running zero in the beginning of [decimal digits] will
+  be ignored. Then, the function stops at the first character that is a not a
+  valid decimal character or a Null-terminator, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid decimal digits in the above format, then 0 is stored
+  at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINT64, then
+  MAX_UINT64 is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  decimal digits right after the optional pad spaces, the value of String is
+  stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                   zero, and String contains more than
+                                   PcdMaximumUnicodeStringLength Unicode
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINT64.
+
+**/
+RETURN_STATUS
+StrDecimalToUint64S (
+    CONST CHAR16             *String,
+         CHAR16             **EndPointer,  OPTIONAL
+         UINT64             *Data
+  )
+{
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. Neither String nor Data shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. The length of String shall not be greater than RSIZE_MAX.
+  //
+  if (RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) String;
+  }
+
+  //
+  // Ignore the pad spaces (space or tab)
+  //
+  while ((*String == L' ') || (*String == L'\t')) {
+    String++;
+  }
+
+  //
+  // Ignore leading Zeros after the spaces
+  //
+  while (*String == L'0') {
+    String++;
+  }
+
+  *Data = 0;
+
+  while (InternalIsDecimalDigitCharacter (*String)) {
+    //
+    // If the number represented by String overflows according to the range
+    // defined by UINT64, then MAX_UINT64 is stored in *Data and
+    // RETURN_UNSUPPORTED is returned.
+    //
+    if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) {
+      *Data = MAX_UINT64;
+      if (EndPointer != NULL) {
+        *EndPointer = (CHAR16 *) String;
+      }
+      return RETURN_UNSUPPORTED;
+    }
+
+    *Data = (*Data) * 10 + (*String - L'0');
+    String++;
+  }
+
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) String;
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a value of type
+  UINTN.
+
+  This function outputs a value of type UINTN by interpreting the contents of
+  the Unicode string specified by String as a hexadecimal number. The format of
+  the input Unicode string String is:
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
+  If "x" appears in the input string, it must be prefixed with at least one 0.
+  The function will ignore the pad space, which includes spaces or tab
+  characters, before [zeros], [x] or [hexadecimal digit]. The running zero
+  before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
+  after [x] or the first valid hexadecimal digit. Then, the function stops at
+  the first character that is a not a valid hexadecimal character or NULL,
+  whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid hexadecimal digits in the above format, then 0 is
+  stored at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINTN, then
+  MAX_UINTN is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  hexadecimal digits right after the optional pad spaces, the value of String
+  is stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                   zero, and String contains more than
+                                   PcdMaximumUnicodeStringLength Unicode
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINTN.
+
+**/
+RETURN_STATUS
+StrHexToUintnS (
+    CONST CHAR16             *String,
+         CHAR16             **EndPointer,  OPTIONAL
+         UINTN              *Data
+  )
+{
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. Neither String nor Data shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. The length of String shall not be greater than RSIZE_MAX.
+  //
+  if (RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) String;
+  }
+
+  //
+  // Ignore the pad spaces (space or tab)
+  //
+  while ((*String == L' ') || (*String == L'\t')) {
+    String++;
+  }
+
+  //
+  // Ignore leading Zeros after the spaces
+  //
+  while (*String == L'0') {
+    String++;
+  }
+
+  if (InternalCharToUpper (*String) == L'X') {
+    if (*(String - 1) != L'0') {
+      *Data = 0;
+      return RETURN_SUCCESS;
+    }
+    //
+    // Skip the 'X'
+    //
+    String++;
+  }
+
+  *Data = 0;
+
+  while (InternalIsHexaDecimalDigitCharacter (*String)) {
+    //
+    // If the number represented by String overflows according to the range
+    // defined by UINTN, then MAX_UINTN is stored in *Data and
+    // RETURN_UNSUPPORTED is returned.
+    //
+    if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {
+      *Data = MAX_UINTN;
+      if (EndPointer != NULL) {
+        *EndPointer = (CHAR16 *) String;
+      }
+      return RETURN_UNSUPPORTED;
+    }
+
+    *Data = (*Data << 4) + InternalHexCharToUintn (*String);
+    String++;
+  }
+
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) String;
+  }
+  return RETURN_SUCCESS;
+}
+RETURN_STATUS
+StrHexToUint64S (
+    CONST CHAR16             *String,
+         CHAR16             **EndPointer,  OPTIONAL
+         UINT64             *Data
+  )
+{
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. Neither String nor Data shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. The length of String shall not be greater than RSIZE_MAX.
+  //
+  if (RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) String;
+  }
+
+  //
+  // Ignore the pad spaces (space or tab)
+  //
+  while ((*String == L' ') || (*String == L'\t')) {
+    String++;
+  }
+
+  //
+  // Ignore leading Zeros after the spaces
+  //
+  while (*String == L'0') {
+    String++;
+  }
+
+  if (InternalCharToUpper (*String) == L'X') {
+    if (*(String - 1) != L'0') {
+      *Data = 0;
+      return RETURN_SUCCESS;
+    }
+    //
+    // Skip the 'X'
+    //
+    String++;
+  }
+
+  *Data = 0;
+
+  while (InternalIsHexaDecimalDigitCharacter (*String)) {
+    //
+    // If the number represented by String overflows according to the range
+    // defined by UINT64, then MAX_UINT64 is stored in *Data and
+    // RETURN_UNSUPPORTED is returned.
+    //
+    if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) {
+      *Data = MAX_UINT64;
+      if (EndPointer != NULL) {
+        *EndPointer = (CHAR16 *) String;
+      }
+      return RETURN_UNSUPPORTED;
+    }
+
+    *Data =  ((*Data) << 4) + InternalHexCharToUintn (*String);
+    String++;
+  }
+
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) String;
+  }
+  return RETURN_SUCCESS;
+}
+
+UINT64
+StrDecimalToUint64 (
+  CONST CHAR16              *String
+  )
+{
+  UINT64     Result;
+
+  StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);
+  return Result;
+}
+
+
+UINT64
+StrHexToUint64 (
+  CONST CHAR16             *String
+  )
+{
+  UINT64    Result;
+
+  StrHexToUint64S (String, (CHAR16 **) NULL, &Result);
+  return Result;
+}
+
+UINTN
+StrDecimalToUintn (
+  CONST CHAR16              *String
+  )
+{
+  UINTN     Result;
+
+  StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result);
+  return Result;
+}
+
+UINTN
+StrHexToUintn (
+  CONST CHAR16              *String
+  )
+{
+  UINTN     Result;
+
+  StrHexToUintnS (String, (CHAR16 **) NULL, &Result);
+  return Result;
+}
+
+UINTN
+StrSize (
+  CONST CHAR16              *String
+  )
+{
+  return (StrLen (String) + 1) * sizeof (*String);
+}
+
+
+UINT64
+ReadUnaligned64 (
+   CONST UINT64              *Buffer
+  )
+{
+  ASSERT (Buffer != NULL);
+
+  return *Buffer;
+}
+
+UINT64
+WriteUnaligned64 (
+   UINT64                    *Buffer,
+   UINT64                    Value
+  )
+{
+  ASSERT (Buffer != NULL);
+
+  return *Buffer = Value;
+}
+
+
+EFI_GUID *
+CopyGuid (
+   EFI_GUID         *DestinationGuid,
+   CONST EFI_GUID  *SourceGuid
+  )
+{
+  WriteUnaligned64 (
+    (UINT64*)DestinationGuid,
+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)
+    );
+  WriteUnaligned64 (
+    (UINT64*)DestinationGuid + 1,
+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
+    );
+  return DestinationGuid;
+}
+
+UINT16
+SwapBytes16 (
+  UINT16                    Value
+  )
+{
+  return (UINT16) ((Value<< 8) | (Value>> 8));
+}
+
+
+UINT32
+SwapBytes32 (
+  UINT32                    Value
+  )
+{
+  UINT32  LowerBytes;
+  UINT32  HigherBytes;
+
+  LowerBytes  = (UINT32) SwapBytes16 ((UINT16) Value);
+  HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16));
+  return (LowerBytes << 16 | HigherBytes);
+}
+
+BOOLEAN
+InternalIsDecimalDigitCharacter (
+  CHAR16                    Char
+  )
+{
+  return (BOOLEAN) (Char >= L'0' && Char <= L'9');
+}
+
+VOID *
+InternalAllocateCopyPool (
+   UINTN            AllocationSize,
+   CONST VOID       *Buffer
+  )
+{
+  VOID  *Memory;
+
+  ASSERT (Buffer != NULL);
+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
+
+  Memory = malloc (AllocationSize);
+  if (Memory != NULL) {
+     Memory = memcpy (Memory, Buffer, AllocationSize);
+  }
+  return Memory;
+}
+
+BOOLEAN
+InternalIsHexaDecimalDigitCharacter (
+  CHAR16                    Char
+  )
+{
+
+  return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
+    (Char >= L'A' && Char <= L'F') ||
+    (Char >= L'a' && Char <= L'f'));
+}
+
+UINTN
+InternalHexCharToUintn (
+        CHAR16                    Char
+  )
+{
+  if (InternalIsDecimalDigitCharacter (Char)) {
+    return Char - L'0';
+  }
+
+  return (10 + InternalCharToUpper (Char) - L'A');
+}
+
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a byte array.
+
+  This function outputs a byte array by interpreting the contents of
+  the Unicode string specified by String in hexadecimal format. The format of
+  the input Unicode string String is:
+
+                  [XX]*
+
+  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+  The function decodes every two hexadecimal digit characters as one byte. The
+  decoding stops after Length of characters and outputs Buffer containing
+  (Length / 2) bytes.
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If String is NULL, then ASSERT().
+
+  If Buffer is NULL, then ASSERT().
+
+  If Length is not multiple of 2, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero and Length is greater than
+  PcdMaximumUnicodeStringLength, then ASSERT().
+
+  If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  Length                   The number of Unicode characters to decode.
+  @param  Buffer                   Pointer to the converted bytes array.
+  @param  MaxBufferSize            The maximum size of Buffer.
+
+  @retval RETURN_SUCCESS           Buffer is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If Length is not multiple of 2.
+                                   If PcdMaximumUnicodeStringLength is not zero,
+                                    and Length is greater than
+                                    PcdMaximumUnicodeStringLength.
+  @retval RETURN_UNSUPPORTED       If Length of characters from String contain
+                                    a character that is not valid hexadecimal
+                                    digit characters, or a Null-terminator.
+  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+StrHexToBytes (
+   CONST CHAR16       *String,
+   UINTN              Length,
+   UINT8              *Buffer,
+   UINTN              MaxBufferSize
+  )
+{
+  UINTN                  Index;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. None of String or Buffer shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. Length shall not be greater than RSIZE_MAX.
+  //
+  if (RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  //
+  // 3. Length shall not be odd.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
+
+  //
+  // 4. MaxBufferSize shall equal to or greater than Length / 2.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
+
+  //
+  // 5. String shall not contains invalid hexadecimal digits.
+  //
+  for (Index = 0; Index < Length; Index++) {
+    if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
+      break;
+    }
+  }
+  if (Index != Length) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  //
+  // Convert the hex string to bytes.
+  //
+  for(Index = 0; Index < Length; Index++) {
+
+    //
+    // For even characters, write the upper nibble for each buffer byte,
+    // and for even characters, the lower nibble.
+    //
+    if ((Index & BIT0) == 0) {
+      Buffer[Index / 2]  = (UINT8) InternalHexCharToUintn (String[Index]) << 4;
+    } else {
+      Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
+    }
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated Unicode GUID string to a value of type
+  EFI_GUID.
+
+  This function outputs a GUID value by interpreting the contents of
+  the Unicode string specified by String. The format of the input
+  Unicode string String consists of 36 characters, as follows:
+
+                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+  The pairs aa - pp are two characters in the range [0-9], [a-f] and
+  [A-F], with each pair representing a single byte hexadecimal value.
+
+  The mapping between String and the EFI_GUID structure is as follows:
+                  aa          Data1[24:31]
+                  bb          Data1[16:23]
+                  cc          Data1[8:15]
+                  dd          Data1[0:7]
+                  ee          Data2[8:15]
+                  ff          Data2[0:7]
+                  gg          Data3[8:15]
+                  hh          Data3[0:7]
+                  ii          Data4[0:7]
+                  jj          Data4[8:15]
+                  kk          Data4[16:23]
+                  ll          Data4[24:31]
+                  mm          Data4[32:39]
+                  nn          Data4[40:47]
+                  oo          Data4[48:55]
+                  pp          Data4[56:63]
+
+  If String is NULL, then ASSERT().
+  If Guid is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  Guid                     Pointer to the converted GUID.
+
+  @retval RETURN_SUCCESS           Guid is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+  @retval RETURN_UNSUPPORTED       If String is not as the above format.
+
+**/
+RETURN_STATUS
+StrToGuid (
+   CONST CHAR16       *String,
+   EFI_GUID           *Guid
+  )
+{
+  RETURN_STATUS          Status;
+  EFI_GUID               LocalGuid;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. None of String or Guid shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // Get aabbccdd in big-endian.
+  //
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
+    return RETURN_UNSUPPORTED;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
+  String += 2 * sizeof (LocalGuid.Data1) + 1;
+
+  //
+  // Get eeff in big-endian.
+  //
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
+    return RETURN_UNSUPPORTED;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
+  String += 2 * sizeof (LocalGuid.Data2) + 1;
+
+  //
+  // Get gghh in big-endian.
+  //
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
+    return RETURN_UNSUPPORTED;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
+  String += 2 * sizeof (LocalGuid.Data3) + 1;
+
+  //
+  // Get iijj.
+  //
+  Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
+  if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
+    return RETURN_UNSUPPORTED;
+  }
+  String += 2 * 2 + 1;
+
+  //
+  // Get kkllmmnnoopp.
+  //
+  Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
+  if (RETURN_ERROR (Status)) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  CopyGuid (Guid, &LocalGuid);
+  return RETURN_SUCCESS;
+}
+
+/**
+  Compares up to a specified length the contents of two Null-terminated Unicode strings,
+  and returns the difference between the first mismatched Unicode characters.
+
+  This function compares the Null-terminated Unicode string FirstString to the
+  Null-terminated Unicode string SecondString. At most, Length Unicode
+  characters will be compared. If Length is 0, then 0 is returned. If
+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the
+  value returned is the first mismatched Unicode character in SecondString
+  subtracted from the first mismatched Unicode character in FirstString.
+
+  If Length > 0 and FirstString is NULL, then ASSERT().
+  If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
+  If Length > 0 and SecondString is NULL, then ASSERT().
+  If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
+  PcdMaximumUnicodeStringLength, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+  then ASSERT().
+
+  @param  FirstString   A pointer to a Null-terminated Unicode string.
+  @param  SecondString  A pointer to a Null-terminated Unicode string.
+  @param  Length        The maximum number of Unicode characters to compare.
+
+  @retval 0      FirstString is identical to SecondString.
+  @return others FirstString is not identical to SecondString.
+
+**/
+INTN
+StrnCmp (
+        CONST CHAR16              *FirstString,
+        CONST CHAR16              *SecondString,
+        UINTN                     Length
+  )
+{
+  if (Length == 0) {
+    return 0;
+  }
+
+  //
+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
+  // Length tests are performed inside StrLen().
+  //
+  ASSERT (StrSize (FirstString) != 0);
+  ASSERT (StrSize (SecondString) != 0);
+
+  while ((*FirstString != L'\0') &&
+         (*SecondString != L'\0') &&
+         (*FirstString == *SecondString) &&
+         (Length > 1)) {
+    FirstString++;
+    SecondString++;
+    Length--;
+  }
+
+  return *FirstString - *SecondString;
+}
+
+VOID *
+AllocateCopyPool (
+   UINTN       AllocationSize,
+   CONST VOID  *Buffer
+  )
+{
+  return InternalAllocateCopyPool (AllocationSize, Buffer);
+}
+
+INTN
+StrCmp (
+  CONST CHAR16              *FirstString,
+  CONST CHAR16              *SecondString
+  )
+{
+  //
+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
+  //
+  ASSERT (StrSize (FirstString) != 0);
+  ASSERT (StrSize (SecondString) != 0);
+
+  while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
+    FirstString++;
+    SecondString++;
+  }
+  return *FirstString - *SecondString;
+}
+
+UINT64
+SwapBytes64 (
+  UINT64                    Value
+  )
+{
+  return InternalMathSwapBytes64 (Value);
+}
+
+UINT64
+InternalMathSwapBytes64 (
+  UINT64                    Operand
+  )
+{
+  UINT64  LowerBytes;
+  UINT64  HigherBytes;
+
+  LowerBytes  = (UINT64) SwapBytes32 ((UINT32) Operand);
+  HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));
+
+  return (LowerBytes << 32 | HigherBytes);
+}
+
+RETURN_STATUS
+StrToIpv4Address (
+  CONST CHAR16       *String,
+  CHAR16             **EndPointer,
+  EFI_IPv4_ADDRESS       *Address,
+  UINT8              *PrefixLength
+  )
+{
+  RETURN_STATUS          Status;
+  UINTN                  AddressIndex;
+  UINTN                  Uintn;
+  EFI_IPv4_ADDRESS       LocalAddress;
+  UINT8                  LocalPrefixLength;
+  CHAR16                 *Pointer;
+
+  LocalPrefixLength = MAX_UINT8;
+  LocalAddress.Addr[0] = 0;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. None of String or Guid shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+  for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+    if (!InternalIsDecimalDigitCharacter (*Pointer)) {
+      //
+      // D or P contains invalid characters.
+      //
+      break;
+    }
+
+    //
+    // Get D or P.
+    //
+    Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer, &Uintn);
+    if (RETURN_ERROR (Status)) {
+      return RETURN_UNSUPPORTED;
+    }
+    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+      //
+      // It's P.
+      //
+      if (Uintn > 32) {
+        return RETURN_UNSUPPORTED;
+      }
+      LocalPrefixLength = (UINT8) Uintn;
+    } else {
+      //
+      // It's D.
+      //
+      if (Uintn > MAX_UINT8) {
+        return RETURN_UNSUPPORTED;
+      }
+      LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
+      AddressIndex++;
+    }
+
+    //
+    // Check the '.' or '/', depending on the AddressIndex.
+    //
+    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+      if (*Pointer == L'/') {
+        //
+        // '/P' is in the String.
+        // Skip "/" and get P in next loop.
+        //
+        Pointer++;
+      } else {
+        //
+        // '/P' is not in the String.
+        //
+        break;
+      }
+    } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+      if (*Pointer == L'.') {
+        //
+        // D should be followed by '.'
+        //
+        Pointer++;
+      } else {
+        return RETURN_UNSUPPORTED;
+      }
+    }
+  }
+
+  if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  memcpy (Address, &LocalAddress, sizeof (*Address));
+  if (PrefixLength != NULL) {
+    *PrefixLength = LocalPrefixLength;
+  }
+  if (EndPointer != NULL) {
+    *EndPointer = Pointer;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+StrToIpv6Address (
+  CONST CHAR16       *String,
+  CHAR16             **EndPointer,
+  EFI_IPv6_ADDRESS   *Address,
+  UINT8              *PrefixLength
+  )
+{
+  RETURN_STATUS          Status;
+  UINTN                  AddressIndex;
+  UINTN                  Uintn;
+  EFI_IPv6_ADDRESS       LocalAddress;
+  UINT8                  LocalPrefixLength;
+  CONST CHAR16           *Pointer;
+  CHAR16                 *End;
+  UINTN                  CompressStart;
+  BOOLEAN                ExpectPrefix;
+
+  LocalPrefixLength = MAX_UINT8;
+  CompressStart     = ARRAY_SIZE (Address->Addr);
+  ExpectPrefix      = FALSE;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. None of String or Guid shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+  for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
+      if (*Pointer != L':') {
+        //
+        // ":" or "/" should be followed by digit characters.
+        //
+        return RETURN_UNSUPPORTED;
+      }
+
+      //
+      // Meet second ":" after previous ":" or "/"
+      // or meet first ":" in the beginning of String.
+      //
+      if (ExpectPrefix) {
+        //
+        // ":" shall not be after "/"
+        //
+        return RETURN_UNSUPPORTED;
+      }
+
+      if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
+        //
+        // "::" can only appear once.
+        // "::" can only appear when address is not full length.
+        //
+        return RETURN_UNSUPPORTED;
+      } else {
+        //
+        // Remember the start of zero compressing.
+        //
+        CompressStart = AddressIndex;
+        Pointer++;
+
+        if (CompressStart == 0) {
+          if (*Pointer != L':') {
+            //
+            // Single ":" shall not be in the beginning of String.
+            //
+            return RETURN_UNSUPPORTED;
+          }
+          Pointer++;
+        }
+      }
+    }
+
+    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
+      if (*Pointer == L'/') {
+        //
+        // Might be optional "/P" after "::".
+        //
+        if (CompressStart != AddressIndex) {
+          return RETURN_UNSUPPORTED;
+        }
+      } else {
+        break;
+      }
+    } else {
+      if (!ExpectPrefix) {
+        //
+        // Get X.
+        //
+        Status = StrHexToUintnS (Pointer, &End, &Uintn);
+        if (RETURN_ERROR (Status) || End - Pointer > 4) {
+          //
+          // Number of hexadecimal digit characters is no more than 4.
+          //
+          return RETURN_UNSUPPORTED;
+        }
+        Pointer = End;
+        //
+        // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
+        //
+        ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
+        LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
+        LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
+        AddressIndex += 2;
+      } else {
+        //
+        // Get P, then exit the loop.
+        //
+        Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
+        if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
+          //
+          // Prefix length should not exceed 128.
+          //
+          return RETURN_UNSUPPORTED;
+        }
+        LocalPrefixLength = (UINT8) Uintn;
+        Pointer = End;
+        break;
+      }
+    }
+
+    //
+    // Skip ':' or "/"
+    //
+    if (*Pointer == L'/') {
+      ExpectPrefix = TRUE;
+    } else if (*Pointer == L':') {
+      if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+        //
+        // Meet additional ":" after all 8 16-bit address
+        //
+        break;
+      }
+    } else {
+      //
+      // Meet other character that is not "/" or ":" after all 8 16-bit address
+      //
+      break;
+    }
+    Pointer++;
+  }
+
+  if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
+    (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
+      ) {
+    //
+    // Full length of address shall not have compressing zeros.
+    // Non-full length of address shall have compressing zeros.
+    //
+    return RETURN_UNSUPPORTED;
+  }
+  memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
+  memset (&Address->Addr[CompressStart], 0,  ARRAY_SIZE (Address->Addr) - AddressIndex);
+  if (AddressIndex > CompressStart) {
+    memcpy (
+      &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
+      &LocalAddress.Addr[CompressStart],
+      AddressIndex - CompressStart
+      );
+  }
+
+  if (PrefixLength != NULL) {
+    *PrefixLength = LocalPrefixLength;
+  }
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) Pointer;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+
+RETURN_STATUS
+UnicodeStrToAsciiStrS (
+  CONST CHAR16              *Source,
+  CHAR8                     *Destination,
+  UINTN                     DestMax
+  )
+{
+  UINTN            SourceLen;
+
+  ASSERT (((UINTN) Source & BIT0) == 0);
+
+  //
+  // 1. Neither Destination nor Source shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
+  //
+  if (ASCII_RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+  if (RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  //
+  // 3. DestMax shall not equal zero.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
+
+  //
+  // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
+  //
+  SourceLen = StrnLenS (Source, DestMax);
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
+
+  //
+  // 5. Copying shall not take place between objects that overlap.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
+
+  //
+  // convert string
+  //
+  while (*Source != '\0') {
+    //
+    // If any Unicode characters in Source contain
+    // non-zero value in the upper 8 bits, then ASSERT().
+    //
+    ASSERT (*Source < 0x100);
+    *(Destination++) = (CHAR8) *(Source++);
+  }
+  *Destination = '\0';
+
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+StrCpyS (
+  CHAR16       *Destination,
+  UINTN        DestMax,
+  CONST CHAR16 *Source
+  )
+{
+  UINTN            SourceLen;
+
+  ASSERT (((UINTN) Destination & BIT0) == 0);
+  ASSERT (((UINTN) Source & BIT0) == 0);
+
+  //
+  // 1. Neither Destination nor Source shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. DestMax shall not be greater than RSIZE_MAX.
+  //
+  if (RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  //
+  // 3. DestMax shall not equal zero.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
+
+  //
+  // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
+  //
+  SourceLen = StrnLenS (Source, DestMax);
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
+
+  //
+  // 5. Copying shall not take place between objects that overlap.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
+
+  //
+  // The StrCpyS function copies the string pointed to by Source (including the terminating
+  // null character) into the array pointed to by Destination.
+  //
+  while (*Source != 0) {
+    *(Destination++) = *(Source++);
+  }
+  *Destination = 0;
+
+  return RETURN_SUCCESS;
+}
+
+VOID *
+AllocateZeroPool (
+  UINTN  AllocationSize
+  )
+{
+  VOID * Memory;
+  Memory = malloc(AllocationSize);
+  ASSERT (Memory != NULL);
+  if (Memory == NULL) {
+    fprintf(stderr, "Not memory for malloc\n");
+  }
+  memset(Memory, 0, AllocationSize);
+  return Memory;
+}
+
+VOID *
+AllocatePool (
+  UINTN  AllocationSize
+  )
+{
+  return InternalAllocatePool (AllocationSize);
+}
+
+UINT16
+WriteUnaligned16 (
+  UINT16                    *Buffer,
+  UINT16                    Value
+  )
+{
+  ASSERT (Buffer != NULL);
+
+  return *Buffer = Value;
+}
+
+UINT16
+ReadUnaligned16 (
+  CONST UINT16              *Buffer
+  )
+{
+  ASSERT (Buffer != NULL);
+
+  return *Buffer;
+}
+/**
+  Return whether the integer string is a hex string.
+
+  @param Str             The integer string
+
+  @retval TRUE   Hex string
+  @retval FALSE  Decimal string
+
+**/
+BOOLEAN
+IsHexStr (
+   CHAR16   *Str
+  )
+{
+  //
+  // skip preceeding white space
+  //
+  while ((*Str != 0) && *Str == L' ') {
+    Str ++;
+  }
+  //
+  // skip preceeding zeros
+  //
+  while ((*Str != 0) && *Str == L'0') {
+    Str ++;
+  }
+
+  return (BOOLEAN) (*Str == L'x' || *Str == L'X');
+}
+
+/**
+
+  Convert integer string to uint.
+
+  @param Str             The integer string. If leading with "0x" or "0X", it's hexadecimal.
+
+  @return A UINTN value represented by Str
+
+**/
+UINTN
+Strtoi (
+   CHAR16  *Str
+  )
+{
+  if (IsHexStr (Str)) {
+    return StrHexToUintn (Str);
+  } else {
+    return StrDecimalToUintn (Str);
+  }
+}
+
+/**
+
+  Convert integer string to 64 bit data.
+
+  @param Str             The integer string. If leading with "0x" or "0X", it's hexadecimal.
+  @param Data            A pointer to the UINT64 value represented by Str
+
+**/
+VOID
+Strtoi64 (
+    CHAR16  *Str,
+   UINT64  *Data
+  )
+{
+  if (IsHexStr (Str)) {
+    *Data = StrHexToUint64 (Str);
+  } else {
+    *Data = StrDecimalToUint64 (Str);
+  }
+}
+
+/**
+  Converts a Unicode string to ASCII string.
+
+  @param Str             The equivalent Unicode string
+  @param AsciiStr        On input, it points to destination ASCII string buffer; on output, it points
+                         to the next ASCII string next to it
+
+**/
+VOID
+StrToAscii (
+       CHAR16 *Str,
+    CHAR8  **AsciiStr
+  )
+{
+  CHAR8 *Dest;
+
+  Dest = *AsciiStr;
+  while (!IS_NULL (*Str)) {
+    *(Dest++) = (CHAR8) *(Str++);
+  }
+  *Dest = 0;
+
+  //
+  // Return the string next to it
+  //
+  *AsciiStr = Dest + 1;
+}
+
+/**
+  Gets current sub-string from a string list, before return
+  the list header is moved to next sub-string. The sub-string is separated
+  by the specified character. For example, the separator is ',', the string
+  list is "2,0,3", it returns "2", the remain list move to "0,3"
+
+  @param  List        A string list separated by the specified separator
+  @param  Separator   The separator character
+
+  @return A pointer to the current sub-string
+
+**/
+CHAR16 *
+SplitStr (
+    CHAR16 **List,
+       CHAR16 Separator
+  )
+{
+  CHAR16  *Str;
+  CHAR16  *ReturnStr;
+
+  Str = *List;
+  ReturnStr = Str;
+
+  if (IS_NULL (*Str)) {
+    return ReturnStr;
+  }
+
+  //
+  // Find first occurrence of the separator
+  //
+  while (!IS_NULL (*Str)) {
+    if (*Str == Separator) {
+      break;
+    }
+    Str++;
+  }
+
+  if (*Str == Separator) {
+    //
+    // Find a sub-string, terminate it
+    //
+    *Str = L'\0';
+    Str++;
+  }
+
+  //
+  // Move to next sub-string
+  //
+  *List = Str;
+  return ReturnStr;
+}
+
diff --git a/BaseTools/Source/C/Common/CommonLib.h b/BaseTools/Source/C/Common/CommonLib.h
index 2041b89..9da16e8 100644
--- a/BaseTools/Source/C/Common/CommonLib.h
+++ b/BaseTools/Source/C/Common/CommonLib.h
@@ -1,9 +1,9 @@
 /** @file
 Common library assistance routines.
 
-Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
 
@@ -15,14 +15,35 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #ifndef _EFI_COMMON_LIB_H
 #define _EFI_COMMON_LIB_H
 
 #include <Common/UefiBaseTypes.h>
 #include <Common/BuildVersion.h>
+#include <assert.h>
 #define PRINTED_GUID_BUFFER_SIZE  37  // including null-termination
 
 #define MAX_LONG_FILE_PATH 500
 
+#define MAX_UINTN MAX_ADDRESS
+#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL)
+#define MAX_UINT16  ((UINT16)0xFFFF)
+#define MAX_UINT8   ((UINT8)0xFF)
+#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
+#define ASCII_RSIZE_MAX 1000000
+#ifndef RSIZE_MAX
+#define RSIZE_MAX 1000000
+#endif
+
+#define IS_COMMA(a)                ((a) == L',')
+#define IS_HYPHEN(a)               ((a) == L'-')
+#define IS_DOT(a)                  ((a) == L'.')
+#define IS_LEFT_PARENTH(a)         ((a) == L'(')
+#define IS_RIGHT_PARENTH(a)        ((a) == L')')
+#define IS_SLASH(a)                ((a) == L'/')
+#define IS_NULL(a)                 ((a) == L'\0')
+
+#define ASSERT(x) assert(x)
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 //
@@ -147,10 +168,289 @@ PrintGuidToBuffer (
 
 CHAR8 *
 LongFilePath (
  IN CHAR8 *FileName
 );
+
+UINTN
+StrLen (
+  CONST CHAR16   *String
+  );
+
+VOID *
+AllocateCopyPool (
+  UINTN       AllocationSize,
+  CONST VOID  *Buffer
+  );
+
+INTN
+StrnCmp (
+  CONST CHAR16              *FirstString,
+  CONST CHAR16              *SecondString,
+  UINTN                     Length
+  );
+
+RETURN_STATUS
+StrToGuid (
+  CONST CHAR16       *String,
+  EFI_GUID               *Guid
+  );
+
+RETURN_STATUS
+StrHexToBytes (
+  CONST CHAR16       *String,
+  UINTN              Length,
+  UINT8              *Buffer,
+  UINTN              MaxBufferSize
+  );
+
+UINTN
+InternalHexCharToUintn (
+  CHAR16                    Char
+  );
+
+VOID *
+InternalAllocateCopyPool (
+   UINTN            AllocationSize,
+   CONST VOID       *Buffer
+  );
+
+BOOLEAN
+InternalIsDecimalDigitCharacter (
+        CHAR16                    Char
+  );
+
+UINT32
+SwapBytes32 (
+        UINT32                    Value
+  );
+
+UINT16
+SwapBytes16 (
+        UINT16                    Value
+  );
+
+EFI_GUID *
+CopyGuid (
+   EFI_GUID       *DestinationGuid,
+   CONST EFI_GUID  *SourceGuid
+  );
+
+UINT64
+WriteUnaligned64 (
+   UINT64                    *Buffer,
+   UINT64                    Value
+  );
+
+UINT64
+ReadUnaligned64 (
+   CONST UINT64              *Buffer
+  );
+
+UINTN
+StrSize (
+  CONST CHAR16              *String
+  );
+
+UINTN
+StrHexToUintn (
+  CONST CHAR16              *String
+  );
+
+UINTN
+StrDecimalToUintn (
+  CONST CHAR16              *String
+  );
+
+UINT64
+StrHexToUint64 (
+  CONST CHAR16             *String
+  );
+
+UINT64
+StrDecimalToUint64 (
+  CONST CHAR16              *String
+  );
+
+RETURN_STATUS
+StrHexToUint64S (
+    CONST CHAR16       *String,
+    CHAR16             **EndPointer,
+    UINT64             *Data
+  );
+
+RETURN_STATUS
+StrHexToUintnS (
+    CONST CHAR16             *String,
+         CHAR16             **EndPointer,  OPTIONAL
+         UINTN              *Data
+  );
+
+RETURN_STATUS
+StrDecimalToUint64S (
+    CONST CHAR16             *String,
+         CHAR16             **EndPointer,  OPTIONAL
+         UINT64             *Data
+  );
+
+RETURN_STATUS
+StrDecimalToUintnS (
+    CONST CHAR16             *String,
+         CHAR16             **EndPointer,  OPTIONAL
+         UINTN              *Data
+  );
+
+VOID *
+ReallocatePool (
+   UINTN  OldSize,
+   UINTN  NewSize,
+   VOID   *OldBuffer  OPTIONAL
+  );
+
+VOID *
+InternalReallocatePool (
+   UINTN            OldSize,
+   UINTN            NewSize,
+   VOID             *OldBuffer  OPTIONAL
+  );
+
+VOID *
+InternalAllocateZeroPool (
+   UINTN            AllocationSize
+  ) ;
+
+VOID *
+InternalAllocatePool (
+   UINTN            AllocationSize
+  );
+
+UINTN
+StrnLenS (
+   CONST CHAR16              *String,
+   UINTN                     MaxSize
+  );
+
+CHAR16
+InternalCharToUpper (
+        CHAR16                    Char
+  );
+
+INTN
+StrCmp (
+  CONST CHAR16              *FirstString,
+  CONST CHAR16              *SecondString
+  );
+
+UINT64
+SwapBytes64 (
+  UINT64                    Value
+  );
+
+UINT64
+InternalMathSwapBytes64 (
+  UINT64                    Operand
+  );
+
+RETURN_STATUS
+StrToIpv4Address (
+  CONST CHAR16       *String,
+  CHAR16             **EndPointer,
+  EFI_IPv4_ADDRESS       *Address,
+  UINT8              *PrefixLength
+  );
+
+RETURN_STATUS
+StrToIpv6Address (
+  CONST CHAR16       *String,
+  CHAR16             **EndPointer,
+  EFI_IPv6_ADDRESS       *Address,
+  UINT8              *PrefixLength
+  );
+
+RETURN_STATUS
+StrCpyS (
+  CHAR16       *Destination,
+  UINTN        DestMax,
+  CONST CHAR16 *Source
+  );
+
+RETURN_STATUS
+UnicodeStrToAsciiStrS (
+  CONST CHAR16              *Source,
+  CHAR8                     *Destination,
+  UINTN                     DestMax
+  );
+VOID *
+AllocatePool (
+  UINTN  AllocationSize
+  );
+
+UINT16
+WriteUnaligned16 (
+  UINT16                    *Buffer,
+  UINT16                    Value
+  );
+
+UINT16
+ReadUnaligned16 (
+  CONST UINT16              *Buffer
+  );
+
+VOID *
+AllocateZeroPool (
+  UINTN  AllocationSize
+  );
+
+BOOLEAN
+InternalIsHexaDecimalDigitCharacter (
+  CHAR16                    Char
+  );
+
+BOOLEAN
+InternalSafeStringIsOverlap (
+  IN VOID    *Base1,
+  IN UINTN   Size1,
+  IN VOID    *Base2,
+  IN UINTN   Size2
+  );
+
+BOOLEAN
+InternalSafeStringNoStrOverlap (
+  IN CHAR16  *Str1,
+  IN UINTN   Size1,
+  IN CHAR16  *Str2,
+  IN UINTN   Size2
+  );
+
+BOOLEAN
+IsHexStr (
+   CHAR16   *Str
+  );
+
+UINTN
+Strtoi (
+   CHAR16  *Str
+  );
+
+VOID
+Strtoi64 (
+    CHAR16  *Str,
+   UINT64  *Data
+  );
+
+VOID
+StrToAscii (
+       CHAR16 *Str,
+    CHAR8  **AsciiStr
+  );
+
+CHAR16 *
+SplitStr (
+    CHAR16 **List,
+       CHAR16 Separator
+  );
+
 /*++
 
 Routine Description:
   Convert FileName to the long file path, which can support larger than 260 length. 
 
@@ -164,12 +464,10 @@ Returns:
 
 #ifdef __cplusplus
 }
 #endif
 
-#define ASSERT(x) assert(x)
-
 #ifdef __GNUC__
 #include <stdio.h>
 #include <sys/stat.h>
 #define stricmp strcasecmp
 #define _stricmp strcasecmp
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++) {
+        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
Re: [edk2] [Patch] BaseTools: Add DevicePath support for PCD values
Posted by Ard Biesheuvel 6 years, 11 months ago
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
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [Patch] BaseTools: Add DevicePath support for PCD values
Posted by Zhu, Yonghong 6 years, 11 months ago
Thanks. I already created patches for it.

Best Regards,
Zhu Yonghong


-----Original Message-----
From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] 
Sent: Tuesday, January 02, 2018 5:24 PM
To: Zhu, Yonghong <yonghong.zhu@intel.com>
Cc: edk2-devel@lists.01.org; Feng, YunhuaX <yunhuax.feng@intel.com>; Joakim Bech <joakim.bech@linaro.org>
Subject: Re: [edk2] [Patch] BaseTools: Add DevicePath support for PCD values

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
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [Patch] BaseTools: Add DevicePath support for PCD values
Posted by Zhu, Yonghong 6 years, 11 months ago
Still in verify the new patches, will send it out soon.

Best Regards,
Zhu Yonghong

-----Original Message-----
From: Zhu, Yonghong 
Sent: Tuesday, January 2, 2018 5:49 PM
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: edk2-devel@lists.01.org; Feng, YunhuaX <yunhuax.feng@intel.com>; Joakim Bech <joakim.bech@linaro.org>; Zhu, Yonghong <yonghong.zhu@intel.com>
Subject: RE: [edk2] [Patch] BaseTools: Add DevicePath support for PCD values

Thanks. I already created patches for it.

Best Regards,
Zhu Yonghong


-----Original Message-----
From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] 
Sent: Tuesday, January 02, 2018 5:24 PM
To: Zhu, Yonghong <yonghong.zhu@intel.com>
Cc: edk2-devel@lists.01.org; Feng, YunhuaX <yunhuax.feng@intel.com>; Joakim Bech <joakim.bech@linaro.org>
Subject: Re: [edk2] [Patch] BaseTools: Add DevicePath support for PCD values

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
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel