Add 4 APIs to DevicePathLib: ConvertDeviceNodeToText, ConvertDevicePathToText, ConvertTextToDeviceNode and ConvertTextToDevicePath.
Add a new instance of DevicePathLib which tries to locate the protocol and if it's not found, it uses the internal functions.

Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14504 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/MdePkg/Include/Library/DevicePathLib.h b/MdePkg/Include/Library/DevicePathLib.h
index 37acd45..78aac35 100644
--- a/MdePkg/Include/Library/DevicePathLib.h
+++ b/MdePkg/Include/Library/DevicePathLib.h
@@ -4,7 +4,7 @@
   This library provides defines, macros, and functions to help create and parse 

   EFI_DEVICE_PATH_PROTOCOL structures.

 

-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>

+Copyright (c) 2006 - 2013, 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

@@ -483,4 +483,84 @@
   IN CONST CHAR16                    *FileName

   );

 

+/**

+  Converts a device path to its text representation.

+

+  @param DevicePath      A Pointer to the device to be converted.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device path or

+          NULL if DeviceNode is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+ConvertDevicePathToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,

+  IN BOOLEAN                          DisplayOnly,

+  IN BOOLEAN                          AllowShortcuts

+  );

+

+/**

+  Converts a device node to its string representation.

+

+  @param DeviceNode        A Pointer to the device node to be converted.

+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation

+                           of the display node is used, where applicable. If DisplayOnly

+                           is FALSE, then the longer text representation of the display node

+                           is used.

+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text

+                           representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode

+          is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+ConvertDeviceNodeToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,

+  IN BOOLEAN                         DisplayOnly,

+  IN BOOLEAN                         AllowShortcuts

+  );

+

+/**

+  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 *

+EFIAPI

+ConvertTextToDeviceNode (

+  IN 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 *

+EFIAPI

+ConvertTextToDevicePath (

+  IN CONST CHAR16 *TextDevicePath

+  );

+

 #endif

diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
new file mode 100644
index 0000000..9120319
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
@@ -0,0 +1,3032 @@
+/** @file

+  DevicePathFromText protocol as defined in the UEFI 2.0 specification.

+

+Copyright (c) 2013, 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 (

+  IN 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 (

+  IN CHAR16 *Str,

+  IN CHAR16 *NodeName

+  )

+{

+  CHAR16  *ParamStr;

+  CHAR16  *StrPointer;

+  UINTN   NodeNameLength;

+  UINTN   ParameterLength;

+

+  //

+  // Check whether the node name matchs

+  //

+  NodeNameLength = StrLen (NodeName);

+  if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {

+    return NULL;

+  }

+

+  ParamStr = Str + NodeNameLength;

+  if (!IS_LEFT_PARENTH (*ParamStr)) {

+    return NULL;

+  }

+

+  //

+  // Skip the found '(' and find first occurrence of ')'

+  //

+  ParamStr++;

+  ParameterLength = 0;

+  StrPointer = ParamStr;

+  while (!IS_NULL (*StrPointer)) {

+    if (IS_RIGHT_PARENTH (*StrPointer)) {

+      break;

+    }

+    StrPointer++;

+    ParameterLength++;

+  }

+  if (IS_NULL (*StrPointer)) {

+    //

+    // ')' not found

+    //

+    return NULL;

+  }

+

+  ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);

+  if (ParamStr == NULL) {

+    return NULL;

+  }

+  //

+  // Terminate the parameter string

+  //

+  ParamStr[ParameterLength] = L'\0';

+

+  return ParamStr;

+}

+

+/**

+  Gets current sub-string from a string list, before return

+  the list header is moved to next sub-string. The sub-string is separated

+  by the specified character. For example, the separator is ',', the string

+  list is "2,0,3", it returns "2", the remain list move to "0,3"

+

+  @param  List        A string list separated by the specified separator

+  @param  Separator   The separator character

+

+  @return A pointer to the current sub-string

+

+**/

+CHAR16 *

+SplitStr (

+  IN OUT CHAR16 **List,

+  IN     CHAR16 Separator

+  )

+{

+  CHAR16  *Str;

+  CHAR16  *ReturnStr;

+

+  Str = *List;

+  ReturnStr = Str;

+

+  if (IS_NULL (*Str)) {

+    return ReturnStr;

+  }

+

+  //

+  // Find first occurrence of the separator

+  //

+  while (!IS_NULL (*Str)) {

+    if (*Str == Separator) {

+      break;

+    }

+    Str++;

+  }

+

+  if (*Str == Separator) {

+    //

+    // Find a sub-string, terminate it

+    //

+    *Str = L'\0';

+    Str++;

+  }

+

+  //

+  // Move to next sub-string

+  //

+  *List = Str;

+

+  return ReturnStr;

+}

+

+/**

+  Gets the next parameter string from the list.

+

+  @param List            A string list separated by the specified separator

+

+  @return A pointer to the current sub-string

+

+**/

+CHAR16 *

+GetNextParamStr (

+  IN OUT 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 (

+  IN OUT CHAR16   **DevicePath,

+  OUT    BOOLEAN  *IsInstanceEnd

+  )

+{

+  CHAR16  *Str;

+  CHAR16  *ReturnStr;

+  UINTN   ParenthesesStack;

+

+  Str = *DevicePath;

+  if (IS_NULL (*Str)) {

+    return NULL;

+  }

+

+  //

+  // Skip the leading '/', '(', ')' and ','

+  //

+  while (!IS_NULL (*Str)) {

+    if (!IS_SLASH (*Str) &&

+        !IS_COMMA (*Str) &&

+        !IS_LEFT_PARENTH (*Str) &&

+        !IS_RIGHT_PARENTH (*Str)) {

+      break;

+    }

+    Str++;

+  }

+

+  ReturnStr = Str;

+

+  //

+  // Scan for the separator of this device node, '/' or ','

+  //

+  ParenthesesStack = 0;

+  while (!IS_NULL (*Str)) {

+    if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {

+      break;

+    }

+

+    if (IS_LEFT_PARENTH (*Str)) {

+      ParenthesesStack++;

+    } else if (IS_RIGHT_PARENTH (*Str)) {

+      ParenthesesStack--;

+    }

+

+    Str++;

+  }

+

+  if (ParenthesesStack != 0) {

+    //

+    // The '(' doesn't pair with ')', invalid device path text

+    //

+    return NULL;

+  }

+

+  if (IS_COMMA (*Str)) {

+    *IsInstanceEnd = TRUE;

+    *Str = L'\0';

+    Str++;

+  } else {

+    *IsInstanceEnd = FALSE;

+    if (!IS_NULL (*Str)) {

+      *Str = L'\0';

+      Str++;

+    }

+  }

+

+  *DevicePath = Str;

+

+  return ReturnStr;

+}

+

+

+/**

+  Return whether the integer string is a hex string.

+

+  @param Str             The integer string

+

+  @retval TRUE   Hex string

+  @retval FALSE  Decimal string

+

+**/

+BOOLEAN

+IsHexStr (

+  IN 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 (

+  IN 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 (

+  IN  CHAR16  *Str,

+  OUT UINT64  *Data

+  )

+{

+  if (IsHexStr (Str)) {

+    *Data = StrHexToUint64 (Str);

+  } else {

+    *Data = StrDecimalToUint64 (Str);

+  }

+}

+

+/**

+  Converts a list of string to a specified buffer.

+

+  @param Buf             The output buffer that contains the string.

+  @param BufferLength    The length of the buffer

+  @param Str             The input string that contains the hex number

+

+  @retval EFI_SUCCESS    The string was successfully converted to the buffer.

+

+**/

+EFI_STATUS

+StrToBuf (

+  OUT UINT8    *Buf,

+  IN  UINTN    BufferLength,

+  IN  CHAR16   *Str

+  )

+{

+  UINTN       Index;

+  UINTN       StrLength;

+  UINT8       Digit;

+  UINT8       Byte;

+

+  Digit = 0;

+

+  //

+  // Two hex char make up one byte

+  //

+  StrLength = BufferLength * sizeof (CHAR16);

+

+  for(Index = 0; Index < StrLength; Index++, Str++) {

+

+    if ((*Str >= L'a') && (*Str <= L'f')) {

+      Digit = (UINT8) (*Str - L'a' + 0x0A);

+    } else if ((*Str >= L'A') && (*Str <= L'F')) {

+      Digit = (UINT8) (*Str - L'A' + 0x0A);

+    } else if ((*Str >= L'0') && (*Str <= L'9')) {

+      Digit = (UINT8) (*Str - L'0');

+    } else {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    //

+    // For odd characters, write the upper nibble for each buffer byte,

+    // and for even characters, the lower nibble.

+    //

+    if ((Index & 1) == 0) {

+      Byte = (UINT8) (Digit << 4);

+    } else {

+      Byte = Buf[Index / 2];

+      Byte &= 0xF0;

+      Byte = (UINT8) (Byte | Digit);

+    }

+

+    Buf[Index / 2] = Byte;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Converts a string to GUID value.

+  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

+

+  @param Str              The registry format GUID string that contains the GUID value.

+  @param Guid             A pointer to the converted GUID value.

+

+  @retval EFI_SUCCESS     The GUID string was successfully converted to the GUID value.

+  @retval EFI_UNSUPPORTED The input string is not in registry format.

+  @return others          Some error occurred when converting part of GUID value.

+

+**/

+EFI_STATUS

+StrToGuid (

+  IN  CHAR16   *Str,

+  OUT EFI_GUID *Guid

+  )

+{

+  //

+  // Get the first UINT32 data

+  //

+  Guid->Data1 = (UINT32) StrHexToUint64  (Str);

+  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {

+    Str ++;

+  }

+  

+  if (IS_HYPHEN (*Str)) {

+    Str++;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get the second UINT16 data

+  //

+  Guid->Data2 = (UINT16) StrHexToUint64  (Str);

+  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {

+    Str ++;

+  }

+

+  if (IS_HYPHEN (*Str)) {

+    Str++;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get the third UINT16 data

+  //

+  Guid->Data3 = (UINT16) StrHexToUint64  (Str);

+  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {

+    Str ++;

+  }

+

+  if (IS_HYPHEN (*Str)) {

+    Str++;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get the following 8 bytes data

+  //  

+  StrToBuf (&Guid->Data4[0], 2, Str);

+  //

+  // Skip 2 byte hex chars

+  //

+  Str += 2 * 2;

+

+  if (IS_HYPHEN (*Str)) {

+    Str++;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+  StrToBuf (&Guid->Data4[2], 6, Str);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Converts a string to IPv4 address

+

+  @param Str             A string representation of IPv4 address.

+  @param IPv4Addr        A pointer to the converted IPv4 address.

+

+**/

+VOID

+StrToIPv4Addr (

+  IN OUT CHAR16           **Str,

+  OUT    EFI_IPv4_ADDRESS *IPv4Addr

+  )

+{

+  UINTN  Index;

+

+  for (Index = 0; Index < 4; Index++) {

+    IPv4Addr->Addr[Index] = (UINT8) StrDecimalToUintn (SplitStr (Str, L'.'));

+  }

+}

+

+/**

+  Converts a string to IPv4 address

+

+  @param Str             A string representation of IPv6 address.

+  @param IPv6Addr        A pointer to the converted IPv6 address.

+

+**/

+VOID

+StrToIPv6Addr (

+  IN OUT CHAR16           **Str,

+  OUT    EFI_IPv6_ADDRESS *IPv6Addr

+  )

+{

+  UINTN  Index;

+  UINT16 Data;

+

+  for (Index = 0; Index < 8; Index++) {

+    Data = (UINT16) StrHexToUintn (SplitStr (Str, L':'));

+    IPv6Addr->Addr[Index * 2] = (UINT8) (Data >> 8);

+    IPv6Addr->Addr[Index * 2 + 1] = (UINT8) (Data & 0xff);

+  }

+}

+

+/**

+  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 (

+  IN     CHAR16 *Str,

+  IN OUT CHAR8  **AsciiStr

+  )

+{

+  CHAR8 *Dest;

+

+  Dest = *AsciiStr;

+  while (!IS_NULL (*Str)) {

+    *(Dest++) = (CHAR8) *(Str++);

+  }

+  *Dest = 0;

+

+  //

+  // Return the string next to it

+  //

+  *AsciiStr = Dest + 1;

+}

+

+/**

+  Converts a 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN CHAR16 *TextDeviceNode,

+  IN UINT8  Type,

+  IN 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);

+  StrToBuf (((UINT8 *) Vendor) + sizeof (VENDOR_DEVICE_PATH), Length, DataStr);

+

+  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 (

+  IN 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 (

+  IN 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 string to EisaId.

+

+  @param Text   The input string.

+

+  @return UINT32 EISA ID.

+**/

+UINT32

+EisaIdFromText (

+  IN 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 (

+  IN 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 (

+  IN CHAR16 *TextDeviceNode,

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 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 (

+  IN 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);

+

+  Atapi->PrimarySecondary = (UINT8) ((StrCmp (PrimarySecondaryStr, L"Primary") == 0) ? 0 : 1);

+  Atapi->SlaveMaster      = (UINT8) ((StrCmp (SlaveMasterStr, L"Master") == 0) ? 0 : 1);

+  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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN CHAR16 *TextDeviceNode

+  )

+{

+  CHAR16                  *FlagsStr;

+  CHAR16                  *GuidStr;

+  CHAR16                  *SidStr;

+  CHAR16                  *TidStr;

+  CHAR16                  *DidStr;

+  EFI_GUID                PortGid;

+  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, &PortGid);

+  CopyMem (InfiniBand->PortGid, &PortGid, sizeof (EFI_GUID));

+  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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 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 (

+  IN 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, &gEfiDebugPortProtocolGuid);

+

+  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 (

+  IN 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);

+  StrToBuf (&MACDevPath->MacAddress.Addr[0], Length, AddressStr);

+

+  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 (

+  IN 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 (

+  IN 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)

+                                                 );

+

+  StrToIPv4Addr (&RemoteIPStr, &IPv4->RemoteIpAddress);

+  IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);

+  if (StrCmp (TypeStr, L"Static") == 0) {

+    IPv4->StaticIpAddress = TRUE;

+  } else {

+    IPv4->StaticIpAddress = FALSE;

+  }

+

+  StrToIPv4Addr (&LocalIPStr, &IPv4->LocalIpAddress);

+  if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {

+    StrToIPv4Addr (&GatewayIPStr,  &IPv4->GatewayIpAddress);

+    StrToIPv4Addr (&SubnetMaskStr, &IPv4->SubnetMask);

+  } 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 (

+  IN 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)

+                                                 );

+

+  StrToIPv6Addr (&RemoteIPStr, &IPv6->RemoteIpAddress);

+  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;

+  }

+

+  StrToIPv6Addr (&LocalIPStr, &IPv6->LocalIpAddress);

+  if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {

+    StrToIPv6Addr (&GatewayIPStr, &IPv6->GatewayIpAddress);

+    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 (

+  IN 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)

+                                           );

+

+  Uart->BaudRate  = (StrCmp (BaudStr, L"DEFAULT") == 0) ? 115200 : StrDecimalToUintn (BaudStr);

+  Uart->DataBits  = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : StrDecimalToUintn (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 = 0xff;

+  }

+

+  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 = 0xff;

+  }

+

+  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 (

+  IN CHAR16         *TextDeviceNode,

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN CHAR16 *TextDeviceNode

+  )

+{

+  CHAR16                *VIDStr;

+  CHAR16                *PIDStr;

+  CHAR16                *InterfaceNumStr;

+  CHAR16                *SerialNumberStr;

+  USB_WWID_DEVICE_PATH  *UsbWwid;

+

+  VIDStr                    = GetNextParamStr (&TextDeviceNode);

+  PIDStr                    = GetNextParamStr (&TextDeviceNode);

+  InterfaceNumStr           = GetNextParamStr (&TextDeviceNode);

+  SerialNumberStr           = GetNextParamStr (&TextDeviceNode);

+  UsbWwid                   = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (

+                                                         MESSAGING_DEVICE_PATH,

+                                                         MSG_USB_WWID_DP,

+                                                         (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + StrSize (SerialNumberStr))

+                                                         );

+

+  UsbWwid->VendorId         = (UINT16) Strtoi (VIDStr);

+  UsbWwid->ProductId        = (UINT16) Strtoi (PIDStr);

+  UsbWwid->InterfaceNumber  = (UINT16) Strtoi (InterfaceNumStr);

+  StrCpy ((CHAR16 *) ((UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH)), SerialNumberStr);

+

+  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 (

+  IN 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 (

+  IN 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;

+

+  ISCSIDevPath->NetworkProtocol  = (UINT16) StrCmp (ProtocolStr, L"TCP");

+

+  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 (

+  IN 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 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 (

+  IN CHAR16 *TextDeviceNode

+  )

+{

+  CHAR16                *PartitionStr;

+  CHAR16                *TypeStr;

+  CHAR16                *SignatureStr;

+  CHAR16                *StartStr;

+  CHAR16                *SizeStr;

+  UINT32                Signature32;

+  EFI_GUID              SignatureGuid;

+  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) StrDecimalToUintn (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);

+    CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));

+  } else if (StrCmp (TypeStr, L"GPT") == 0) {

+    Hd->SignatureType = SIGNATURE_TYPE_GUID;

+    Hd->MBRType       = 0x02;

+

+    StrToGuid (SignatureStr, &SignatureGuid);

+    CopyMem (Hd->Signature, &SignatureGuid, sizeof (EFI_GUID));

+  } 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 (

+  IN 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 (

+  IN 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 (

+  IN 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)

+                                    );

+

+  StrCpy (File->PathName, 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 (

+  IN 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 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 (

+  IN 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 (

+  IN CHAR16 *TextDeviceNode

+  )

+{

+  SATA_DEVICE_PATH *Sata;

+  CHAR16           *Param1;

+  CHAR16           *Param2;

+  CHAR16           *Param3;

+

+  //

+  // The PMPN is optional.

+  //

+  Param1 = GetNextParamStr (&TextDeviceNode);

+  Param2 = GetNextParamStr (&TextDeviceNode);

+  Param3 = NULL;

+  if (!IS_NULL (TextDeviceNode)) {

+    Param3 = GetNextParamStr (&TextDeviceNode);

+  }

+

+  Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (

+                                MESSAGING_DEVICE_PATH,

+                                MSG_SATA_DP,

+                                (UINT16) sizeof (SATA_DEVICE_PATH)

+                                );

+  Sata->HBAPortNumber = (UINT16) StrHexToUintn (Param1);

+  if (Param3 != NULL) {

+    Sata->PortMultiplierPortNumber = (UINT16) StrHexToUintn (Param2);

+    Param2                   = Param3;

+  } else {

+    Sata->PortMultiplierPortNumber = SATA_HBA_DIRECT_CONNECT_FLAG;

+  }

+  Sata->Lun = (UINT16) StrHexToUintn (Param2);

+

+  return (EFI_DEVICE_PATH_PROTOCOL *) Sata;

+}

+

+GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = {

+  {L"Pci",                     DevPathFromTextPci                     },

+  {L"PcCard",                  DevPathFromTextPcCard                  },

+  {L"MemoryMapped",            DevPathFromTextMemoryMapped            },

+  {L"VenHw",                   DevPathFromTextVenHw                   },

+  {L"Ctrl",                    DevPathFromTextCtrl                    },

+  {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"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"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"HD",                      DevPathFromTextHD                      },

+  {L"CDROM",                   DevPathFromTextCDROM                   },

+  {L"VenMEDIA",                DevPathFromTextVenMEDIA                },

+  {L"Media",                   DevPathFromTextMedia                   },

+  {L"Fv",                      DevPathFromTextFv                      },

+  {L"FvFile",                  DevPathFromTextFvFile                  },

+  {L"Offset",                  DevPathFromTextRelativeOffsetRange     },

+  {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 *

+EFIAPI

+UefiDevicePathLibConvertTextToDeviceNode (

+  IN 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);

+    FreePool (ParamStr);

+  }

+

+  FreePool (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 *

+EFIAPI

+UefiDevicePathLibConvertTextToDevicePath (

+  IN 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);

+    FreePool (DevicePath);

+    FreePool (DeviceNode);

+    DevicePath = NewDevicePath;

+

+    if (IsInstanceEnd) {

+      DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);

+      ASSERT (DeviceNode != NULL);

+      SetDevicePathEndNode (DeviceNode);

+

+      NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);

+      FreePool (DevicePath);

+      FreePool (DeviceNode);

+      DevicePath = NewDevicePath;

+    }

+  }

+

+  FreePool (DevicePathStr);

+  return DevicePath;

+}

diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
new file mode 100644
index 0000000..83c3f8b
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
@@ -0,0 +1,1969 @@
+/** @file

+  DevicePathToText protocol as defined in the UEFI 2.0 specification.

+

+Copyright (c) 2013, 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"

+

+/**

+  Concatenates a formatted unicode string to allocated pool. The caller must

+  free the resulting buffer.

+

+  @param Str             Tracks the allocated pool, size in use, and

+                         amount of pool allocated.

+  @param Fmt             The format string

+  @param ...             Variable arguments based on the format string.

+

+  @return Allocated buffer with the formatted string printed in it.

+          The caller must free the allocated buffer. The buffer

+          allocation is not packed.

+

+**/

+CHAR16 *

+UefiDevicePathLibCatPrint (

+  IN OUT POOL_PRINT   *Str,

+  IN CHAR16           *Fmt,

+  ...

+  )

+{

+  UINTN   Count;

+  VA_LIST Args;

+

+  VA_START (Args, Fmt);

+  Count = SPrintLength (Fmt, Args);

+

+  if ((Str->Count + (Count + 1)) * sizeof (CHAR16) > Str->Capacity) {

+    Str->Capacity = (Str->Count + (Count + 1) * 2) * sizeof (CHAR16);

+    Str->Str = ReallocatePool (

+                 Str->Count * sizeof (CHAR16),

+                 Str->Capacity,

+                 Str->Str

+                 );

+    ASSERT (Str->Str != NULL);

+  }

+  UnicodeVSPrint (&Str->Str[Str->Count], Str->Capacity - Str->Count * sizeof (CHAR16), Fmt, Args);

+  Str->Count += Count;

+  

+  VA_END (Args);

+  return Str->Str;

+}

+

+/**

+  Converts a PCI device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextPci (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  PCI_DEVICE_PATH *Pci;

+

+  Pci = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"Pci(0x%x,0x%x)", Pci->Device, Pci->Function);

+}

+

+/**

+  Converts a PC Card device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextPccard (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  PCCARD_DEVICE_PATH  *Pccard;

+

+  Pccard = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"PcCard(0x%x)", Pccard->FunctionNumber);

+}

+

+/**

+  Converts a Memory Map device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextMemMap (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  MEMMAP_DEVICE_PATH  *MemMap;

+

+  MemMap = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"MemoryMapped(0x%x,0x%lx,0x%lx)",

+    MemMap->MemoryType,

+    MemMap->StartingAddress,

+    MemMap->EndingAddress

+    );

+}

+

+/**

+  Converts a Vendor device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextVendor (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  VENDOR_DEVICE_PATH  *Vendor;

+  CHAR16              *Type;

+  UINTN               Index;

+  UINTN               DataLength;

+  UINT32              FlowControlMap;

+  UINT16              Info;

+

+  Vendor = (VENDOR_DEVICE_PATH *) DevPath;

+  switch (DevicePathType (&Vendor->Header)) {

+  case HARDWARE_DEVICE_PATH:

+    Type = L"Hw";

+    break;

+

+  case MESSAGING_DEVICE_PATH:

+    Type = L"Msg";

+    if (AllowShortcuts) {

+      if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {

+        UefiDevicePathLibCatPrint (Str, L"VenPcAnsi()");

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {

+        UefiDevicePathLibCatPrint (Str, L"VenVt100()");

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {

+        UefiDevicePathLibCatPrint (Str, L"VenVt100Plus()");

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {

+        UefiDevicePathLibCatPrint (Str, L"VenUft8()");

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {

+        FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);

+        switch (FlowControlMap & 0x00000003) {

+        case 0:

+          UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"None");

+          break;

+

+        case 1:

+          UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");

+          break;

+

+        case 2:

+          UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");

+          break;

+

+        default:

+          break;

+        }

+

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {

+        UefiDevicePathLibCatPrint (

+          Str,

+          L"SAS(0x%lx,0x%lx,0x%x,",

+          ((SAS_DEVICE_PATH *) Vendor)->SasAddress,

+          ((SAS_DEVICE_PATH *) Vendor)->Lun,

+          ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort

+          );

+        Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);

+        if (((Info & 0x0f) == 0) && ((Info & BIT7) == 0)) {

+          UefiDevicePathLibCatPrint (Str, L"NoTopology,0,0,0,");

+        } else if (((Info & 0x0f) <= 2) && ((Info & BIT7) == 0)) {

+          UefiDevicePathLibCatPrint (

+            Str,

+            L"%s,%s,%s,",

+            ((Info & BIT4) != 0) ? L"SATA" : L"SAS",

+            ((Info & BIT5) != 0) ? L"External" : L"Internal",

+            ((Info & BIT6) != 0) ? L"Expanded" : L"Direct"

+            );

+          if ((Info & 0x0f) == 1) {

+            UefiDevicePathLibCatPrint (Str, L"0,");

+          } else {

+            //

+            // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256

+            //

+            UefiDevicePathLibCatPrint (Str, L"0x%x,", ((Info >> 8) & 0xff) + 1);

+          }

+        } else {

+          UefiDevicePathLibCatPrint (Str, L"0x%x,0,0,0,", Info);

+        }

+

+        UefiDevicePathLibCatPrint (Str, L"0x%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {

+        UefiDevicePathLibCatPrint (Str, L"DebugPort()");

+        return ;

+      }

+    }

+    break;

+

+  case MEDIA_DEVICE_PATH:

+    Type = L"Media";

+    break;

+

+  default:

+    Type = L"?";

+    break;

+  }

+

+  DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);

+  UefiDevicePathLibCatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);

+  if (DataLength != 0) {

+    UefiDevicePathLibCatPrint (Str, L",");

+    for (Index = 0; Index < DataLength; Index++) {

+      UefiDevicePathLibCatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);

+    }

+  }

+

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  Converts a Controller device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextController (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  CONTROLLER_DEVICE_PATH  *Controller;

+

+  Controller = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"Ctrl(0x%x)",

+    Controller->ControllerNumber

+    );

+}

+

+/**

+  Converts a ACPI device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextAcpi (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  ACPI_HID_DEVICE_PATH  *Acpi;

+

+  Acpi = DevPath;

+  if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {

+    switch (EISA_ID_TO_NUM (Acpi->HID)) {

+    case 0x0a03:

+      UefiDevicePathLibCatPrint (Str, L"PciRoot(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0a08:

+      UefiDevicePathLibCatPrint (Str, L"PcieRoot(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0604:

+      UefiDevicePathLibCatPrint (Str, L"Floppy(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0301:

+      UefiDevicePathLibCatPrint (Str, L"Keyboard(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0501:

+      UefiDevicePathLibCatPrint (Str, L"Serial(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0401:

+      UefiDevicePathLibCatPrint (Str, L"ParallelPort(0x%x)", Acpi->UID);

+      break;

+

+    default:

+      UefiDevicePathLibCatPrint (Str, L"Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);

+      break;

+    }

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID);

+  }

+}

+

+/**

+  Converts a ACPI extended HID device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextAcpiEx (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;

+  CHAR8                          *HIDStr;

+  CHAR8                          *UIDStr;

+  CHAR8                          *CIDStr;

+  CHAR16                         HIDText[11];

+  CHAR16                         CIDText[11];

+

+  AcpiEx = DevPath;

+  HIDStr = (CHAR8 *) (((UINT8 *) AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));

+  UIDStr = HIDStr + AsciiStrLen (HIDStr) + 1;

+  CIDStr = UIDStr + AsciiStrLen (UIDStr) + 1;

+

+  //

+  // Converts EISA identification to string.

+  // 

+  UnicodeSPrint (

+    HIDText,

+    sizeof (HIDText),

+    L"%c%c%c%04X",

+    ((AcpiEx->HID >> 10) & 0x1f) + 'A' - 1,

+    ((AcpiEx->HID >>  5) & 0x1f) + 'A' - 1,

+    ((AcpiEx->HID >>  0) & 0x1f) + 'A' - 1,

+    (AcpiEx->HID >> 16) & 0xFFFF

+    );

+  UnicodeSPrint (

+    CIDText,

+    sizeof (CIDText),

+    L"%c%c%c%04X",

+    ((AcpiEx->CID >> 10) & 0x1f) + 'A' - 1,

+    ((AcpiEx->CID >>  5) & 0x1f) + 'A' - 1,

+    ((AcpiEx->CID >>  0) & 0x1f) + 'A' - 1,

+    (AcpiEx->CID >> 16) & 0xFFFF

+    );

+

+  if ((*HIDStr == '\0') && (*CIDStr == '\0') && (AcpiEx->UID == 0)) {

+    //

+    // use AcpiExp()

+    //

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"AcpiExp(%s,%s,%a)",

+      HIDText,

+      CIDText,

+      UIDStr

+      );

+  } else {

+    if (AllowShortcuts) {

+      //

+      // display only

+      //

+      if (AcpiEx->HID == 0) {

+        UefiDevicePathLibCatPrint (Str, L"AcpiEx(%a,", HIDStr);

+      } else {

+        UefiDevicePathLibCatPrint (Str, L"AcpiEx(%s,", HIDText);

+      }

+

+      if (AcpiEx->UID == 0) {

+        UefiDevicePathLibCatPrint (Str, L"%a,", UIDStr);

+      } else {

+        UefiDevicePathLibCatPrint (Str, L"0x%x,", AcpiEx->UID);

+      }

+

+      if (AcpiEx->CID == 0) {

+        UefiDevicePathLibCatPrint (Str, L"%a)", CIDStr);

+      } else {

+        UefiDevicePathLibCatPrint (Str, L"%s)", CIDText);

+      }

+    } else {

+      UefiDevicePathLibCatPrint (

+        Str,

+        L"AcpiEx(%s,%s,0x%x,%a,%a,%a)",

+        HIDText,

+        CIDText,

+        AcpiEx->UID,

+        HIDStr,

+        CIDStr,

+        UIDStr

+        );

+    }

+  }

+}

+

+/**

+  Converts a ACPI address device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextAcpiAdr (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  ACPI_ADR_DEVICE_PATH    *AcpiAdr;

+  UINT16                  Index;

+  UINT16                  Length;

+  UINT16                  AdditionalAdrCount;

+

+  AcpiAdr            = DevPath;

+  Length             = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);

+  AdditionalAdrCount = (UINT16) ((Length - 8) / 4);

+

+  UefiDevicePathLibCatPrint (Str, L"AcpiAdr(0x%x", AcpiAdr->ADR);

+  for (Index = 0; Index < AdditionalAdrCount; Index++) {

+    UefiDevicePathLibCatPrint (Str, L",0x%x", *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));

+  }

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  Converts a ATAPI device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextAtapi (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  ATAPI_DEVICE_PATH *Atapi;

+

+  Atapi = DevPath;

+

+  if (DisplayOnly) {

+    UefiDevicePathLibCatPrint (Str, L"Ata(0x%x)", Atapi->Lun);

+  } else {

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"Ata(%s,%s,0x%x)",

+      (Atapi->PrimarySecondary == 1) ? L"Secondary" : L"Primary",

+      (Atapi->SlaveMaster == 1) ? L"Slave" : L"Master",

+      Atapi->Lun

+      );

+  }

+}

+

+/**

+  Converts a SCSI device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextScsi (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  SCSI_DEVICE_PATH  *Scsi;

+

+  Scsi = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"Scsi(0x%x,0x%x)", Scsi->Pun, Scsi->Lun);

+}

+

+/**

+  Converts a Fibre device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextFibre (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  FIBRECHANNEL_DEVICE_PATH  *Fibre;

+

+  Fibre = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);

+}

+

+/**

+  Converts a FibreEx device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextFibreEx (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  FIBRECHANNELEX_DEVICE_PATH  *FibreEx;

+  UINTN                       Index;

+

+  FibreEx = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"FibreEx(0x");

+  for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", FibreEx->WWN[Index]);

+  }

+  UefiDevicePathLibCatPrint (Str, L",0x");

+  for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", FibreEx->Lun[Index]);

+  }

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  Converts a Sas Ex device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextSasEx (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  SASEX_DEVICE_PATH  *SasEx;

+  UINTN              Index;

+

+  SasEx = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"SasEx(0x");

+

+  for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", SasEx->SasAddress[Index]);

+  }

+  UefiDevicePathLibCatPrint (Str, L",0x");

+  for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", SasEx->Lun[Index]);

+  }

+  UefiDevicePathLibCatPrint (Str, L",0x%x,", SasEx->RelativeTargetPort);

+

+  if (((SasEx->DeviceTopology & 0x0f) == 0) && ((SasEx->DeviceTopology & BIT7) == 0)) {

+    UefiDevicePathLibCatPrint (Str, L"NoTopology,0,0,0");

+  } else if (((SasEx->DeviceTopology & 0x0f) <= 2) && ((SasEx->DeviceTopology & BIT7) == 0)) {

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"%s,%s,%s,",

+      ((SasEx->DeviceTopology & BIT4) != 0) ? L"SATA" : L"SAS",

+      ((SasEx->DeviceTopology & BIT5) != 0) ? L"External" : L"Internal",

+      ((SasEx->DeviceTopology & BIT6) != 0) ? L"Expanded" : L"Direct"

+      );

+    if ((SasEx->DeviceTopology & 0x0f) == 1) {

+      UefiDevicePathLibCatPrint (Str, L"0");

+    } else {

+      //

+      // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256

+      //

+      UefiDevicePathLibCatPrint (Str, L"0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);

+    }

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"0x%x,0,0,0", SasEx->DeviceTopology);

+  }

+

+  UefiDevicePathLibCatPrint (Str, L")");

+  return ;

+

+}

+

+/**

+  Converts a 1394 device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToText1394 (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  F1394_DEVICE_PATH *F1394DevPath;

+

+  F1394DevPath = DevPath;

+  //

+  // Guid has format of IEEE-EUI64

+  //

+  UefiDevicePathLibCatPrint (Str, L"I1394(%016lx)", F1394DevPath->Guid);

+}

+

+/**

+  Converts a USB device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextUsb (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  USB_DEVICE_PATH *Usb;

+

+  Usb = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);

+}

+

+/**

+  Converts a USB WWID device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextUsbWWID (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  USB_WWID_DEVICE_PATH  *UsbWWId;

+  CHAR16                *SerialNumberStr;

+  CHAR16                *NewStr;

+  UINT16                Length;

+

+  UsbWWId = DevPath;

+

+  SerialNumberStr = (CHAR16 *) ((UINT8 *) UsbWWId + sizeof (USB_WWID_DEVICE_PATH));

+  Length = (UINT16) ((DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) UsbWWId) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16));

+  if (SerialNumberStr [Length - 1] != 0) {

+    //

+    // In case no NULL terminator in SerialNumber, create a new one with NULL terminator

+    //

+    NewStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), SerialNumberStr);

+    ASSERT (NewStr != NULL);

+    NewStr [Length] = 0;

+    SerialNumberStr = NewStr;

+  }

+

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"UsbWwid(0x%x,0x%x,0x%x,\"%s\")",

+    UsbWWId->VendorId,

+    UsbWWId->ProductId,

+    UsbWWId->InterfaceNumber,

+    SerialNumberStr

+    );

+}

+

+/**

+  Converts a Logic Unit device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextLogicalUnit (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;

+

+  LogicalUnit = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"Unit(0x%x)", LogicalUnit->Lun);

+}

+

+/**

+  Converts a USB class device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextUsbClass (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  USB_CLASS_DEVICE_PATH *UsbClass;

+  BOOLEAN               IsKnownSubClass;

+

+

+  UsbClass = DevPath;

+

+  IsKnownSubClass = TRUE;

+  switch (UsbClass->DeviceClass) {

+  case USB_CLASS_AUDIO:

+    UefiDevicePathLibCatPrint (Str, L"UsbAudio");

+    break;

+

+  case USB_CLASS_CDCCONTROL:

+    UefiDevicePathLibCatPrint (Str, L"UsbCDCControl");

+    break;

+

+  case USB_CLASS_HID:

+    UefiDevicePathLibCatPrint (Str, L"UsbHID");

+    break;

+

+  case USB_CLASS_IMAGE:

+    UefiDevicePathLibCatPrint (Str, L"UsbImage");

+    break;

+

+  case USB_CLASS_PRINTER:

+    UefiDevicePathLibCatPrint (Str, L"UsbPrinter");

+    break;

+

+  case USB_CLASS_MASS_STORAGE:

+    UefiDevicePathLibCatPrint (Str, L"UsbMassStorage");

+    break;

+

+  case USB_CLASS_HUB:

+    UefiDevicePathLibCatPrint (Str, L"UsbHub");

+    break;

+

+  case USB_CLASS_CDCDATA:

+    UefiDevicePathLibCatPrint (Str, L"UsbCDCData");

+    break;

+

+  case USB_CLASS_SMART_CARD:

+    UefiDevicePathLibCatPrint (Str, L"UsbSmartCard");

+    break;

+

+  case USB_CLASS_VIDEO:

+    UefiDevicePathLibCatPrint (Str, L"UsbVideo");

+    break;

+

+  case USB_CLASS_DIAGNOSTIC:

+    UefiDevicePathLibCatPrint (Str, L"UsbDiagnostic");

+    break;

+

+  case USB_CLASS_WIRELESS:

+    UefiDevicePathLibCatPrint (Str, L"UsbWireless");

+    break;

+

+  default:

+    IsKnownSubClass = FALSE;

+    break;

+  }

+

+  if (IsKnownSubClass) {

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"(0x%x,0x%x,0x%x,0x%x)",

+      UsbClass->VendorId,

+      UsbClass->ProductId,

+      UsbClass->DeviceSubClass,

+      UsbClass->DeviceProtocol

+      );

+    return;

+  }

+

+  if (UsbClass->DeviceClass == USB_CLASS_RESERVE) {

+    if (UsbClass->DeviceSubClass == USB_SUBCLASS_FW_UPDATE) {

+      UefiDevicePathLibCatPrint (

+        Str,

+        L"UsbDeviceFirmwareUpdate(0x%x,0x%x,0x%x)",

+        UsbClass->VendorId,

+        UsbClass->ProductId,

+        UsbClass->DeviceProtocol

+        );

+      return;

+    } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_IRDA_BRIDGE) {

+      UefiDevicePathLibCatPrint (

+        Str,

+        L"UsbIrdaBridge(0x%x,0x%x,0x%x)",

+        UsbClass->VendorId,

+        UsbClass->ProductId,

+        UsbClass->DeviceProtocol

+        );

+      return;

+    } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_TEST) {

+      UefiDevicePathLibCatPrint (

+        Str,

+        L"UsbTestAndMeasurement(0x%x,0x%x,0x%x)",

+        UsbClass->VendorId,

+        UsbClass->ProductId,

+        UsbClass->DeviceProtocol

+        );

+      return;

+    }

+  }

+

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"UsbClass(0x%x,0x%x,0x%x,0x%x,0x%x)",

+    UsbClass->VendorId,

+    UsbClass->ProductId,

+    UsbClass->DeviceClass,

+    UsbClass->DeviceSubClass,

+    UsbClass->DeviceProtocol

+    );

+}

+

+/**

+  Converts a SATA device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextSata (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  SATA_DEVICE_PATH *Sata;

+

+  Sata = DevPath;

+  if ((Sata->PortMultiplierPortNumber & SATA_HBA_DIRECT_CONNECT_FLAG) != 0) {

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"Sata(0x%x,0x%x)",

+      Sata->HBAPortNumber,

+      Sata->Lun

+      );

+  } else {

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"Sata(0x%x,0x%x,0x%x)",

+      Sata->HBAPortNumber,

+      Sata->PortMultiplierPortNumber,

+      Sata->Lun

+      );

+  }

+}

+

+/**

+  Converts a I20 device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextI2O (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  I2O_DEVICE_PATH *I2ODevPath;

+

+  I2ODevPath = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"I2O(0x%x)", I2ODevPath->Tid);

+}

+

+/**

+  Converts a MAC address device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextMacAddr (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  MAC_ADDR_DEVICE_PATH  *MacDevPath;

+  UINTN                 HwAddressSize;

+  UINTN                 Index;

+

+  MacDevPath = DevPath;

+

+  HwAddressSize = sizeof (EFI_MAC_ADDRESS);

+  if (MacDevPath->IfType == 0x01 || MacDevPath->IfType == 0x00) {

+    HwAddressSize = 6;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"MAC(");

+

+  for (Index = 0; Index < HwAddressSize; Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", MacDevPath->MacAddress.Addr[Index]);

+  }

+

+  UefiDevicePathLibCatPrint (Str, L",0x%x)", MacDevPath->IfType);

+}

+

+/**

+  Converts network protocol string to its text representation.

+

+  @param Str             The string representative of input device.

+  @param Protocol        The network protocol ID.

+

+**/

+VOID

+CatNetworkProtocol (

+  IN OUT POOL_PRINT  *Str,

+  IN UINT16          Protocol

+  )

+{

+  if (Protocol == RFC_1700_TCP_PROTOCOL) {

+    UefiDevicePathLibCatPrint (Str, L"TCP");

+  } else if (Protocol == RFC_1700_UDP_PROTOCOL) {

+    UefiDevicePathLibCatPrint (Str, L"UDP");

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"0x%x", Protocol);

+  }

+}

+

+/**

+  Converts IP v4 address to its text representation.

+

+  @param Str             The string representative of input device.

+  @param Address         The IP v4 address.

+**/

+VOID

+CatIPv4Address (

+  IN OUT POOL_PRINT   *Str,

+  IN EFI_IPv4_ADDRESS *Address

+  )

+{

+  UefiDevicePathLibCatPrint (Str, L"%d.%d.%d.%d", Address->Addr[0], Address->Addr[1], Address->Addr[2], Address->Addr[3]);

+}

+

+/**

+  Converts IP v6 address to its text representation.

+

+  @param Str             The string representative of input device.

+  @param Address         The IP v6 address.

+**/

+VOID

+CatIPv6Address (

+  IN OUT POOL_PRINT   *Str,

+  IN EFI_IPv6_ADDRESS *Address

+  )

+{

+  UefiDevicePathLibCatPrint (

+    Str, L"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",

+    Address->Addr[0],  Address->Addr[1],

+    Address->Addr[2],  Address->Addr[3],

+    Address->Addr[4],  Address->Addr[5],

+    Address->Addr[6],  Address->Addr[7],

+    Address->Addr[8],  Address->Addr[9],

+    Address->Addr[10], Address->Addr[11],

+    Address->Addr[12], Address->Addr[13],

+    Address->Addr[14], Address->Addr[15]

+  );

+}

+

+/**

+  Converts a IPv4 device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextIPv4 (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  IPv4_DEVICE_PATH  *IPDevPath;

+

+  IPDevPath = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"IPv4(");

+  CatIPv4Address (Str, &IPDevPath->RemoteIpAddress);

+

+  if (DisplayOnly) {

+    UefiDevicePathLibCatPrint (Str, L")");

+    return ;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L",");

+  CatNetworkProtocol (Str, IPDevPath->Protocol);

+

+  UefiDevicePathLibCatPrint (Str, L",%s,", IPDevPath->StaticIpAddress ? L"Static" : L"DHCP");

+  CatIPv4Address (Str, &IPDevPath->LocalIpAddress);

+  if (DevicePathNodeLength (IPDevPath) == sizeof (IPv4_DEVICE_PATH)) {

+    UefiDevicePathLibCatPrint (Str, L",");

+    CatIPv4Address (Str, &IPDevPath->GatewayIpAddress);

+    UefiDevicePathLibCatPrint (Str, L",");

+    CatIPv4Address (Str, &IPDevPath->SubnetMask);

+  }

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  Converts a IPv6 device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextIPv6 (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  IPv6_DEVICE_PATH  *IPDevPath;

+

+  IPDevPath = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"IPv6(");

+  CatIPv6Address (Str, &IPDevPath->RemoteIpAddress);

+  if (DisplayOnly) {

+    UefiDevicePathLibCatPrint (Str, L")");

+    return ;

+  }

+  

+  UefiDevicePathLibCatPrint (Str, L",");

+  CatNetworkProtocol (Str, IPDevPath->Protocol);

+

+  switch (IPDevPath->IpAddressOrigin) {

+    case 0:

+      UefiDevicePathLibCatPrint (Str, L",Static,");

+      break;

+    case 1:

+      UefiDevicePathLibCatPrint (Str, L",StatelessAutoConfigure,");

+      break;

+    default:

+      UefiDevicePathLibCatPrint (Str, L",StatefulAutoConfigure,");

+      break;

+  }

+

+  CatIPv6Address (Str, &IPDevPath->LocalIpAddress);

+

+  if (DevicePathNodeLength (IPDevPath) == sizeof (IPv6_DEVICE_PATH)) {

+    UefiDevicePathLibCatPrint (Str, L",0x%x,", IPDevPath->PrefixLength);

+    CatIPv6Address (Str, &IPDevPath->GatewayIpAddress);

+  }

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  Converts an Infini Band device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextInfiniBand (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  INFINIBAND_DEVICE_PATH  *InfiniBand;

+

+  InfiniBand = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"Infiniband(0x%x,%g,0x%lx,0x%lx,0x%lx)",

+    InfiniBand->ResourceFlags,

+    InfiniBand->PortGid,

+    InfiniBand->ServiceId,

+    InfiniBand->TargetPortId,

+    InfiniBand->DeviceId

+    );

+}

+

+/**

+  Converts a UART device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextUart (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  UART_DEVICE_PATH  *Uart;

+  CHAR8             Parity;

+

+  Uart = DevPath;

+  switch (Uart->Parity) {

+  case 0:

+    Parity = 'D';

+    break;

+

+  case 1:

+    Parity = 'N';

+    break;

+

+  case 2:

+    Parity = 'E';

+    break;

+

+  case 3:

+    Parity = 'O';

+    break;

+

+  case 4:

+    Parity = 'M';

+    break;

+

+  case 5:

+    Parity = 'S';

+    break;

+

+  default:

+    Parity = 'x';

+    break;

+  }

+

+  if (Uart->BaudRate == 0) {

+    UefiDevicePathLibCatPrint (Str, L"Uart(DEFAULT,");

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"Uart(%ld,", Uart->BaudRate);

+  }

+

+  if (Uart->DataBits == 0) {

+    UefiDevicePathLibCatPrint (Str, L"DEFAULT,");

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"%d,", Uart->DataBits);

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"%c,", Parity);

+

+  switch (Uart->StopBits) {

+  case 0:

+    UefiDevicePathLibCatPrint (Str, L"D)");

+    break;

+

+  case 1:

+    UefiDevicePathLibCatPrint (Str, L"1)");

+    break;

+

+  case 2:

+    UefiDevicePathLibCatPrint (Str, L"1.5)");

+    break;

+

+  case 3:

+    UefiDevicePathLibCatPrint (Str, L"2)");

+    break;

+

+  default:

+    UefiDevicePathLibCatPrint (Str, L"x)");

+    break;

+  }

+}

+

+/**

+  Converts an iSCSI device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextiSCSI (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;

+  UINT16                      Options;

+

+  ISCSIDevPath = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"iSCSI(%a,0x%x,0x%lx,",

+    ISCSIDevPath->TargetName,

+    ISCSIDevPath->TargetPortalGroupTag,

+    ISCSIDevPath->Lun

+    );

+

+  Options = ISCSIDevPath->LoginOption;

+  UefiDevicePathLibCatPrint (Str, L"%s,", (((Options >> 1) & 0x0001) != 0) ? L"CRC32C" : L"None");

+  UefiDevicePathLibCatPrint (Str, L"%s,", (((Options >> 3) & 0x0001) != 0) ? L"CRC32C" : L"None");

+  if (((Options >> 11) & 0x0001) != 0) {

+    UefiDevicePathLibCatPrint (Str, L"%s,", L"None");

+  } else if (((Options >> 12) & 0x0001) != 0) {

+    UefiDevicePathLibCatPrint (Str, L"%s,", L"CHAP_UNI");

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"%s,", L"CHAP_BI");

+

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"%s)", (ISCSIDevPath->NetworkProtocol == 0) ? L"TCP" : L"reserved");

+}

+

+/**

+  Converts a VLAN device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextVlan (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  VLAN_DEVICE_PATH  *Vlan;

+

+  Vlan = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"Vlan(%d)", Vlan->VlanId);

+}

+

+/**

+  Converts a Hard drive device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextHardDrive (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  HARDDRIVE_DEVICE_PATH *Hd;

+

+  Hd = DevPath;

+  switch (Hd->SignatureType) {

+  case SIGNATURE_TYPE_MBR:

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"HD(%d,%s,0x%08x,",

+      Hd->PartitionNumber,

+      L"MBR",

+      *((UINT32 *) (&(Hd->Signature[0])))

+      );

+    break;

+

+  case SIGNATURE_TYPE_GUID:

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"HD(%d,%s,%g,",

+      Hd->PartitionNumber,

+      L"GPT",

+      (EFI_GUID *) &(Hd->Signature[0])

+      );

+    break;

+

+  default:

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"HD(%d,%d,0,",

+      Hd->PartitionNumber,

+      Hd->SignatureType

+      );

+    break;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);

+}

+

+/**

+  Converts a CDROM device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextCDROM (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  CDROM_DEVICE_PATH *Cd;

+

+  Cd = DevPath;

+  if (DisplayOnly) {

+    UefiDevicePathLibCatPrint (Str, L"CDROM(0x%x)", Cd->BootEntry);

+    return ;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"CDROM(0x%x,0x%lx,0x%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);

+}

+

+/**

+  Converts a File device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextFilePath (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  FILEPATH_DEVICE_PATH  *Fp;

+

+  Fp = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"%s", Fp->PathName);

+}

+

+/**

+  Converts a Media protocol device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextMediaProtocol (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;

+

+  MediaProt = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"Media(%g)", &MediaProt->Protocol);

+}

+

+/**

+  Converts a Firmware Volume device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextFv (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  MEDIA_FW_VOL_DEVICE_PATH  *Fv;

+

+  Fv = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"Fv(%g)", &Fv->FvName);

+}

+

+/**

+  Converts a Firmware Volume File device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextFvFile (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFile;

+

+  FvFile = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"FvFile(%g)", &FvFile->FvFileName);

+}

+

+/**

+  Converts a Relative Offset device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathRelativeOffsetRange (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath,

+  IN BOOLEAN              DisplayOnly,

+  IN BOOLEAN              AllowShortcuts

+  )

+{

+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;

+

+  Offset = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"Offset(0x%lx,0x%lx)",

+    Offset->StartingOffset,

+    Offset->EndingOffset

+    );

+}

+

+/**

+  Converts a BIOS Boot Specification device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextBBS (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  BBS_BBS_DEVICE_PATH *Bbs;

+  CHAR16              *Type;

+

+  Bbs = DevPath;

+  switch (Bbs->DeviceType) {

+  case BBS_TYPE_FLOPPY:

+    Type = L"Floppy";

+    break;

+

+  case BBS_TYPE_HARDDRIVE:

+    Type = L"HD";

+    break;

+

+  case BBS_TYPE_CDROM:

+    Type = L"CDROM";

+    break;

+

+  case BBS_TYPE_PCMCIA:

+    Type = L"PCMCIA";

+    break;

+

+  case BBS_TYPE_USB:

+    Type = L"USB";

+    break;

+

+  case BBS_TYPE_EMBEDDED_NETWORK:

+    Type = L"Network";

+    break;

+

+  default:

+    Type = NULL;

+    break;

+  }

+

+  if (Type != NULL) {

+    UefiDevicePathLibCatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"BBS(0x%x,%a", Bbs->DeviceType, Bbs->String);

+  }

+

+  if (DisplayOnly) {

+    UefiDevicePathLibCatPrint (Str, L")");

+    return ;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L",0x%x)", Bbs->StatusFlag);

+}

+

+/**

+  Converts an End-of-Device-Path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextEndInstance (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  UefiDevicePathLibCatPrint (Str, L",");

+}

+

+/**

+  Converts an unknown device path structure to its string representative.

+

+  @param Str             The string representative of input device.

+  @param DevPath         The input device path structure.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+**/

+VOID

+DevPathToTextNodeUnknown (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  UefiDevicePathLibCatPrint (Str, L"?");

+}

+

+GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_TABLE mUefiDevicePathLibDevPathToTextTable[] = {

+  {HARDWARE_DEVICE_PATH,  HW_PCI_DP,                        DevPathToTextPci            },

+  {HARDWARE_DEVICE_PATH,  HW_PCCARD_DP,                     DevPathToTextPccard         },

+  {HARDWARE_DEVICE_PATH,  HW_MEMMAP_DP,                     DevPathToTextMemMap         },

+  {HARDWARE_DEVICE_PATH,  HW_VENDOR_DP,                     DevPathToTextVendor         },

+  {HARDWARE_DEVICE_PATH,  HW_CONTROLLER_DP,                 DevPathToTextController     },

+  {ACPI_DEVICE_PATH,      ACPI_DP,                          DevPathToTextAcpi           },

+  {ACPI_DEVICE_PATH,      ACPI_EXTENDED_DP,                 DevPathToTextAcpiEx         },

+  {ACPI_DEVICE_PATH,      ACPI_ADR_DP,                      DevPathToTextAcpiAdr        },

+  {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP,                     DevPathToTextAtapi          },

+  {MESSAGING_DEVICE_PATH, MSG_SCSI_DP,                      DevPathToTextScsi           },

+  {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP,              DevPathToTextFibre          },

+  {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNELEX_DP,            DevPathToTextFibreEx        },

+  {MESSAGING_DEVICE_PATH, MSG_SASEX_DP,                     DevPathToTextSasEx          },

+  {MESSAGING_DEVICE_PATH, MSG_1394_DP,                      DevPathToText1394           },

+  {MESSAGING_DEVICE_PATH, MSG_USB_DP,                       DevPathToTextUsb            },

+  {MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP,                  DevPathToTextUsbWWID        },

+  {MESSAGING_DEVICE_PATH, MSG_DEVICE_LOGICAL_UNIT_DP,       DevPathToTextLogicalUnit    },

+  {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,                 DevPathToTextUsbClass       },

+  {MESSAGING_DEVICE_PATH, MSG_SATA_DP,                      DevPathToTextSata           },

+  {MESSAGING_DEVICE_PATH, MSG_I2O_DP,                       DevPathToTextI2O            },

+  {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP,                  DevPathToTextMacAddr        },

+  {MESSAGING_DEVICE_PATH, MSG_IPv4_DP,                      DevPathToTextIPv4           },

+  {MESSAGING_DEVICE_PATH, MSG_IPv6_DP,                      DevPathToTextIPv6           },

+  {MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP,                DevPathToTextInfiniBand     },

+  {MESSAGING_DEVICE_PATH, MSG_UART_DP,                      DevPathToTextUart           },

+  {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,                    DevPathToTextVendor         },

+  {MESSAGING_DEVICE_PATH, MSG_ISCSI_DP,                     DevPathToTextiSCSI          },

+  {MESSAGING_DEVICE_PATH, MSG_VLAN_DP,                      DevPathToTextVlan           },

+  {MEDIA_DEVICE_PATH,     MEDIA_HARDDRIVE_DP,               DevPathToTextHardDrive      },

+  {MEDIA_DEVICE_PATH,     MEDIA_CDROM_DP,                   DevPathToTextCDROM          },

+  {MEDIA_DEVICE_PATH,     MEDIA_VENDOR_DP,                  DevPathToTextVendor         },

+  {MEDIA_DEVICE_PATH,     MEDIA_PROTOCOL_DP,                DevPathToTextMediaProtocol  },

+  {MEDIA_DEVICE_PATH,     MEDIA_FILEPATH_DP,                DevPathToTextFilePath       },

+  {MEDIA_DEVICE_PATH,     MEDIA_PIWG_FW_VOL_DP,             DevPathToTextFv             },

+  {MEDIA_DEVICE_PATH,     MEDIA_PIWG_FW_FILE_DP,            DevPathToTextFvFile         },

+  {MEDIA_DEVICE_PATH,     MEDIA_RELATIVE_OFFSET_RANGE_DP,   DevPathRelativeOffsetRange  },

+  {BBS_DEVICE_PATH,       BBS_BBS_DP,                       DevPathToTextBBS            },

+  {END_DEVICE_PATH_TYPE,  END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance    },

+  {0, 0, NULL}

+};

+

+/**

+  Converts a device node to its string representation.

+

+  @param DeviceNode        A Pointer to the device node to be converted.

+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation

+                           of the display node is used, where applicable. If DisplayOnly

+                           is FALSE, then the longer text representation of the display node

+                           is used.

+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text

+                           representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode

+          is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+UefiDevicePathLibConvertDeviceNodeToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,

+  IN BOOLEAN                         DisplayOnly,

+  IN BOOLEAN                         AllowShortcuts

+  )

+{

+  POOL_PRINT          Str;

+  UINTN               Index;

+  DEVICE_PATH_TO_TEXT ToText;

+

+  if (DeviceNode == NULL) {

+    return NULL;

+  }

+

+  ZeroMem (&Str, sizeof (Str));

+

+  //

+  // Process the device path node

+  // If not found, use a generic function

+  //

+  ToText = DevPathToTextNodeUnknown;

+  for (Index = 0; mUefiDevicePathLibDevPathToTextTable[Index].Function != NULL; Index++) {

+    if (DevicePathType (DeviceNode) == mUefiDevicePathLibDevPathToTextTable[Index].Type &&

+        DevicePathSubType (DeviceNode) == mUefiDevicePathLibDevPathToTextTable[Index].SubType

+        ) {

+      ToText = mUefiDevicePathLibDevPathToTextTable[Index].Function;

+      break;

+    }

+  }

+

+  //

+  // Print this node

+  //

+  ToText (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);

+

+  ASSERT (Str.Str != NULL);

+  return Str.Str;

+}

+

+/**

+  Converts a device path to its text representation.

+

+  @param DevicePath      A Pointer to the device to be converted.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device path or

+          NULL if DeviceNode is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+UefiDevicePathLibConvertDevicePathToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,

+  IN BOOLEAN                          DisplayOnly,

+  IN BOOLEAN                          AllowShortcuts

+  )

+{

+  POOL_PRINT               Str;

+  EFI_DEVICE_PATH_PROTOCOL *Node;

+  EFI_DEVICE_PATH_PROTOCOL *AlignedNode;

+  UINTN                    Index;

+  DEVICE_PATH_TO_TEXT      ToText;

+

+  if (DevicePath == NULL) {

+    return NULL;

+  }

+

+  ZeroMem (&Str, sizeof (Str));

+

+  //

+  // Process each device path node

+  //

+  Node = (EFI_DEVICE_PATH_PROTOCOL *) DevicePath;

+  while (!IsDevicePathEnd (Node)) {

+    //

+    // Find the handler to dump this device path node

+    // If not found, use a generic function

+    //

+    ToText = DevPathToTextNodeUnknown;

+    for (Index = 0; mUefiDevicePathLibDevPathToTextTable[Index].Function != NULL; Index += 1) {

+

+      if (DevicePathType (Node) == mUefiDevicePathLibDevPathToTextTable[Index].Type &&

+          DevicePathSubType (Node) == mUefiDevicePathLibDevPathToTextTable[Index].SubType

+          ) {

+        ToText = mUefiDevicePathLibDevPathToTextTable[Index].Function;

+        break;

+      }

+    }

+    //

+    //  Put a path separator in if needed

+    //

+    if ((Str.Count != 0) && (ToText != DevPathToTextEndInstance)) {

+      if (Str.Str[Str.Count] != L',') {

+        UefiDevicePathLibCatPrint (&Str, L"/");

+      }

+    }

+    

+    AlignedNode = AllocateCopyPool (DevicePathNodeLength (Node), Node);

+    //

+    // Print this node of the device path

+    //

+    ToText (&Str, AlignedNode, DisplayOnly, AllowShortcuts);

+    FreePool (AlignedNode);

+    

+    //

+    // Next device path node

+    //

+    Node = NextDevicePathNode (Node);

+  }

+

+  if (Str.Str == NULL) {

+    return AllocateZeroPool (sizeof (CHAR16));

+  } else {

+    return Str.Str;

+  }

+}

diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c b/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c
new file mode 100644
index 0000000..b48bf02
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c
@@ -0,0 +1,882 @@
+/** @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) 2006 - 2013, 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"

+

+//

+// Template for an end-of-device path node.

+//

+GLOBAL_REMOVE_IF_UNREFERENCED 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

+EFIAPI

+IsDevicePathValid (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,

+  IN       UINTN                    MaxSize

+  )

+{

+  UINTN Count;

+  UINTN Size;

+  UINTN NodeLength;

+

+  ASSERT (DevicePath != NULL);

+

+  for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {

+    NodeLength = DevicePathNodeLength (DevicePath);

+    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {

+      return FALSE;

+    }

+

+    if (MaxSize > 0) {

+      Size += NodeLength;

+      if (Size + END_DEVICE_PATH_LENGTH > MaxSize) {

+        return FALSE;

+      }

+    }

+

+    if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {

+      Count++;

+      if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {

+        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

+EFIAPI

+DevicePathType (

+  IN 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

+EFIAPI

+DevicePathSubType (

+  IN 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

+EFIAPI

+DevicePathNodeLength (

+  IN CONST VOID  *Node

+  )

+{

+  UINTN Length;

+

+  ASSERT (Node != NULL);

+  Length = ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);

+  ASSERT (Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL));

+  return Length;

+}

+

+/**

+  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 *

+EFIAPI

+NextDevicePathNode (

+  IN 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

+EFIAPI

+IsDevicePathEndType (

+  IN 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

+EFIAPI

+IsDevicePathEnd (

+  IN 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

+EFIAPI

+IsDevicePathEndInstance (

+  IN 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

+EFIAPI

+SetDevicePathNodeLength (

+  IN OUT VOID  *Node,

+  IN 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

+EFIAPI

+SetDevicePathEndNode (

+  OUT VOID  *Node

+  )

+{

+  ASSERT (Node != NULL);

+  CopyMem (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

+EFIAPI

+UefiDevicePathLibGetDevicePathSize (

+  IN 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 *

+EFIAPI

+UefiDevicePathLibDuplicateDevicePath (

+  IN 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 *

+EFIAPI

+UefiDevicePathLibAppendDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL

+  )

+{

+  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 = CopyMem (NewDevicePath, FirstDevicePath, Size1);

+    //

+    // Over write FirstDevicePath EndNode and do the copy

+    //

+    DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath +

+                  (Size1 - END_DEVICE_PATH_LENGTH));

+    CopyMem (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 *

+EFIAPI

+UefiDevicePathLibAppendDevicePathNode (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL

+  )

+{

+  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 = CopyMem (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);

+

+  FreePool (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 *

+EFIAPI

+UefiDevicePathLibAppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL

+  )

+{

+  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 = CopyMem (NewDevicePath, DevicePath, SrcSize);;

+ 

+    while (!IsDevicePathEnd (TempDevicePath)) {

+      TempDevicePath = NextDevicePathNode (TempDevicePath);

+    }

+    

+    TempDevicePath->SubType  = END_INSTANCE_DEVICE_PATH_SUBTYPE;

+    TempDevicePath           = NextDevicePathNode (TempDevicePath);

+    CopyMem (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 *

+EFIAPI

+UefiDevicePathLibGetNextDevicePathInstance (

+  IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,

+  OUT 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 *

+EFIAPI

+UefiDevicePathLibCreateDeviceNode (

+  IN UINT8                           NodeType,

+  IN UINT8                           NodeSubType,

+  IN 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

+EFIAPI

+UefiDevicePathLibIsDevicePathMultiInstance (

+  IN 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 *

+EFIAPI

+DevicePathFromHandle (

+  IN 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 *

+EFIAPI

+FileDevicePath (

+  IN EFI_HANDLE                      Device,     OPTIONAL

+  IN 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;

+    CopyMem (&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);

+    FreePool (FileDevicePath);

+  }

+

+  return DevicePath;

+}

+

diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
index a91a7a3..baad7bc 100644
--- a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
@@ -8,7 +8,7 @@
   environment varibles. Multi-instance device paths should never be placed

   on a Handle.

 

-  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>

+  Copyright (c) 2006 - 2013, 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        

@@ -20,319 +20,7 @@
 **/

 

 

-#include <Uefi.h>

-

-#include <Library/DevicePathLib.h>

-#include <Library/BaseMemoryLib.h>

-#include <Library/DebugLib.h>

-#include <Library/MemoryAllocationLib.h>

-#include <Library/UefiBootServicesTableLib.h>

-#include <Library/BaseLib.h>

-#include <Library/PcdLib.h>

-

-//

-// Template for an end-of-device path node.

-//

-GLOBAL_REMOVE_IF_UNREFERENCED 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

-EFIAPI

-IsDevicePathValid (

-  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,

-  IN       UINTN                    MaxSize

-  )

-{

-  UINTN Count;

-  UINTN Size;

-  UINTN NodeLength;

-

-  ASSERT (DevicePath != NULL);

-

-  for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {

-    NodeLength = DevicePathNodeLength (DevicePath);

-    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {

-      return FALSE;

-    }

-

-    if (MaxSize > 0) {

-      Size += NodeLength;

-      if (Size + END_DEVICE_PATH_LENGTH > MaxSize) {

-        return FALSE;

-      }

-    }

-

-    if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {

-      Count++;

-      if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {

-        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

-EFIAPI

-DevicePathType (

-  IN 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

-EFIAPI

-DevicePathSubType (

-  IN 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

-EFIAPI

-DevicePathNodeLength (

-  IN CONST VOID  *Node

-  )

-{

-  UINTN Length;

-

-  ASSERT (Node != NULL);

-  Length = ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);

-  ASSERT (Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL));

-  return Length;

-}

-

-/**

-  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 *

-EFIAPI

-NextDevicePathNode (

-  IN 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

-EFIAPI

-IsDevicePathEndType (

-  IN 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

-EFIAPI

-IsDevicePathEnd (

-  IN 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

-EFIAPI

-IsDevicePathEndInstance (

-  IN 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

-EFIAPI

-SetDevicePathNodeLength (

-  IN OUT VOID  *Node,

-  IN 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

-EFIAPI

-SetDevicePathEndNode (

-  OUT VOID  *Node

-  )

-{

-  ASSERT (Node != NULL);

-  CopyMem (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));

-}

+#include "UefiDevicePathLib.h"

 

 /**

   Returns the size of a device path in bytes.

@@ -353,28 +41,7 @@
   IN 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);

+  return UefiDevicePathLibGetDevicePathSize (DevicePath);

 }

 

 /**

@@ -399,21 +66,7 @@
   IN 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);

+  return UefiDevicePathLibDuplicateDevicePath (DevicePath);

 }

 

 /**

@@ -447,48 +100,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL

   )

 {

-  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 = CopyMem (NewDevicePath, FirstDevicePath, Size1);

-    //

-    // Over write FirstDevicePath EndNode and do the copy

-    //

-    DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath +

-                  (Size1 - END_DEVICE_PATH_LENGTH));

-    CopyMem (DevicePath2, SecondDevicePath, Size2);

-  }

-

-  return NewDevicePath;

+  return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);

 }

 

 /**

@@ -526,37 +138,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL

   )

 {

-  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 = CopyMem (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);

-

-  FreePool (TempDevicePath);

-

-  return NewDevicePath;

+  return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);

 }

 

 /**

@@ -589,41 +171,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL

   )

 {

-  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 = CopyMem (NewDevicePath, DevicePath, SrcSize);;

- 

-    while (!IsDevicePathEnd (TempDevicePath)) {

-      TempDevicePath = NextDevicePathNode (TempDevicePath);

-    }

-    

-    TempDevicePath->SubType  = END_INSTANCE_DEVICE_PATH_SUBTYPE;

-    TempDevicePath           = NextDevicePathNode (TempDevicePath);

-    CopyMem (TempDevicePath, DevicePathInstance, InstanceSize);

-  }

-

-  return NewDevicePath;

+  return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);

 }

 

 /**

@@ -661,53 +209,7 @@
   OUT 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;

+  return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);

 }

 

 /**

@@ -737,23 +239,7 @@
   IN 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;

+  return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength);

 }

 

 /**

@@ -777,115 +263,98 @@
   IN 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;

+  return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);

 }

 

+/**

+  Converts a device node to its string representation.

+

+  @param DeviceNode        A Pointer to the device node to be converted.

+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation

+                           of the display node is used, where applicable. If DisplayOnly

+                           is FALSE, then the longer text representation of the display node

+                           is used.

+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text

+                           representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode

+          is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+ConvertDeviceNodeToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,

+  IN BOOLEAN                         DisplayOnly,

+  IN BOOLEAN                         AllowShortcuts

+  )

+{

+  return UefiDevicePathLibConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);

+}

 

 /**

-  Retrieves the device path protocol from a handle.

+  Converts a device path to its text representation.

 

-  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.

+  @param DevicePath      A Pointer to the device to be converted.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

 

-  @return The device path protocol from the handle specified by Handle.

+  @return A pointer to the allocated text representation of the device path or

+          NULL if DeviceNode is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+ConvertDevicePathToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,

+  IN BOOLEAN                          DisplayOnly,

+  IN BOOLEAN                          AllowShortcuts

+  )

+{

+  return UefiDevicePathLibConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);

+}

+

+/**

+  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 *

 EFIAPI

-DevicePathFromHandle (

-  IN EFI_HANDLE                      Handle

+ConvertTextToDeviceNode (

+  IN CONST CHAR16 *TextDeviceNode

   )

 {

-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

-  EFI_STATUS                Status;

-

-  Status = gBS->HandleProtocol (

-                  Handle,

-                  &gEfiDevicePathProtocolGuid,

-                  (VOID *) &DevicePath

-                  );

-  if (EFI_ERROR (Status)) {

-    DevicePath = NULL;

-  }

-  return DevicePath;

+  return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);

 }

 

 /**

-  Allocates a device path for a file and appends it to an existing device path.

+  Convert text to the binary representation of a 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.

+  @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 The allocated device path.

+  @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or

+          there was insufficient memory.

 

 **/

 EFI_DEVICE_PATH_PROTOCOL *

 EFIAPI

-FileDevicePath (

-  IN EFI_HANDLE                      Device,     OPTIONAL

-  IN CONST CHAR16                    *FileName

+ConvertTextToDevicePath (

+  IN CONST CHAR16 *TextDevicePath

   )

 {

-  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;

-    CopyMem (&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);

-    FreePool (FileDevicePath);

-  }

-

-  return DevicePath;

+  return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);

 }

-

diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
new file mode 100644
index 0000000..a7ed531
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
@@ -0,0 +1,451 @@
+/** @file

+  Definition for Device Path library.

+

+Copyright (c) 2013, 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 <Uefi.h>

+#include <Protocol/DevicePathUtilities.h>

+#include <Protocol/DebugPort.h>

+#include <Protocol/DevicePathToText.h>

+#include <Protocol/DevicePathFromText.h>

+#include <Guid/PcAnsi.h>

+#include <Library/DebugLib.h>

+#include <Library/PrintLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/PcdLib.h>

+

+#define IS_COMMA(a)                ((a) == L',')

+#define IS_HYPHEN(a)               ((a) == L'-')

+#define IS_DOT(a)                  ((a) == L'.')

+#define IS_LEFT_PARENTH(a)         ((a) == L'(')

+#define IS_RIGHT_PARENTH(a)        ((a) == L')')

+#define IS_SLASH(a)                ((a) == L'/')

+#define IS_NULL(a)                 ((a) == L'\0')

+

+

+//

+// Private Data structure

+//

+typedef struct {

+  CHAR16  *Str;

+  UINTN   Count;

+  UINTN   Capacity;

+} POOL_PRINT;

+

+typedef

+EFI_DEVICE_PATH_PROTOCOL  *

+(*DEVICE_PATH_FROM_TEXT) (

+  IN  CHAR16 *Str

+  );

+

+typedef

+VOID

+(*DEVICE_PATH_TO_TEXT) (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevicePath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  );

+

+typedef struct {

+  UINT8                Type;

+  UINT8                SubType;

+  DEVICE_PATH_TO_TEXT  Function;

+} DEVICE_PATH_TO_TEXT_TABLE;

+

+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

+EFIAPI

+UefiDevicePathLibGetDevicePathSize (

+  IN 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 *

+EFIAPI

+UefiDevicePathLibDuplicateDevicePath (

+  IN 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 *

+EFIAPI

+UefiDevicePathLibAppendDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL

+  IN 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 *

+EFIAPI

+UefiDevicePathLibAppendDevicePathNode (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL

+  IN 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 *

+EFIAPI

+UefiDevicePathLibAppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL

+  IN 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 *

+EFIAPI

+UefiDevicePathLibGetNextDevicePathInstance (

+  IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,

+  OUT 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 *

+EFIAPI

+UefiDevicePathLibCreateDeviceNode (

+  IN UINT8                           NodeType,

+  IN UINT8                           NodeSubType,

+  IN 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

+EFIAPI

+UefiDevicePathLibIsDevicePathMultiInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  );

+

+

+/**

+  Converts a device path to its text representation.

+

+  @param DevicePath      A Pointer to the device to be converted.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device path or

+          NULL if DeviceNode is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+UefiDevicePathLibConvertDevicePathToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,

+  IN BOOLEAN                          DisplayOnly,

+  IN BOOLEAN                          AllowShortcuts

+  );

+

+/**

+  Converts a device node to its string representation.

+

+  @param DeviceNode        A Pointer to the device node to be converted.

+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation

+                           of the display node is used, where applicable. If DisplayOnly

+                           is FALSE, then the longer text representation of the display node

+                           is used.

+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text

+                           representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode

+          is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+UefiDevicePathLibConvertDeviceNodeToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,

+  IN BOOLEAN                         DisplayOnly,

+  IN BOOLEAN                         AllowShortcuts

+  );

+

+/**

+  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 *

+EFIAPI

+UefiDevicePathLibConvertTextToDeviceNode (

+  IN 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 *

+EFIAPI

+UefiDevicePathLibConvertTextToDevicePath (

+  IN CONST CHAR16 *TextDevicePath

+  );

+

+#endif

diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
index 2ae151d..fc9b5c0 100644
--- a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
@@ -3,7 +3,7 @@
 #

 # Device Path Library that layers on top of the Memory Allocation Library.

 #

-# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>

+# Copyright (c) 2007 - 2013, 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

@@ -29,8 +29,11 @@
 #

 

 [Sources]

+  DevicePathUtilities.c

+  DevicePathToText.c

+  DevicePathFromText.c

   UefiDevicePathLib.c

-

+  UefiDevicePathLib.h

 

 [Packages]

   MdePkg/MdePkg.dec

@@ -38,14 +41,23 @@
 

 [LibraryClasses]

   BaseLib

-  UefiBootServicesTableLib

   MemoryAllocationLib

   DebugLib

   BaseMemoryLib

   PcdLib

+  PrintLib

+

+[Guids]

+  gEfiVTUTF8Guid

+  gEfiVT100Guid

+  gEfiVT100PlusGuid

+  gEfiPcAnsiGuid

+  gEfiUartDevicePathGuid

+  gEfiSasDevicePathGuid

 

 [Protocols]

   gEfiDevicePathProtocolGuid                    ## CONSUMES

+  gEfiDebugPortProtocolGuid                     ## SOMETIMES_CONSUMES ## GUID

 

 [Pcd]

   gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount

diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c
new file mode 100644
index 0000000..9580e39
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c
@@ -0,0 +1,484 @@
+/** @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) 2013, 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"

+

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathLibDevicePathUtilities = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   *mDevicePathLibDevicePathToText    = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mDevicePathLibDevicePathFromText  = NULL;

+

+/**

+  The constructor function caches the pointer to DevicePathUtilites protocol,

+  DevicePathToText protocol and DevicePathFromText protocol.

+  

+  The constructor function locates these three protocols from protocol database.

+  It will caches the pointer to local protocol instance if that operation fails

+  and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiDevicePathLibOptionalDevicePathProtocolConstructor (

+  IN      EFI_HANDLE                ImageHandle,

+  IN      EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = gBS->LocateProtocol (

+                  &gEfiDevicePathUtilitiesProtocolGuid,

+                  NULL,

+                  (VOID**) &mDevicePathLibDevicePathUtilities

+                  );

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mDevicePathLibDevicePathUtilities != NULL);

+  return Status;

+}

+

+/**

+  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

+EFIAPI

+GetDevicePathSize (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->GetDevicePathSize (DevicePath);

+  } else {

+    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 *

+EFIAPI

+DuplicateDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->DuplicateDevicePath (DevicePath);

+  } else {

+    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 *

+EFIAPI

+AppendDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);

+  } else {

+    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 *

+EFIAPI

+AppendDevicePathNode (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);

+  } else {

+    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 *

+EFIAPI

+AppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);

+  } else {

+    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 *

+EFIAPI

+GetNextDevicePathInstance (

+  IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,

+  OUT UINTN                          *Size

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);

+  } else {

+    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 *

+EFIAPI

+CreateDeviceNode (

+  IN UINT8                           NodeType,

+  IN UINT8                           NodeSubType,

+  IN UINT16                          NodeLength

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);

+  } else {

+    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

+EFIAPI

+IsDevicePathMultiInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);

+  } else {

+    return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);

+  }

+}

+

+/**

+  Locate and return the protocol instance identified by the ProtocolGuid.

+

+  @param ProtocolGuid     The GUID of the protocol.

+

+  @return A pointer to the protocol instance or NULL when absent.

+**/

+VOID *

+UefiDevicePathLibLocateProtocol (

+  EFI_GUID                         *ProtocolGuid

+  )

+{

+  EFI_STATUS Status;

+  VOID       *Protocol;

+  Status = gBS->LocateProtocol (

+                  ProtocolGuid,

+                  NULL,

+                  (VOID**) &Protocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  } else {

+    return Protocol;

+  }

+}

+

+/**

+  Converts a device node to its string representation.

+

+  @param DeviceNode        A Pointer to the device node to be converted.

+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation

+                           of the display node is used, where applicable. If DisplayOnly

+                           is FALSE, then the longer text representation of the display node

+                           is used.

+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text

+                           representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode

+          is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+ConvertDeviceNodeToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,

+  IN BOOLEAN                         DisplayOnly,

+  IN BOOLEAN                         AllowShortcuts

+  )

+{

+  if (mDevicePathLibDevicePathToText == NULL) {

+    mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathToText != NULL) {

+    return mDevicePathLibDevicePathToText->ConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);

+  }

+

+  return UefiDevicePathLibConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);

+}

+

+/**

+  Converts a device path to its text representation.

+

+  @param DevicePath      A Pointer to the device to be converted.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device path or

+          NULL if DeviceNode is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+ConvertDevicePathToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,

+  IN BOOLEAN                          DisplayOnly,

+  IN BOOLEAN                          AllowShortcuts

+  )

+{

+  if (mDevicePathLibDevicePathToText == NULL) {

+    mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathToText != NULL) {

+    return mDevicePathLibDevicePathToText->ConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);

+  }

+

+  return UefiDevicePathLibConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);

+}

+

+/**

+  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 *

+EFIAPI

+ConvertTextToDeviceNode (

+  IN CONST CHAR16 *TextDeviceNode

+  )

+{

+  if (mDevicePathLibDevicePathFromText == NULL) {

+    mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathFromText != NULL) {

+    return mDevicePathLibDevicePathFromText->ConvertTextToDeviceNode (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 *

+EFIAPI

+ConvertTextToDevicePath (

+  IN CONST CHAR16 *TextDevicePath

+  )

+{

+  if (mDevicePathLibDevicePathFromText == NULL) {

+    mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathFromText != NULL) {

+    return mDevicePathLibDevicePathFromText->ConvertTextToDevicePath (TextDevicePath);

+  }

+

+  return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);

+}

+

diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf
new file mode 100644
index 0000000..34bc120
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf
@@ -0,0 +1,73 @@
+## @file

+# Instance of Device Path Library based on Device Path Protocol.

+#

+#  Device Path Library that layers on top of the UEFI 2.0 Device Path Protocol.

+#  If the DevicePathFromText/DevicePathToText protocol doesn't exist, the library

+#  uses its internal conversion logic.

+#

+# Copyright (c) 2013, 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.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiDevicePathLibOptionalDevicePathProtocol

+  FILE_GUID                      = 3E1C696D-FCF0-45a7-85A7-E86C2A1C1080

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DevicePathLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+

+  CONSTRUCTOR                    = UefiDevicePathLibOptionalDevicePathProtocolConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DevicePathUtilities.c

+  DevicePathToText.c

+  DevicePathFromText.c

+  UefiDevicePathLibOptionalDevicePathProtocol.c

+  UefiDevicePathLib.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  UefiBootServicesTableLib

+  MemoryAllocationLib

+  DebugLib

+  BaseMemoryLib

+  PcdLib

+  PrintLib

+

+[Guids]

+  gEfiVTUTF8Guid

+  gEfiVT100Guid

+  gEfiVT100PlusGuid

+  gEfiPcAnsiGuid

+  gEfiUartDevicePathGuid

+  gEfiSasDevicePathGuid

+

+[Protocols]

+  gEfiDevicePathProtocolGuid                    ## CONSUMES

+  gEfiDevicePathUtilitiesProtocolGuid           ## CONSUMES

+  gEfiDevicePathToTextProtocolGuid              ## CONSUMES

+  gEfiDevicePathFromTextProtocolGuid            ## CONSUMES

+  gEfiDebugPortProtocolGuid                     ## SOMETIMES_CONSUMES ## GUID

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount

+

+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]

+  gEfiDevicePathUtilitiesProtocolGuid
\ No newline at end of file
diff --git a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
index 1052988..b73bcce 100644
--- a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
+++ b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
@@ -2,7 +2,7 @@
   Library instance that implement UEFI Device Path Library class based on protocol

   gEfiDevicePathUtilitiesProtocolGuid.

 

-  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>

+  Copyright (c) 2006 - 2013, 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

@@ -17,6 +17,8 @@
 #include <Uefi.h>

 

 #include <Protocol/DevicePathUtilities.h>

+#include <Protocol/DevicePathToText.h>

+#include <Protocol/DevicePathFromText.h>

 

 #include <Library/DevicePathLib.h>

 #include <Library/DebugLib.h>

@@ -26,7 +28,9 @@
 #include <Library/UefiBootServicesTableLib.h>

 #include <Library/PcdLib.h>

 

-EFI_DEVICE_PATH_UTILITIES_PROTOCOL          *mDevicePathUtilities = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathLibDevicePathUtilities = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   *mDevicePathLibDevicePathToText    = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mDevicePathLibDevicePathFromText  = NULL;

 

 //

 // Template for an end-of-device path node.

@@ -64,11 +68,10 @@
   Status = gBS->LocateProtocol (

                   &gEfiDevicePathUtilitiesProtocolGuid,

                   NULL,

-                  (VOID**) &mDevicePathUtilities

+                  (VOID**) &mDevicePathLibDevicePathUtilities

                   );

   ASSERT_EFI_ERROR (Status);

-  ASSERT (mDevicePathUtilities != NULL);

-

+  ASSERT (mDevicePathLibDevicePathUtilities != NULL);

   return Status;

 }

 

@@ -382,7 +385,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

   )

 {

-  return mDevicePathUtilities->GetDevicePathSize (DevicePath);

+  return mDevicePathLibDevicePathUtilities->GetDevicePathSize (DevicePath);

 }

 

 /**

@@ -408,7 +411,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

   )

 {

-  return mDevicePathUtilities->DuplicateDevicePath (DevicePath);

+  return mDevicePathLibDevicePathUtilities->DuplicateDevicePath (DevicePath);

 }

 

 /**

@@ -442,7 +445,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL

   )

 {

-  return mDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);

+  return mDevicePathLibDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);

 }

 

 /**

@@ -480,7 +483,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL

   )

 {

-  return mDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);

+  return mDevicePathLibDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);

 }

 

 /**

@@ -513,7 +516,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL

   )

 {

-  return mDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);

+  return mDevicePathLibDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);

 }

 

 /**

@@ -551,7 +554,7 @@
   )

 {

   ASSERT (Size != NULL);

-  return mDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);

+  return mDevicePathLibDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);

 }

 

 /**

@@ -582,7 +585,7 @@
   IN UINT16                          NodeLength

   )

 {

-  return mDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);

+  return mDevicePathLibDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);

 }

 

 /**

@@ -606,7 +609,7 @@
   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

   )

 {

-  return mDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);

+  return mDevicePathLibDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);

 }

 

 /**

@@ -698,3 +701,151 @@
 

   return DevicePath;

 }

+

+/**

+  Locate and return the protocol instance identified by the ProtocolGuid.

+

+  @param ProtocolGuid     The GUID of the protocol.

+

+  @return A pointer to the protocol instance or NULL when absent.

+**/

+VOID *

+UefiDevicePathLibLocateProtocol (

+  EFI_GUID                         *ProtocolGuid

+  )

+{

+  EFI_STATUS Status;

+  VOID       *Protocol;

+  Status = gBS->LocateProtocol (

+                  ProtocolGuid,

+                  NULL,

+                  (VOID**) &Protocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  } else {

+    return Protocol;

+  }

+}

+

+/**

+  Converts a device node to its string representation.

+

+  @param DeviceNode        A Pointer to the device node to be converted.

+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation

+                           of the display node is used, where applicable. If DisplayOnly

+                           is FALSE, then the longer text representation of the display node

+                           is used.

+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text

+                           representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode

+          is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+ConvertDeviceNodeToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,

+  IN BOOLEAN                         DisplayOnly,

+  IN BOOLEAN                         AllowShortcuts

+  )

+{

+  if (mDevicePathLibDevicePathToText == NULL) {

+    mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathToText != NULL) {

+    return mDevicePathLibDevicePathToText->ConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);

+  } else {

+    return NULL;

+  }

+}

+

+/**

+  Converts a device path to its text representation.

+

+  @param DevicePath      A Pointer to the device to be converted.

+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+  @return A pointer to the allocated text representation of the device path or

+          NULL if DeviceNode is NULL or there was insufficient memory.

+

+**/

+CHAR16 *

+EFIAPI

+ConvertDevicePathToText (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,

+  IN BOOLEAN                          DisplayOnly,

+  IN BOOLEAN                          AllowShortcuts

+  )

+{

+  if (mDevicePathLibDevicePathToText == NULL) {

+    mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathToText != NULL) {

+    return mDevicePathLibDevicePathToText->ConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);

+  } else {

+    return 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 *

+EFIAPI

+ConvertTextToDeviceNode (

+  IN CONST CHAR16 *TextDeviceNode

+  )

+{

+  if (mDevicePathLibDevicePathFromText == NULL) {

+    mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathFromText != NULL) {

+    return mDevicePathLibDevicePathFromText->ConvertTextToDeviceNode (TextDeviceNode);

+  } else {

+    return NULL;

+  }

+}

+

+/**

+  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 *

+EFIAPI

+ConvertTextToDevicePath (

+  IN CONST CHAR16 *TextDevicePath

+  )

+{

+  if (mDevicePathLibDevicePathFromText == NULL) {

+    mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathFromText != NULL) {

+    return mDevicePathLibDevicePathFromText->ConvertTextToDevicePath (TextDevicePath);

+  } else {

+    return NULL;

+  }

+}

+

diff --git a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
index 16b47e3..48ae8d0 100644
--- a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+++ b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
@@ -22,7 +22,7 @@
   FILE_GUID                      = 050EB8C6-C12E-4b86-892B-40985E8B3137

   MODULE_TYPE                    = UEFI_DRIVER

   VERSION_STRING                 = 1.0

-  LIBRARY_CLASS                  = DevicePathLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER 

+  LIBRARY_CLASS                  = DevicePathLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

 

   CONSTRUCTOR                    = DevicePathLibConstructor

 

@@ -49,6 +49,8 @@
 [Protocols]

   gEfiDevicePathProtocolGuid                    ## CONSUMES

   gEfiDevicePathUtilitiesProtocolGuid           ## CONSUMES

+  gEfiDevicePathToTextProtocolGuid              ## CONSUMES

+  gEfiDevicePathFromTextProtocolGuid            ## CONSUMES

 

 [Pcd]

   gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount

diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index 0fd6fcb..092a67d 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -1,7 +1,7 @@
 ## @file

 # EFI/PI MdePkg Package

 #

-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>

+# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>

 # Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

 #

 #    This program and the accompanying materials

@@ -113,6 +113,7 @@
   MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf

   MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf

   MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf

+  MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf

   MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf

   MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf

   MdePkg/Library/UefiLib/UefiLib.inf