summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/DevicePath
diff options
context:
space:
mode:
authorljin6 <ljin6@6f19259b-4bc3-4df7-8a09-765794883524>2006-07-18 04:13:40 +0000
committerljin6 <ljin6@6f19259b-4bc3-4df7-8a09-765794883524>2006-07-18 04:13:40 +0000
commit562d28495df348923812281161e64bc9514e15e6 (patch)
tree121f4f3c37c23b23a4dabe21cf4fc46c78a0c5b3 /EdkModulePkg/Universal/DevicePath
parent4b9fc76f7bba0d847d36cb2070a2d3305ae87acc (diff)
downloadedk2-platforms-562d28495df348923812281161e64bc9514e15e6.tar.xz
Add DevicePathUtilities DevicePathToText DevciePathFromText USB2HostController protocols
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1037 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Universal/DevicePath')
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c107
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h422
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa109
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c2434
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c1526
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c421
6 files changed, 5019 insertions, 0 deletions
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c
new file mode 100644
index 0000000000..79741a4615
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c
@@ -0,0 +1,107 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+ DevicePathDriver.c
+
+Abstract:
+
+ Device Path Driver to produce DevPathUtilities Protocol, DevPathFromText Protocol
+ and DevPathToText Protocol.
+
+--*/
+
+#include <Uefi/UefiSpec.h>
+#include <Protocol/DevicePath.h>
+#include "DevicePath.h"
+
+DEVICE_PATH_DRIVER_PRIVATE_DATA mPrivateData;
+
+EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid = DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL;
+EFI_GUID mEfiDevicePathMessagingSASGuid = DEVICE_PATH_MESSAGING_SAS;
+
+STATIC EFI_DEVICE_PATH_UTILITIES_PROTOCOL mDevicePathUtilitiesProtocol = {
+ GetDevicePathSize,
+ DuplicateDevicePath,
+ AppendDevicePath,
+ AppendDeviceNode,
+ AppendDevicePathInstance,
+ GetNextDevicePathInstance,
+ IsDevicePathMultiInstance,
+ CreateDeviceNode
+};
+
+STATIC EFI_DEVICE_PATH_TO_TEXT_PROTOCOL mDevicePathToTextProtocol = {
+ ConvertDeviceNodeToText,
+ ConvertDevicePathToText
+};
+
+STATIC EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL mDevicePathFromTextProtocol = {
+ ConvertTextToDeviceNode,
+ ConvertTextToDevicePath
+};
+
+EFI_STATUS
+EFIAPI
+DevicePathEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+ Entry point for EFI drivers.
+
+ Arguments:
+ ImageHandle - EFI_HANDLE
+ SystemTable - EFI_SYSTEM_TABLE
+
+ Returns:
+ EFI_SUCCESS
+ others
+
+--*/
+{
+ EFI_STATUS Status;
+
+ mPrivateData.Signature = DEVICE_PATH_DRIVER_SIGNATURE;
+
+ mPrivateData.DevicePathUtilities.GetDevicePathSize = GetDevicePathSize;
+ mPrivateData.DevicePathUtilities.DuplicateDevicePath = DuplicateDevicePath;
+ mPrivateData.DevicePathUtilities.AppendDevicePath = AppendDevicePath;
+ mPrivateData.DevicePathUtilities.AppendDeviceNode = AppendDeviceNode;
+ mPrivateData.DevicePathUtilities.AppendDevicePathInstance = AppendDevicePathInstance;
+ mPrivateData.DevicePathUtilities.GetNextDevicePathInstance = GetNextDevicePathInstance;
+ mPrivateData.DevicePathUtilities.IsDevicePathMultiInstance = IsDevicePathMultiInstance;
+ mPrivateData.DevicePathUtilities.CreateDeviceNode = CreateDeviceNode;
+
+ mPrivateData.DevicePathToText.ConvertDeviceNodeToText = ConvertDeviceNodeToText;
+ mPrivateData.DevicePathToText.ConvertDevicePathToText = ConvertDevicePathToText;
+
+ mPrivateData.DevicePathFromText.ConvertTextToDeviceNode = ConvertTextToDeviceNode;
+ mPrivateData.DevicePathFromText.ConvertTextToDevicePath = ConvertTextToDevicePath;
+
+ mPrivateData.Handle = NULL;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPrivateData.Handle,
+ &gEfiDevicePathUtilitiesProtocolGuid,
+ &mPrivateData.DevicePathUtilities,
+ &gEfiDevicePathToTextProtocolGuid,
+ &mPrivateData.DevicePathToText,
+ &gEfiDevicePathFromTextProtocolGuid,
+ &mPrivateData.DevicePathFromText,
+ NULL
+ );
+
+ return Status;
+}
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h
new file mode 100644
index 0000000000..aa333453ea
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h
@@ -0,0 +1,422 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+ DevicePathDriver.h
+
+Abstract:
+ Definition for Device Path Utilities driver
+
+--*/
+
+#ifndef _DEVICE_PATH_DRIVER_H
+#define _DEVICE_PATH_DRIVER_H
+
+extern EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid;
+extern EFI_GUID mEfiDevicePathMessagingSASGuid;
+
+#define DEVICE_PATH_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('D', 'P', 'D', 'V')
+
+typedef struct {
+
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ //
+ // Produced protocols
+ //
+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL DevicePathUtilities;
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL DevicePathFromText;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL DevicePathToText;
+
+} DEVICE_PATH_DRIVER_PRIVATE_DATA;
+
+#define MAX_CHAR 480
+
+#define MIN_ALIGNMENT_SIZE sizeof(UINTN)
+#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
+
+#define IS_COMMA(a) ((a) == L',')
+#define IS_HYPHEN(a) ((a) == L'-')
+#define IS_DOT(a) ((a) == L'.')
+#define IS_LEFT_PARENTH(a) ((a) == L'(')
+#define IS_RIGHT_PARENTH(a) ((a) == L')')
+#define IS_SLASH(a) ((a) == L'/')
+#define IS_NULL(a) ((a) == L'\0')
+
+#define DEVICE_NODE_END 1
+#define DEVICE_PATH_INSTANCE_END 2
+#define DEVICE_PATH_END 3
+
+#define SetDevicePathInstanceEndNode(a) { \
+ (a)->Type = END_DEVICE_PATH_TYPE; \
+ (a)->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; \
+ (a)->Length[0] = sizeof (EFI_DEVICE_PATH_PROTOCOL); \
+ (a)->Length[1] = 0; \
+ }
+
+//
+// Private Data structure
+//
+typedef struct {
+ CHAR16 *Str;
+ UINTN Len;
+ UINTN MaxLen;
+} POOL_PRINT;
+
+typedef struct {
+ UINT8 Type;
+ UINT8 SubType;
+ VOID (*Function) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+} DEVICE_PATH_TO_TEXT_TABLE;
+
+typedef struct {
+ CHAR16 *DevicePathNodeText;
+ EFI_DEVICE_PATH_PROTOCOL * (*Function) (CHAR16 *);
+} 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
+
+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;
+ UINT16 Reserved;
+ UINT16 TargetPortalGroupTag;
+ UINT64 Lun;
+ CHAR16 iSCSITargetName[1];
+} ISCSI_DEVICE_PATH_WITH_NAME;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEVICE_PATH_WITH_DATA;
+
+CHAR16 *
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device node to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device node to be converted.
+ 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.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device node.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+;
+
+CHAR16 *
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device path to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device path to be converted.
+ 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.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device path.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ )
+/*++
+
+ Routine Description:
+ Convert text to the binary representation of a device node.
+
+ Arguments:
+ 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.
+
+ Returns:
+ A pointer - Pointer to the EFI device node.
+ NULL - if TextDeviceNode is NULL or there was insufficient memory.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ )
+/*++
+
+ Routine Description:
+ Convert text to the binary representation of a device path.
+
+ Arguments:
+ 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.
+
+ Returns:
+ A pointer - Pointer to the allocated device path.
+ NULL - if TextDeviceNode is NULL or there was insufficient memory.
+
+--*/
+;
+
+UINTN
+GetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns the size of the device path, in bytes.
+
+ Arguments:
+ DevicePath - Points to the start of the EFI device path.
+
+ Returns:
+ Size - Size of the specified device path, in bytes, including the end-of-path tag.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Create a duplicate of the specified path.
+
+ Arguments:
+ DevicePath - Points to the source EFI device path.
+
+ Returns:
+ Pointer - A pointer to the duplicate device path.
+ NULL - Insufficient memory.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+ )
+/*++
+
+ Routine Description:
+ Create a new path by appending the second device path to the first.
+
+ Arguments:
+ Src1 - Points to the first device path. If NULL, then it is ignored.
+ Src2 - Points to the second device path. If NULL, then it is ignored.
+
+ Returns:
+ Pointer - A pointer to the newly created device path.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDeviceNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the device node to the device path.
+
+ Arguments:
+ DevicePath - Points to the device path.
+ DeviceNode - Points to the device node.
+
+ Returns:
+ Pointer - A pointer to the allocated device node.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the specified device path instance to the specified device path.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+ DevicePathInstance - Points to the device path instance.
+
+ Returns:
+ Pointer - A pointer to the newly created device path
+ NULL - Memory could not be allocated or DevicePathInstance is NULL.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
+ OUT UINTN *DevicePathInstanceSize
+ )
+/*++
+
+ Routine Description:
+ Creates a copy of the current device path instance and returns a pointer to the next device path instance.
+
+ Arguments:
+ DevicePathInstance - On input, this holds the pointer to the current device path
+ instance. On output, this holds the pointer to the next
+ device path instance or NULL if there are no more device
+ path instances in the device path.
+ DevicePathInstanceSize - On output, this holds the size of the device path instance,
+ in bytes or zero, if DevicePathInstance is zero.
+
+ Returns:
+ Pointer - A pointer to the copy of the current device path instance.
+ NULL - DevicePathInstace was NULL on entry or there was insufficient memory.
+
+--*/
+;
+
+BOOLEAN
+IsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns whether a device path is multi-instance.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+
+ Returns:
+ TRUE - The device path has more than one instance
+ FALSE - The device path is empty or contains only a single instance.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ )
+/*++
+
+ Routine Description:
+ Creates a device node
+
+ Arguments:
+ NodeType - NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+ the new device node.
+ NodeSubType - NodeSubType is the device node sub-type
+ EFI_DEVICE_PATH.SubType) for the new device node.
+ NodeLength - NodeLength is the length of the device node
+ (EFI_DEVICE_PATH.Length) for the new device node.
+
+ Returns:
+ Pointer - A pointer to the newly created device node.
+ NULL - NodeLength is less than
+ the size of the header or there was insufficient memory.
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa
new file mode 100644
index 0000000000..20dd59848f
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+
+ <MsaHeader>
+ <ModuleName>DevicePath</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>9B680FCE-AD6B-4F3A-B60B-F59899003443</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component description file for Device Path Driver.</Abstract>
+ <Description>This driver is for DevicePathUtilities, DevicePahtToText and DevicePathFromText</Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+ <License>All rights reserved. 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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>DevicePath</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PrintLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>DevicePath.c</Filename>
+ <Filename>DevicePath.h</Filename>
+ <Filename>DevicePathFromText.c</Filename>
+ <Filename>DevicePathToText.c</Filename>
+ <Filename>DevicePathUtilities.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiDebugPortProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiDevicePathUtilitiesProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiDevicePathFromTextProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiDevicePathToTextProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiPcAnsiGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiVT100PlusGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiVT100Guid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiVTUTF8Guid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00090000</Specification>
+ <Extern>
+ <ModuleEntryPoint>DevicePathEntryPoint</ModuleEntryPoint>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c
new file mode 100644
index 0000000000..e0864da6f0
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c
@@ -0,0 +1,2434 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+ DevicePathFromText.c
+
+Abstract:
+
+ DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+--*/
+
+#include <protocol/DevicePathFromText.h>
+#include "DevicePath.h"
+
+CHAR16 *
+StrDuplicate (
+ IN CONST CHAR16 *Src
+ )
+/*++
+
+ Routine Description:
+ Duplicate a string
+
+ Arguments:
+ Src - Source string
+
+ Returns:
+ Duplicated string
+
+--*/
+{
+ UINTN Length;
+ CHAR16 *ReturnStr;
+
+ Length = StrLen ((CHAR16 *) Src);
+
+ ReturnStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), (VOID *) Src);
+
+ return ReturnStr;
+}
+
+CHAR16 *
+GetParamByNodeName (
+ IN CHAR16 *Str,
+ IN CHAR16 *NodeName
+ )
+/*++
+
+ Routine Description:
+ 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".
+
+ Arguments:
+ Str - Device Path Text
+ NodeName - Name of the node
+
+ Returns:
+ Parameter text for the node
+
+--*/
+{
+ CHAR16 *ParamStr;
+ CHAR16 *StrPointer;
+ UINTN NodeNameLength;
+ UINTN ParameterLength;
+
+ //
+ // Check whether the node name matchs
+ //
+ NodeNameLength = StrLen (NodeName);
+ if (CompareMem (Str, NodeName, NodeNameLength * sizeof (CHAR16)) != 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;
+}
+
+CHAR16 *
+SplitStr (
+ IN OUT CHAR16 **List,
+ IN CHAR16 Separator
+ )
+/*++
+
+ Routine Description:
+ Get 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 "2,3"
+
+ Arguments:
+ List - A string list separated by the specified separator
+ Separator - The separator character
+
+ Returns:
+ pointer - The current sub-string
+
+--*/
+{
+ 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;
+}
+
+CHAR16 *
+GetNextParamStr (
+ IN OUT CHAR16 **List
+ )
+{
+ //
+ // The separator is comma
+ //
+ return SplitStr (List, L',');
+}
+
+CHAR16 *
+GetNextDeviceNodeStr (
+ IN OUT CHAR16 **DevicePath,
+ OUT BOOLEAN *IsInstanceEnd
+ )
+/*++
+
+ Routine Description:
+ Get one device node from entire device path text.
+
+ Arguments:
+ Str - The entire device path text string
+ IsInstanceEnd - This node is the end of a device path instance
+
+ Returns:
+ a pointer - A device node text
+ NULL - No more device node available
+
+--*/
+{
+ 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;
+}
+
+BOOLEAN
+IsHexDigit (
+ OUT UINT8 *Digit,
+ IN CHAR16 Char
+ )
+/*++
+
+ Routine Description:
+ Determines if a Unicode character is a hexadecimal digit.
+ The test is case insensitive.
+
+ Arguments:
+ Digit - Pointer to byte that receives the value of the hex character.
+ Char - Unicode character to test.
+
+ Returns:
+ TRUE - If the character is a hexadecimal digit.
+ FALSE - Otherwise.
+
+--*/
+{
+ if ((Char >= L'0') && (Char <= L'9')) {
+ *Digit = (UINT8) (Char - L'0');
+ return TRUE;
+ }
+
+ if ((Char >= L'A') && (Char <= L'F')) {
+ *Digit = (UINT8) (Char - L'A' + 0x0A);
+ return TRUE;
+ }
+
+ if ((Char >= L'a') && (Char <= L'f')) {
+ *Digit = (UINT8) (Char - L'a' + 0x0A);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+CHAR16
+NibbleToHexChar (
+ IN UINT8 Nibble
+ )
+/*++
+
+ Routine Description:
+ Converts the low nibble of a byte to hex unicode character.
+
+ Arguments:
+ Nibble - lower nibble of a byte.
+
+ Returns:
+ Hex unicode character.
+
+--*/
+{
+ Nibble &= 0x0F;
+ if (Nibble <= 0x9) {
+ return (CHAR16)(Nibble + L'0');
+ }
+
+ return (CHAR16)(Nibble - 0xA + L'A');
+}
+
+EFI_STATUS
+HexStringToBuf (
+ IN OUT UINT8 *Buf,
+ IN OUT UINTN *Len,
+ IN CHAR16 *Str,
+ OUT UINTN *ConvertedStrLen OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Converts Unicode string to binary buffer.
+ The conversion may be partial.
+ The first character in the string that is not hex digit stops the conversion.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ Arguments:
+ Buf - Pointer to buffer that receives the data.
+ Len - Length in bytes of the buffer to hold converted data.
+ If routine return with EFI_SUCCESS, containing length of converted data.
+ If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
+ Str - String to be converted from.
+ ConvertedStrLen - Length of the Hex String consumed.
+
+ Returns:
+ EFI_SUCCESS: Routine Success.
+ EFI_BUFFER_TOO_SMALL: The buffer is too small to hold converted data.
+ EFI_
+
+--*/
+{
+ UINTN HexCnt;
+ UINTN Idx;
+ UINTN BufferLength;
+ UINT8 Digit;
+ UINT8 Byte;
+
+ //
+ // Find out how many hex characters the string has.
+ //
+ for (Idx = 0, HexCnt = 0; IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);
+
+ if (HexCnt == 0) {
+ *Len = 0;
+ return EFI_SUCCESS;
+ }
+ //
+ // Two Unicode characters make up 1 buffer byte. Round up.
+ //
+ BufferLength = (HexCnt + 1) / 2;
+
+ //
+ // Test if buffer is passed enough.
+ //
+ if (BufferLength > (*Len)) {
+ *Len = BufferLength;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Len = BufferLength;
+
+ for (Idx = 0; Idx < HexCnt; Idx++) {
+
+ IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]);
+
+ //
+ // For odd charaters, write the lower nibble for each buffer byte,
+ // and for even characters, the upper nibble.
+ //
+ if ((Idx & 1) == 0) {
+ Byte = Digit;
+ } else {
+ Byte = Buf[Idx / 2];
+ Byte &= 0x0F;
+ Byte |= Digit << 4;
+ }
+
+ Buf[Idx / 2] = Byte;
+ }
+
+ if (ConvertedStrLen != NULL) {
+ *ConvertedStrLen = HexCnt;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BufToHexString (
+ IN OUT CHAR16 *Str,
+ IN OUT UINTN *HexStringBufferLength,
+ IN UINT8 *Buf,
+ IN UINTN Len
+ )
+/*++
+
+ Routine Description:
+ Converts binary buffer to Unicode string.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ Arguments:
+ Str - Pointer to the string.
+ HexStringBufferLength - Length in bytes of buffer to hold the hex string. Includes tailing '\0' character.
+ If routine return with EFI_SUCCESS, containing length of hex string buffer.
+ If routine return with EFI_BUFFER_TOO_SMALL, containg length of hex string buffer desired.
+ Buf - Buffer to be converted from.
+ Len - Length in bytes of the buffer to be converted.
+
+ Returns:
+ EFI_SUCCESS: Routine success.
+ EFI_BUFFER_TOO_SMALL: The hex string buffer is too small.
+
+--*/
+{
+ UINTN Idx;
+ UINT8 Byte;
+ UINTN StrLen;
+
+ //
+ // Make sure string is either passed or allocate enough.
+ // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.
+ // Plus the Unicode termination character.
+ //
+ StrLen = Len * 2;
+ if (StrLen > ((*HexStringBufferLength) - 1)) {
+ *HexStringBufferLength = StrLen + 1;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *HexStringBufferLength = StrLen + 1;
+ //
+ // Ends the string.
+ //
+ Str[StrLen] = L'\0';
+
+ for (Idx = 0; Idx < Len; Idx++) {
+
+ Byte = Buf[Idx];
+ Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);
+ Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));
+ }
+
+ return EFI_SUCCESS;
+}
+
+CHAR16 *
+TrimHexStr (
+ IN CHAR16 *Str
+ )
+/*++
+
+ Routine Description:
+ Skip the leading white space and '0x' or '0X' of a hex string
+
+ Arguments:
+ Str - The hex string
+
+ Returns:
+
+--*/
+{
+ //
+ // skip preceeding white space
+ //
+ while (*Str && *Str == ' ') {
+ Str += 1;
+ }
+ //
+ // skip preceeding zeros
+ //
+ while (*Str && *Str == '0') {
+ Str += 1;
+ }
+ //
+ // skip preceeding white space
+ //
+ if (*Str && (*Str == 'x' || *Str == 'X')) {
+ Str += 1;
+ }
+
+ return Str;
+}
+
+UINTN
+Xtoi (
+ IN CHAR16 *Str
+ )
+/*++
+
+Routine Description:
+
+ Convert hex string to uint
+
+Arguments:
+
+ Str - The string
+
+Returns:
+
+--*/
+{
+ UINTN Rvalue;
+ UINTN Length;
+
+ ASSERT (Str != NULL);
+
+ //
+ // convert hex digits
+ //
+ Rvalue = 0;
+ Length = sizeof (UINTN);
+ HexStringToBuf ((UINT8 *) &Rvalue, &Length, TrimHexStr (Str), NULL);
+
+ return Rvalue;
+}
+
+VOID
+Xtoi64 (
+ IN CHAR16 *Str,
+ IN UINT64 *Data
+ )
+/*++
+
+Routine Description:
+
+ Convert hex string to 64 bit data.
+
+Arguments:
+
+ Str - The string
+
+Returns:
+
+--*/
+{
+ UINTN Length;
+
+ Length = sizeof (UINT64);
+ HexStringToBuf ((UINT8 *) Data, &Length, TrimHexStr (Str), NULL);
+}
+
+UINTN
+Atoi (
+ IN CHAR16 *str
+ )
+/*++
+
+Routine Description:
+
+ Convert decimal string to uint
+
+Arguments:
+
+ Str - The string
+
+Returns:
+
+--*/
+{
+ UINTN Rvalue;
+ CHAR16 Char;
+ UINTN High;
+ UINTN Low;
+
+ ASSERT (str != NULL);
+
+ High = (UINTN) -1 / 10;
+ Low = (UINTN) -1 % 10;
+ //
+ // skip preceeding white space
+ //
+ while (*str && *str == ' ') {
+ str += 1;
+ }
+ //
+ // convert digits
+ //
+ Rvalue = 0;
+ Char = *(str++);
+ while (Char) {
+ if (Char >= '0' && Char <= '9') {
+ if (Rvalue > High || Rvalue == High && Char - '0' > (INTN) Low) {
+ return (UINTN) -1;
+ }
+
+ Rvalue = (Rvalue * 10) + Char - '0';
+ } else {
+ break;
+ }
+
+ Char = *(str++);
+ }
+
+ return Rvalue;
+}
+
+EFI_STATUS
+StrToBuf (
+ OUT UINT8 *Buf,
+ IN UINTN BufferLength,
+ IN CHAR16 *Str
+ )
+{
+ UINTN Index;
+ UINTN StrLength;
+ UINT8 Digit;
+ UINT8 Byte;
+
+ //
+ // Two hex char make up one byte
+ //
+ StrLength = BufferLength * sizeof (CHAR16);
+
+ for(Index = 0; Index < StrLength; Index++, Str++) {
+
+ IsHexDigit (&Digit, *Str);
+
+ //
+ // For odd charaters, write the upper nibble for each buffer byte,
+ // and for even characters, the lower nibble.
+ //
+ if ((Index & 1) == 0) {
+ Byte = Digit << 4;
+ } else {
+ Byte = Buf[Index / 2];
+ Byte &= 0xF0;
+ Byte |= Digit;
+ }
+
+ Buf[Index / 2] = Byte;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+StrToGuid (
+ IN CHAR16 *Str,
+ OUT EFI_GUID *Guid
+ )
+{
+ UINTN BufferLength;
+ UINTN ConvertedStrLen;
+ EFI_STATUS Status;
+
+ BufferLength = sizeof (Guid->Data1);
+ Status = HexStringToBuf ((UINT8 *) &Guid->Data1, &BufferLength, Str, &ConvertedStrLen);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Str += ConvertedStrLen;
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ BufferLength = sizeof (Guid->Data2);
+ Status = HexStringToBuf ((UINT8 *) &Guid->Data2, &BufferLength, Str, &ConvertedStrLen);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Str += ConvertedStrLen;
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ BufferLength = sizeof (Guid->Data3);
+ Status = HexStringToBuf ((UINT8 *) &Guid->Data3, &BufferLength, Str, &ConvertedStrLen);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Str += ConvertedStrLen;
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ 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;
+}
+
+VOID
+StrToIPv4Addr (
+ IN OUT CHAR16 **Str,
+ OUT EFI_IPv4_ADDRESS *IPv4Addr
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < 4; Index++) {
+ IPv4Addr->Addr[Index] = (UINT8) Atoi (SplitStr (Str, L'.'));
+ }
+}
+
+VOID
+StrToIPv6Addr (
+ IN OUT CHAR16 **Str,
+ OUT EFI_IPv6_ADDRESS *IPv6Addr
+ )
+{
+ UINTN Index;
+ UINT16 Data;
+
+ for (Index = 0; Index < 8; Index++) {
+ Data = (UINT16) Xtoi (SplitStr (Str, L':'));
+ IPv6Addr->Addr[Index * 2] = (UINT8) (Data >> 8);
+ IPv6Addr->Addr[Index * 2 + 1] = (UINT8) (Data & 0xff);
+ }
+}
+
+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;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPci (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionStr;
+ CHAR16 *DeviceStr;
+ PCI_DEVICE_PATH *Pci;
+
+ FunctionStr = GetNextParamStr (&TextDeviceNode);
+ DeviceStr = GetNextParamStr (&TextDeviceNode);
+ Pci = (PCI_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCI_DP,
+ sizeof (PCI_DEVICE_PATH)
+ );
+
+ Pci->Function = (UINT8) Xtoi (FunctionStr);
+ Pci->Device = (UINT8) Xtoi (DeviceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
+}
+
+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,
+ sizeof (PCCARD_DEVICE_PATH)
+ );
+
+ Pccard->FunctionNumber = (UINT8) Xtoi (FunctionNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMemoryMapped (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddressStr;
+ CHAR16 *EndingAddressStr;
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ StartingAddressStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddressStr = GetNextParamStr (&TextDeviceNode);
+ MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ sizeof (MEMMAP_DEVICE_PATH)
+ );
+
+ MemMap->MemoryType = 0;
+
+ Xtoi64 (StartingAddressStr, &MemMap->StartingAddress);
+ Xtoi64 (EndingAddressStr, &MemMap->EndingAddress);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
+}
+
+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,
+ sizeof (VENDOR_DEVICE_PATH) + (UINT16) Length
+ );
+
+ StrToGuid (GuidStr, &Vendor->Guid);
+ StrToBuf (((UINT8 *) Vendor) + sizeof (VENDOR_DEVICE_PATH), Length, DataStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenHw (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP
+ );
+}
+
+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,
+ sizeof (CONTROLLER_DEVICE_PATH)
+ );
+ Controller->ControllerNumber = (UINT32) Xtoi (ControllerStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
+}
+
+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,
+ sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+ HIDStr += 3;
+ }
+
+ Acpi->HID = EISA_PNP_ID (Xtoi (HIDStr));
+ Acpi->UID = (UINT32) Xtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextAcpi (
+ IN CHAR16 *TextDeviceNode,
+ IN UINT32 Hid
+ )
+{
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = Hid;
+ Acpi->UID = (UINT32) Xtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPciRoot (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a0341d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFloppy (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x060441d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextKeyboard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x030141d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSerial (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x050141d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextParallelPort (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x040141d0);
+}
+
+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_WITH_STR *AcpiExt;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ HIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ CIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ Length = sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) +
+ (UINT16) StrLen (HIDSTRStr) + 1 +
+ (UINT16) StrLen (UIDSTRStr) + 1 +
+ (UINT16) StrLen (CIDSTRStr) + 1;
+ AcpiExt = (ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+ HIDStr += 3;
+ AcpiExt->HID = EISA_PNP_ID (Xtoi (HIDStr));
+ } else {
+ AcpiExt->HID = (UINT32) Xtoi (HIDStr);
+ }
+
+ AcpiExt->UID = (UINT32) Xtoi (UIDStr);
+ AcpiExt->CID = (UINT32) Xtoi (CIDStr);
+
+ AsciiStr = AcpiExt->HidUidCidStr;
+ StrToAscii (HIDSTRStr, &AsciiStr);
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ StrToAscii (CIDSTRStr, &AsciiStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiExt;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiExp (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *AcpiExt;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ Length = sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + (UINT16) StrLen (UIDSTRStr) + 3;
+ AcpiExt = (ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+ HIDStr += 3;
+ AcpiExt->HID = EISA_PNP_ID (Xtoi (HIDStr));
+ } else {
+ AcpiExt->HID = (UINT32) Xtoi (HIDStr);
+ }
+
+ AcpiExt->UID = 0;
+ AcpiExt->CID = (UINT32) Xtoi (CIDStr);
+
+ AsciiStr = AcpiExt->HidUidCidStr;
+ //
+ // HID string is NULL
+ //
+ *AsciiStr = 0;
+ //
+ // Convert UID string
+ //
+ AsciiStr++;
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ //
+ // CID string is NULL
+ //
+ *AsciiStr = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiExt;
+}
+
+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,
+ sizeof (ATAPI_DEVICE_PATH)
+ );
+
+ PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
+ SlaveMasterStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+
+ Atapi->PrimarySecondary = (StrCmp (PrimarySecondaryStr, L"Primary") == 0) ? (UINT8) 0 : (UINT8) 1;
+ Atapi->SlaveMaster = (StrCmp (SlaveMasterStr, L"Master") == 0) ? (UINT8) 0 : (UINT8) 1;
+ Atapi->Lun = (UINT16) Xtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
+}
+
+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,
+ sizeof (SCSI_DEVICE_PATH)
+ );
+
+ Scsi->Pun = (UINT16) Xtoi (PunStr);
+ Scsi->Lun = (UINT16) Xtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
+}
+
+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,
+ sizeof (FIBRECHANNEL_DEVICE_PATH)
+ );
+
+ Fibre->Reserved = 0;
+ Xtoi64 (WWNStr, &Fibre->WWN);
+ Xtoi64 (LunStr, &Fibre->Lun);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromText1394 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ F1394_DEVICE_PATH *F1394;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ F1394 = (F1394_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_1394_DP,
+ sizeof (F1394_DEVICE_PATH)
+ );
+
+ F1394->Reserved = 0;
+ Xtoi64 (GuidStr, &F1394->Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) F1394;
+}
+
+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,
+ sizeof (USB_DEVICE_PATH)
+ );
+
+ Usb->ParentPortNumber = (UINT8) Xtoi (PortStr);
+ Usb->InterfaceNumber = (UINT8) Xtoi (InterfaceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextI2O (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TIDStr;
+ I2O_DEVICE_PATH *I2O;
+
+ TIDStr = GetNextParamStr (&TextDeviceNode);
+ I2O = (I2O_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_I2O_DP,
+ sizeof (I2O_DEVICE_PATH)
+ );
+
+ I2O->Tid = (UINT32) Xtoi (TIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) I2O;
+}
+
+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,
+ sizeof (INFINIBAND_DEVICE_PATH)
+ );
+
+ InfiniBand->ResourceFlags = (UINT32) Xtoi (FlagsStr);
+ StrToGuid (GuidStr, &PortGid);
+ CopyMem (InfiniBand->PortGid, &PortGid, sizeof (EFI_GUID));
+ Xtoi64 (SidStr, &InfiniBand->ServiceId);
+ Xtoi64 (TidStr, &InfiniBand->TargetPortId);
+ Xtoi64 (DidStr, &InfiniBand->DeviceId);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMsg (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP
+ );
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenPcAnsi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ Vendor->Guid = gEfiPcAnsiGuid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ Vendor->Guid = gEfiVT100Guid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100Plus (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ Vendor->Guid = gEfiVT100PlusGuid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenUtf8 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ Vendor->Guid = gEfiVTUTF8Guid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+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,
+ sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
+ );
+
+ UartFlowControl->Guid = mEfiDevicePathMessagingUartFlowControlGuid;
+ 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;
+}
+
+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;
+ 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);
+ Info = 0x0000;
+ Sas = (SAS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (SAS_DEVICE_PATH)
+ );
+
+ Sas->Guid = mEfiDevicePathMessagingSASGuid;
+ Xtoi64 (AddressStr, &Sas->SasAddress);
+ Xtoi64 (LunStr, &Sas->Lun);
+ Sas->RelativeTargetPort = (UINT16) Xtoi (RTPStr);
+ if (StrCmp (SASSATAStr, L"NoTopology") == 0)
+ ;
+ else {
+ if (StrCmp (DriveBayStr, L"0") == 0) {
+ Info |= 0x0001;
+ } else {
+ Info |= 0x0002;
+ Info |= (Xtoi (DriveBayStr) << 8);
+ }
+
+ if (StrCmp (SASSATAStr, L"SATA") == 0) {
+ Info |= 0x0010;
+ }
+
+ if (StrCmp (LocationStr, L"External") == 0) {
+ Info |= 0x0020;
+ }
+
+ if (StrCmp (ConnectStr, L"Expanded") == 0) {
+ Info |= 0x0040;
+ }
+ }
+
+ Sas->DeviceTopology = Info;
+ Sas->Reserved = (UINT32) Xtoi (ReservedStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
+}
+
+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,
+ sizeof (VENDOR_DEFINED_MESSAGING_DEVICE_PATH)
+ );
+
+ Vend->Guid = gEfiDebugPortProtocolGuid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMAC (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *IfTypeStr;
+ UINTN Length;
+ MAC_ADDR_DEVICE_PATH *MAC;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ IfTypeStr = GetNextParamStr (&TextDeviceNode);
+ MAC = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_MAC_ADDR_DP,
+ sizeof (MAC_ADDR_DEVICE_PATH)
+ );
+
+ MAC->IfType = (UINT8) Xtoi (IfTypeStr);
+
+ Length = sizeof (EFI_MAC_ADDRESS);
+ StrToBuf (&MAC->MacAddress.Addr[0], Length, AddressStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MAC;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv4 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ IPv4_DEVICE_PATH *IPv4;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ IPv4 = (IPv4_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv4_DP,
+ sizeof (IPv4_DEVICE_PATH)
+ );
+
+ StrToIPv4Addr (&RemoteIPStr, &IPv4->RemoteIpAddress);
+ IPv4->Protocol = (StrCmp (ProtocolStr, L"UDP") == 0) ? (UINT16) 0 : (UINT16) 1;
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv4->StaticIpAddress = TRUE;
+ } else {
+ IPv4->StaticIpAddress = FALSE;
+ }
+
+ StrToIPv4Addr (&LocalIPStr, &IPv4->LocalIpAddress);
+
+ IPv4->LocalPort = 0;
+ IPv4->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv6 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ IPv6_DEVICE_PATH *IPv6;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ IPv6 = (IPv6_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv6_DP,
+ sizeof (IPv6_DEVICE_PATH)
+ );
+
+ StrToIPv6Addr (&RemoteIPStr, &IPv6->RemoteIpAddress);
+ IPv6->Protocol = (StrCmp (ProtocolStr, L"UDP") == 0) ? (UINT16) 0 : (UINT16) 1;
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv6->StaticIpAddress = TRUE;
+ } else {
+ IPv6->StaticIpAddress = FALSE;
+ }
+
+ StrToIPv6Addr (&LocalIPStr, &IPv6->LocalIpAddress);
+
+ IPv6->LocalPort = 0;
+ IPv6->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
+}
+
+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,
+ sizeof (UART_DEVICE_PATH)
+ );
+
+ Uart->BaudRate = (StrCmp (BaudStr, L"DEFAULT") == 0) ? 115200 : Atoi (BaudStr);
+ Uart->DataBits = (StrCmp (DataBitsStr, L"DEFAULT") == 0) ? (UINT8) 8 : (UINT8) Atoi (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;
+
+ 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;
+}
+
+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,
+ sizeof (USB_CLASS_DEVICE_PATH)
+ );
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ if (UsbClassText->ClassExist) {
+ ClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceClass = (UINT8) Xtoi (ClassStr);
+ } else {
+ UsbClass->DeviceClass = UsbClassText->Class;
+ }
+ if (UsbClassText->SubClassExist) {
+ SubClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceSubClass = (UINT8) Xtoi (SubClassStr);
+ } else {
+ UsbClass->DeviceSubClass = UsbClassText->SubClass;
+ }
+
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+
+ UsbClass->VendorId = (UINT16) Xtoi (VIDStr);
+ UsbClass->ProductId = (UINT16) Xtoi (PIDStr);
+ UsbClass->DeviceProtocol = (UINT8) Xtoi (ProtocolStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
+}
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbClass (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = TRUE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWwid (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *InterfaceNumStr;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceNumStr = GetNextParamStr (&TextDeviceNode);
+ UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_WWID_DP,
+ sizeof (USB_WWID_DEVICE_PATH)
+ );
+
+ UsbWwid->VendorId = (UINT16) Xtoi (VIDStr);
+ UsbWwid->ProductId = (UINT16) Xtoi (PIDStr);
+ UsbWwid->InterfaceNumber = (UINT16) Xtoi (InterfaceNumStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
+}
+
+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,
+ sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
+ );
+
+ LogicalUnit->Lun = (UINT8) Xtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextiSCSI (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ UINT16 Options;
+ CHAR16 *NameStr;
+ CHAR16 *PortalGroupStr;
+ CHAR16 *LunStr;
+ CHAR16 *HeaderDigestStr;
+ CHAR16 *DataDigestStr;
+ CHAR16 *AuthenticationStr;
+ CHAR16 *ProtocolStr;
+ ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;
+
+ NameStr = GetNextParamStr (&TextDeviceNode);
+ PortalGroupStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ HeaderDigestStr = GetNextParamStr (&TextDeviceNode);
+ DataDigestStr = GetNextParamStr (&TextDeviceNode);
+ AuthenticationStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ iSCSI = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ISCSI_DP,
+ sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + (UINT16) (StrLen (NameStr) * 2)
+ );
+
+ StrCpy (iSCSI->iSCSITargetName, NameStr);
+ iSCSI->TargetPortalGroupTag = (UINT16) Xtoi (PortalGroupStr);
+ Xtoi64 (LunStr, &iSCSI->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;
+ }
+
+ iSCSI->LoginOption = (UINT16) Options;
+
+ iSCSI->NetworkProtocol = (UINT16) StrCmp (ProtocolStr, L"TCP");
+ iSCSI->Reserved = (UINT16) 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) iSCSI;
+}
+
+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,
+ sizeof (HARDDRIVE_DEVICE_PATH)
+ );
+
+ Hd->PartitionNumber = (UINT32) Atoi (PartitionStr);
+
+ ZeroMem (Hd->Signature, 16);
+ Hd->MBRType = (UINT8) 0;
+
+ if (StrCmp (TypeStr, L"None") == 0) {
+ Hd->SignatureType = (UINT8) 0;
+ } else if (StrCmp (TypeStr, L"MBR") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_MBR;
+ Hd->MBRType = 0x01;
+
+ Signature32 = (UINT32) Xtoi (SignatureStr);
+ CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));
+ } else if (StrCmp (TypeStr, L"GUID") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_GUID;
+ Hd->MBRType = 0x02;
+
+ StrToGuid (SignatureStr, &SignatureGuid);
+ CopyMem (Hd->Signature, &SignatureGuid, sizeof (EFI_GUID));
+ } else {
+ Hd->SignatureType = 0xff;
+
+ }
+
+ Xtoi64 (StartStr, &Hd->PartitionStart);
+ Xtoi64 (SizeStr, &Hd->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCDROM (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *EntryStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ CDROM_DEVICE_PATH *CDROM;
+
+ EntryStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ CDROM = (CDROM_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_CDROM_DP,
+ sizeof (CDROM_DEVICE_PATH)
+ );
+
+ CDROM->BootEntry = (UINT32) Xtoi (EntryStr);
+ Xtoi64 (StartStr, &CDROM->PartitionStart);
+ Xtoi64 (SizeStr, &CDROM->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) CDROM;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMEDIA (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MEDIA_DEVICE_PATH,
+ MEDIA_VENDOR_DP
+ );
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFilePath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ FILEPATH_DEVICE_PATH *File;
+
+ File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ sizeof (FILEPATH_DEVICE_PATH) + (UINT16) (StrLen (TextDeviceNode) * 2)
+ );
+
+ StrCpy (File->PathName, TextDeviceNode);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) File;
+}
+
+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,
+ sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Media->Protocol);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Media;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBBS (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+ CHAR16 *IdStr;
+ CHAR16 *FlagsStr;
+ UINT8 *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,
+ sizeof (BBS_BBS_DEVICE_PATH) + (UINT16) (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 = BBS_TYPE_UNKNOWN;
+ }
+
+ AsciiStr = Bbs->String;
+ StrToAscii (IdStr, &AsciiStr);
+
+ Bbs->StatusFlag = (UINT16) Xtoi (FlagsStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
+}
+
+DEVICE_PATH_FROM_TEXT_TABLE DevPathFromTextTable[] = {
+ L"Pci",
+ DevPathFromTextPci,
+ L"PcCard",
+ DevPathFromTextPcCard,
+ L"MemoryMapped",
+ DevPathFromTextMemoryMapped,
+ L"VenHw",
+ DevPathFromTextVenHw,
+ L"Ctrl",
+ DevPathFromTextCtrl,
+ L"Acpi",
+ DevPathFromTextAcpi,
+ L"PciRoot",
+ DevPathFromTextPciRoot,
+ L"Floppy",
+ DevPathFromTextFloppy,
+ L"Keyboard",
+ DevPathFromTextKeyboard,
+ L"Serial",
+ DevPathFromTextSerial,
+ L"ParallelPort",
+ DevPathFromTextParallelPort,
+ L"AcpiEx",
+ DevPathFromTextAcpiEx,
+ L"AcpiExp",
+ DevPathFromTextAcpiExp,
+ L"Ata",
+ DevPathFromTextAta,
+ L"Scsi",
+ DevPathFromTextScsi,
+ L"Fibre",
+ DevPathFromTextFibre,
+ 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"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"HD",
+ DevPathFromTextHD,
+ L"CDROM",
+ DevPathFromTextCDROM,
+ L"VenMEDIA",
+ DevPathFromTextVenMEDIA,
+ L"Media",
+ DevPathFromTextMedia,
+ L"BBS",
+ DevPathFromTextBBS,
+ NULL,
+ NULL
+};
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ )
+/*++
+
+ Routine Description:
+ Convert text to the binary representation of a device node.
+
+ Arguments:
+ 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.
+
+ Returns:
+ A pointer - Pointer to the EFI device node.
+ NULL - If TextDeviceNode is NULL or there was insufficient memory or text unsupported.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL * (*DumpNode) (CHAR16 *);
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ CHAR16 *DeviceNodeStr;
+ UINTN Index;
+
+ if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
+ return NULL;
+ }
+
+ ParamStr = NULL;
+ DumpNode = NULL;
+ DeviceNodeStr = StrDuplicate (TextDeviceNode);
+
+ for (Index = 0; DevPathFromTextTable[Index].Function; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ DumpNode = DevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (DumpNode == NULL) {
+ //
+ // A file path
+ //
+ DumpNode = DevPathFromTextFilePath;
+ DeviceNode = DumpNode (DeviceNodeStr);
+ } else {
+ DeviceNode = DumpNode (ParamStr);
+ gBS->FreePool (ParamStr);
+ }
+
+ gBS->FreePool (DeviceNodeStr);
+
+ return DeviceNode;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ )
+/*++
+
+ Routine Description:
+ Convert text to the binary representation of a device path.
+
+ Arguments:
+ 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.
+
+ Returns:
+ A pointer - Pointer to the allocated device path.
+ NULL - If TextDeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL * (*DumpNode) (CHAR16 *);
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ CHAR16 *DevicePathStr;
+ CHAR16 *Str;
+ CHAR16 *DeviceNodeStr;
+ UINT8 IsInstanceEnd;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
+ return NULL;
+ }
+
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ SetDevicePathEndNode (DevicePath);
+
+ ParamStr = NULL;
+ DeviceNodeStr = NULL;
+ DevicePathStr = StrDuplicate (TextDevicePath);
+
+ Str = DevicePathStr;
+ while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
+ DumpNode = NULL;
+ for (Index = 0; DevPathFromTextTable[Index].Function; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ DumpNode = DevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (DumpNode == NULL) {
+ //
+ // A file path
+ //
+ DumpNode = DevPathFromTextFilePath;
+ DeviceNode = DumpNode (DeviceNodeStr);
+ } else {
+ DeviceNode = DumpNode (ParamStr);
+ gBS->FreePool (ParamStr);
+ }
+
+ NewDevicePath = AppendDeviceNode (DevicePath, DeviceNode);
+ gBS->FreePool (DevicePath);
+ gBS->FreePool (DeviceNode);
+ DevicePath = NewDevicePath;
+
+ if (IsInstanceEnd) {
+ DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ SetDevicePathInstanceEndNode (DeviceNode);
+
+ NewDevicePath = AppendDeviceNode (DevicePath, DeviceNode);
+ gBS->FreePool (DevicePath);
+ gBS->FreePool (DeviceNode);
+ DevicePath = NewDevicePath;
+ }
+ }
+
+ gBS->FreePool (DevicePathStr);
+ return DevicePath;
+}
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c
new file mode 100644
index 0000000000..64fd5658fd
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c
@@ -0,0 +1,1526 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+ DevicePathToText.c
+
+Abstract:
+
+ DevicePathToText protocol as defined in the UEFI 2.0 specification.
+
+--*/
+
+#include <protocol/DevicePathToText.h>
+#include "DevicePath.h"
+
+EFI_DEVICE_PATH_PROTOCOL *
+UnpackDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ )
+/*++
+
+ Routine Description:
+ Function unpacks a device path data structure so that all the nodes of a device path
+ are naturally aligned.
+
+ Arguments:
+ DevPath - A pointer to a device path data structure
+
+ Returns:
+ If the memory for the device path is successfully allocated, then a pointer to the
+ new device path is returned. Otherwise, NULL is returned.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Src;
+ EFI_DEVICE_PATH_PROTOCOL *Dest;
+ EFI_DEVICE_PATH_PROTOCOL *NewPath;
+ UINTN Size;
+
+ if (DevPath == NULL) {
+ return NULL;
+ }
+ //
+ // Walk device path and round sizes to valid boundries
+ //
+ Src = DevPath;
+ Size = 0;
+ for (;;) {
+ Size += DevicePathNodeLength (Src);
+ Size += ALIGN_SIZE (Size);
+
+ if (IsDevicePathEnd (Src)) {
+ break;
+ }
+
+ Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);
+ }
+ //
+ // Allocate space for the unpacked path
+ //
+ NewPath = AllocateZeroPool (Size);
+ if (NewPath != NULL) {
+
+ ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);
+
+ //
+ // Copy each node
+ //
+ Src = DevPath;
+ Dest = NewPath;
+ for (;;) {
+ Size = DevicePathNodeLength (Src);
+ CopyMem (Dest, Src, Size);
+ Size += ALIGN_SIZE (Size);
+ SetDevicePathNodeLength (Dest, Size);
+ Dest->Type |= EFI_DP_TYPE_UNPACKED;
+ Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);
+
+ if (IsDevicePathEnd (Src)) {
+ break;
+ }
+
+ Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);
+ }
+ }
+
+ return NewPath;
+}
+
+VOID *
+ReallocatePool (
+ IN VOID *OldPool,
+ IN UINTN OldSize,
+ IN UINTN NewSize
+ )
+/*++
+
+ Routine Description:
+ Adjusts the size of a previously allocated buffer.
+
+ Arguments:
+ OldPool - A pointer to the buffer whose size is being adjusted.
+ OldSize - The size of the current buffer.
+ NewSize - The size of the new buffer.
+
+ Returns:
+ EFI_SUCEESS - The requested number of bytes were allocated.
+ EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
+ EFI_INVALID_PARAMETER - The buffer was invalid.
+
+--*/
+{
+ VOID *NewPool;
+
+ NewPool = NULL;
+ if (NewSize) {
+ NewPool = AllocateZeroPool (NewSize);
+ }
+
+ if (OldPool) {
+ if (NewPool) {
+ CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
+ }
+
+ gBS->FreePool (OldPool);
+ }
+
+ return NewPool;
+}
+
+CHAR16 *
+CatPrint (
+ IN OUT POOL_PRINT *Str,
+ IN CHAR16 *Fmt,
+ ...
+ )
+/*++
+
+ Routine Description:
+ Concatenates a formatted unicode string to allocated pool.
+ The caller must free the resulting buffer.
+
+ Arguments:
+ Str - Tracks the allocated pool, size in use, and
+ amount of pool allocated.
+ Fmt - The format string
+
+ Returns:
+ Allocated buffer with the formatted string printed in it.
+ The caller must free the allocated buffer. The buffer
+ allocation is not packed.
+
+--*/
+{
+ UINT16 *AppendStr;
+ VA_LIST Args;
+ UINTN Size;
+
+ AppendStr = AllocateZeroPool (0x1000);
+ if (AppendStr == NULL) {
+ return Str->Str;
+ }
+
+ VA_START (Args, Fmt);
+ UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);
+ VA_END (Args);
+ if (NULL == Str->Str) {
+ Size = StrSize (AppendStr);
+ Str->Str = AllocateZeroPool (Size);
+ ASSERT (Str->Str != NULL);
+ } else {
+ Size = StrSize (AppendStr) + StrSize (Str->Str) - sizeof (UINT16);
+ Str->Str = ReallocatePool (
+ Str->Str,
+ StrSize (Str->Str),
+ Size
+ );
+ ASSERT (Str->Str != NULL);
+ }
+
+ Str->MaxLen = MAX_CHAR * sizeof (UINT16);
+ if (Size < Str->MaxLen) {
+ StrCat (Str->Str, AppendStr);
+ Str->Len = Size - sizeof (UINT16);
+ }
+
+ gBS->FreePool (AppendStr);
+ return Str->Str;
+}
+
+VOID
+DevPathToTextPci (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PCI_DEVICE_PATH *Pci;
+
+ Pci = DevPath;
+ CatPrint (Str, L"Pci(%x,%x)", Pci->Function, Pci->Device);
+}
+
+VOID
+DevPathToTextPccard (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PCCARD_DEVICE_PATH *Pccard;
+
+ Pccard = DevPath;
+ CatPrint (Str, L"PcCard(%x)", Pccard->FunctionNumber);
+}
+
+VOID
+DevPathToTextMemMap (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemMap = DevPath;
+ CatPrint (
+ Str,
+ L"MemoryMapped(%lx,%lx)",
+ MemMap->StartingAddress,
+ MemMap->EndingAddress
+ );
+}
+
+VOID
+DevPathToTextVendor (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+ CHAR16 *Type;
+ UINTN Index;
+ 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)) {
+ CatPrint (Str, L"VenPcAnsi()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
+ CatPrint (Str, L"VenVt100()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
+ CatPrint (Str, L"VenVt100Plus()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
+ CatPrint (Str, L"VenUft8()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingUartFlowControlGuid)) {
+ FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
+ switch (FlowControlMap & 0x00000003) {
+ case 0:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
+ break;
+
+ case 1:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
+ break;
+
+ case 2:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingSASGuid)) {
+ CatPrint (
+ Str,
+ L"SAS(%lx,%lx,%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) {
+ CatPrint (Str, L"NoTopology,0,0,0,");
+ } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {
+ CatPrint (
+ Str,
+ L"%s,%s,%s,",
+ (Info & (0x1 << 4)) ? L"SATA" : L"SAS",
+ (Info & (0x1 << 5)) ? L"External" : L"Internal",
+ (Info & (0x1 << 6)) ? L"Expanded" : L"Direct"
+ );
+ if ((Info & 0x0f) == 1) {
+ CatPrint (Str, L"0,");
+ } else {
+ CatPrint (Str, L"%x,", (Info >> 8) & 0xff);
+ }
+ } else {
+ CatPrint (Str, L"0,0,0,0,");
+ }
+
+ CatPrint (Str, L"%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
+ CatPrint (Str, L"DebugPort()");
+ return ;
+ } else {
+ return ;
+ //
+ // reserved
+ //
+ }
+ }
+ break;
+
+ case MEDIA_DEVICE_PATH:
+ Type = L"Media";
+ break;
+
+ default:
+ Type = L"?";
+ break;
+ }
+
+ CatPrint (Str, L"Ven%s(%g,", Type, &Vendor->Guid);
+ for (Index = 0; Index < DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH); Index++) {
+ CatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
+ }
+
+ CatPrint (Str, L")");
+}
+
+VOID
+DevPathToTextController (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ Controller = DevPath;
+ CatPrint (
+ Str,
+ L"Ctrl(%x)",
+ (UINT16 *)Controller->ControllerNumber
+ );
+}
+
+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) {
+ if (AllowShortcuts) {
+ switch (EISA_ID_TO_NUM (Acpi->HID)) {
+ case 0x0a03:
+ CatPrint (Str, L"PciRoot(%x)", Acpi->UID);
+ break;
+
+ case 0x0604:
+ CatPrint (Str, L"Floppy(%x)", Acpi->UID);
+ break;
+
+ case 0x0301:
+ CatPrint (Str, L"Keyboard(%x)", Acpi->UID);
+ break;
+
+ case 0x0501:
+ CatPrint (Str, L"Serial(%x)", Acpi->UID);
+ break;
+
+ case 0x0401:
+ CatPrint (Str, L"ParallelPort(%x)", Acpi->UID);
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ }
+
+ CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
+ } else {
+ CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
+ }
+}
+
+#define NextStrA(a) ((UINT8 *) (((UINT8 *) (a)) + AsciiStrLen (a) + 1))
+
+VOID
+DevPathToTextExtAcpi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *AcpiExt;
+
+ AcpiExt = DevPath;
+
+ if (AllowShortcuts) {
+ if ((*(AcpiExt->HidUidCidStr) == '\0') &&
+ (*(NextStrA (NextStrA (AcpiExt->HidUidCidStr))) == '\0') &&
+ (AcpiExt->UID == 0)
+ ) {
+ if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ CatPrint (
+ Str,
+ L"AcpiExp(PNP%04x,%x,%a)",
+ EISA_ID_TO_NUM (AcpiExt->HID),
+ AcpiExt->CID,
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ } else {
+ CatPrint (
+ Str,
+ L"AcpiExp(%08x,%x,%a)",
+ AcpiExt->HID,
+ AcpiExt->CID,
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ }
+ }
+ return ;
+ }
+
+ if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ CatPrint (
+ Str,
+ L"AcpiEx(PNP%04x,%x,%x,%a,%a,%a)",
+ EISA_ID_TO_NUM (AcpiExt->HID),
+ AcpiExt->CID,
+ AcpiExt->UID,
+ AcpiExt->HidUidCidStr,
+ NextStrA (NextStrA (AcpiExt->HidUidCidStr)),
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ } else {
+ CatPrint (
+ Str,
+ L"AcpiEx(%08x,%x,%x,%a,%a,%a)",
+ AcpiExt->HID,
+ AcpiExt->CID,
+ AcpiExt->UID,
+ AcpiExt->HidUidCidStr,
+ NextStrA (NextStrA (AcpiExt->HidUidCidStr)),
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ }
+}
+
+VOID
+DevPathToTextAtapi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = DevPath;
+
+ if (DisplayOnly) {
+ CatPrint (Str, L"Ata(%x)", Atapi->Lun);
+ } else {
+ CatPrint (
+ Str,
+ L"Ata(%s,%s,%x)",
+ Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
+ Atapi->SlaveMaster ? L"Slave" : L"Master",
+ Atapi->Lun
+ );
+ }
+}
+
+VOID
+DevPathToTextScsi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ SCSI_DEVICE_PATH *Scsi;
+
+ Scsi = DevPath;
+ CatPrint (Str, L"Scsi(%x,%x)", Scsi->Pun, Scsi->Lun);
+}
+
+VOID
+DevPathToTextFibre (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ Fibre = DevPath;
+ CatPrint (Str, L"Fibre(%lx,%lx)", Fibre->WWN, Fibre->Lun);
+}
+
+VOID
+DevPathToText1394 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ F1394_DEVICE_PATH *F1394;
+
+ F1394 = DevPath;
+ CatPrint (Str, L"I1394(%lx)", F1394->Guid);
+}
+
+VOID
+DevPathToTextUsb (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_DEVICE_PATH *Usb;
+
+ Usb = DevPath;
+ CatPrint (Str, L"USB(%x,%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
+}
+
+VOID
+DevPathToTextUsbWWID (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_WWID_DEVICE_PATH *UsbWWId;
+
+ UsbWWId = DevPath;
+ CatPrint (
+ Str,
+ L"UsbWwid(%x,%x,%x,\"WWID\")",
+ UsbWWId->VendorId,
+ UsbWWId->ProductId,
+ UsbWWId->InterfaceNumber
+ );
+}
+
+VOID
+DevPathToTextLogicalUnit (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LogicalUnit = DevPath;
+ CatPrint (Str, L"Unit(%x)", LogicalUnit->Lun);
+}
+
+VOID
+DevPathToTextUsbClass (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_CLASS_DEVICE_PATH *UsbClass;
+
+ UsbClass = DevPath;
+
+ if (AllowShortcuts == TRUE) {
+ switch (UsbClass->DeviceClass) {
+ case 1:
+ CatPrint (
+ Str,
+ L"UsbAudio(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 2:
+ CatPrint (
+ Str,
+ L"UsbCDCControl(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 3:
+ CatPrint (
+ Str,
+ L"UsbHID(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 6:
+ CatPrint (
+ Str,
+ L"UsbImage(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 7:
+ CatPrint (
+ Str,
+ L"UsbPrinter(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 8:
+ CatPrint (
+ Str,
+ L"UsbMassStorage(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 9:
+ CatPrint (
+ Str,
+ L"UsbHub(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 10:
+ CatPrint (
+ Str,
+ L"UsbCDCData(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 11:
+ CatPrint (
+ Str,
+ L"UsbSmartCard(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 14:
+ CatPrint (
+ Str,
+ L"UsbVideo(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 220:
+ CatPrint (
+ Str,
+ L"UsbDiagnostic(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 224:
+ CatPrint (
+ Str,
+ L"UsbWireless(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 254:
+ if (UsbClass->DeviceSubClass == 1) {
+ CatPrint (
+ Str,
+ L"UsbDeviceFirmwareUpdate(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ } else if (UsbClass->DeviceSubClass == 2) {
+ CatPrint (
+ Str,
+ L"UsbIrdaBridge(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ } else if (UsbClass->DeviceSubClass == 3) {
+ CatPrint (
+ Str,
+ L"UsbTestAndMeasurement(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"UsbClass(%x,%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceClass,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+}
+
+VOID
+DevPathToTextI2O (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ I2O_DEVICE_PATH *I2O;
+
+ I2O = DevPath;
+ CatPrint (Str, L"I2O(%x)", I2O->Tid);
+}
+
+VOID
+DevPathToTextMacAddr (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MAC_ADDR_DEVICE_PATH *MAC;
+ UINTN HwAddressSize;
+ UINTN Index;
+
+ MAC = DevPath;
+
+ HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+ if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
+ HwAddressSize = 6;
+ }
+
+ CatPrint (Str, L"MAC(");
+
+ for (Index = 0; Index < HwAddressSize; Index++) {
+ CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);
+ }
+
+ CatPrint (Str, L",%x)", MAC->IfType);
+}
+
+VOID
+DevPathToTextIPv4 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPv4_DEVICE_PATH *IP;
+
+ IP = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (
+ Str,
+ L"IPv4(%d.%d.%d.%d)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3]
+ );
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"IPv4(%d.%d.%d.%d,%s,%s,%d.%d.%d.%d)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->Protocol ? L"TCP" : L"UDP",
+ (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",
+ IP->LocalIpAddress.Addr[0],
+ IP->LocalIpAddress.Addr[1],
+ IP->LocalIpAddress.Addr[2],
+ IP->LocalIpAddress.Addr[3]
+ );
+}
+
+VOID
+DevPathToTextIPv6 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPv6_DEVICE_PATH *IP;
+
+ IP = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (
+ Str,
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->RemoteIpAddress.Addr[4],
+ IP->RemoteIpAddress.Addr[5],
+ IP->RemoteIpAddress.Addr[6],
+ IP->RemoteIpAddress.Addr[7],
+ IP->RemoteIpAddress.Addr[8],
+ IP->RemoteIpAddress.Addr[9],
+ IP->RemoteIpAddress.Addr[10],
+ IP->RemoteIpAddress.Addr[11],
+ IP->RemoteIpAddress.Addr[12],
+ IP->RemoteIpAddress.Addr[13],
+ IP->RemoteIpAddress.Addr[14],
+ IP->RemoteIpAddress.Addr[15]
+ );
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x,%s,%s,%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->RemoteIpAddress.Addr[4],
+ IP->RemoteIpAddress.Addr[5],
+ IP->RemoteIpAddress.Addr[6],
+ IP->RemoteIpAddress.Addr[7],
+ IP->RemoteIpAddress.Addr[8],
+ IP->RemoteIpAddress.Addr[9],
+ IP->RemoteIpAddress.Addr[10],
+ IP->RemoteIpAddress.Addr[11],
+ IP->RemoteIpAddress.Addr[12],
+ IP->RemoteIpAddress.Addr[13],
+ IP->RemoteIpAddress.Addr[14],
+ IP->RemoteIpAddress.Addr[15],
+ IP->Protocol ? L"TCP" : L"UDP",
+ (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",
+ IP->LocalIpAddress.Addr[0],
+ IP->LocalIpAddress.Addr[1],
+ IP->LocalIpAddress.Addr[2],
+ IP->LocalIpAddress.Addr[3],
+ IP->LocalIpAddress.Addr[4],
+ IP->LocalIpAddress.Addr[5],
+ IP->LocalIpAddress.Addr[6],
+ IP->LocalIpAddress.Addr[7],
+ IP->LocalIpAddress.Addr[8],
+ IP->LocalIpAddress.Addr[9],
+ IP->LocalIpAddress.Addr[10],
+ IP->LocalIpAddress.Addr[11],
+ IP->LocalIpAddress.Addr[12],
+ IP->LocalIpAddress.Addr[13],
+ IP->LocalIpAddress.Addr[14],
+ IP->LocalIpAddress.Addr[15]
+ );
+}
+
+VOID
+DevPathToTextInfiniBand (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ InfiniBand = DevPath;
+ CatPrint (
+ Str,
+ L"Infiniband(%x,%g,%lx,%lx,%lx)",
+ InfiniBand->ResourceFlags,
+ InfiniBand->PortGid,
+ InfiniBand->ServiceId,
+ InfiniBand->TargetPortId,
+ InfiniBand->DeviceId
+ );
+}
+
+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) {
+ CatPrint (Str, L"Uart(DEFAULT,");
+ } else {
+ CatPrint (Str, L"Uart(%ld,", Uart->BaudRate);
+ }
+
+ if (Uart->DataBits == 0) {
+ CatPrint (Str, L"DEFAULT,");
+ } else {
+ CatPrint (Str, L"%d,", Uart->DataBits);
+ }
+
+ CatPrint (Str, L"%c,", Parity);
+
+ switch (Uart->StopBits) {
+ case 0:
+ CatPrint (Str, L"D)");
+ break;
+
+ case 1:
+ CatPrint (Str, L"1)");
+ break;
+
+ case 2:
+ CatPrint (Str, L"1.5)");
+ break;
+
+ case 3:
+ CatPrint (Str, L"2)");
+ break;
+
+ default:
+ CatPrint (Str, L"x)");
+ break;
+ }
+}
+
+VOID
+DevPathToTextiSCSI (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;
+ UINT16 Options;
+
+ iSCSI = DevPath;
+ CatPrint (
+ Str,
+ L"iSCSI(%s,%x,%lx,",
+ iSCSI->iSCSITargetName,
+ iSCSI->TargetPortalGroupTag,
+ iSCSI->Lun
+ );
+
+ Options = iSCSI->LoginOption;
+ CatPrint (Str, L"%s,", ((Options >> 1) & 0x0001) ? L"CRC32C" : L"None");
+ CatPrint (Str, L"%s,", ((Options >> 3) & 0x0001) ? L"CRC32C" : L"None");
+ if ((Options >> 11) & 0x0001) {
+ CatPrint (Str, L"%s,", L"None");
+ } else if ((Options >> 12) & 0x0001) {
+ CatPrint (Str, L"%s,", L"CHAP_UNI");
+ } else {
+ CatPrint (Str, L"%s,", L"CHAP_BI");
+
+ }
+
+ CatPrint (Str, L"%s)", (iSCSI->NetworkProtocol == 0) ? L"TCP" : L"reserved");
+}
+
+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 0:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,0,",
+ Hd->PartitionNumber,
+ L"None"
+ );
+ break;
+
+ case SIGNATURE_TYPE_MBR:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,%08x,",
+ Hd->PartitionNumber,
+ L"MBR",
+ *((UINT32 *) (&(Hd->Signature[0])))
+ );
+ break;
+
+ case SIGNATURE_TYPE_GUID:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,%g,",
+ Hd->PartitionNumber,
+ L"GUID",
+ (EFI_GUID *) &(Hd->Signature[0])
+ );
+ break;
+
+ default:
+ break;
+ }
+
+ CatPrint (Str, L"%lx,%lx)", Hd->PartitionStart, Hd->PartitionSize);
+}
+
+VOID
+DevPathToTextCDROM (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CDROM_DEVICE_PATH *Cd;
+
+ Cd = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (Str, L"CDROM(%x)", Cd->BootEntry);
+ return ;
+ }
+
+ CatPrint (Str, L"CDROM(%x,%lx,%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
+}
+
+VOID
+DevPathToTextFilePath (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FILEPATH_DEVICE_PATH *Fp;
+
+ Fp = DevPath;
+ CatPrint (Str, L"%s", Fp->PathName);
+}
+
+VOID
+DevPathToTextMediaProtocol (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
+
+ MediaProt = DevPath;
+ CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
+}
+
+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 = L"?";
+ break;
+ }
+
+ CatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);
+
+ if (DisplayOnly == TRUE) {
+ CatPrint (Str, L")");
+ return ;
+ }
+
+ CatPrint (Str, L",%x)", Bbs->StatusFlag);
+}
+
+VOID
+DevPathToTextEndInstance (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CatPrint (Str, L",");
+}
+
+VOID
+DevPathToTextNodeUnknown (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CatPrint (Str, L"?");
+}
+
+DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable[] = {
+ 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,
+ DevPathToTextExtAcpi,
+ 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_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_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,
+ 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_FILEPATH_DP,
+ DevPathToTextFilePath,
+ MEDIA_DEVICE_PATH,
+ MEDIA_PROTOCOL_DP,
+ DevPathToTextMediaProtocol,
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ DevPathToTextFilePath,
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ DevPathToTextBBS,
+ END_DEVICE_PATH_TYPE,
+ END_INSTANCE_DEVICE_PATH_SUBTYPE,
+ DevPathToTextEndInstance,
+ 0,
+ 0,
+ NULL
+};
+
+CHAR16 *
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device node to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device node to be converted.
+ 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.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device node.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+ POOL_PRINT Str;
+ UINTN Index;
+ UINTN NewSize;
+ VOID (*DumpNode)(POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+
+ if (DeviceNode == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Process the device path node
+ //
+ DumpNode = NULL;
+ for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index++) {
+ if (DevicePathType (DeviceNode) == DevPathToTextTable[Index].Type &&
+ DevicePathSubType (DeviceNode) == DevPathToTextTable[Index].SubType
+ ) {
+ DumpNode = DevPathToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // If not found, use a generic function
+ //
+ if (DumpNode == NULL) {
+ DumpNode = DevPathToTextNodeUnknown;
+ }
+
+ //
+ // Print this node
+ //
+ DumpNode (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);
+
+ //
+ // Shrink pool used for string allocation
+ //
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);
+ Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);
+ ASSERT (Str.Str != NULL);
+ Str.Str[Str.Len] = 0;
+ return Str.Str;
+}
+
+CHAR16 *
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device path to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device path to be converted.
+ 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.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device path.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+ POOL_PRINT Str;
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ EFI_DEVICE_PATH_PROTOCOL *UnpackDevPath;
+ UINTN Index;
+ UINTN NewSize;
+ VOID (*DumpNode) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Unpacked the device path
+ //
+ UnpackDevPath = UnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath);
+ ASSERT (UnpackDevPath != NULL);
+
+ //
+ // Process each device path node
+ //
+ DevPathNode = UnpackDevPath;
+ while (!IsDevicePathEnd (DevPathNode)) {
+ //
+ // Find the handler to dump this device path node
+ //
+ DumpNode = NULL;
+ for (Index = 0; DevPathToTextTable[Index].Function; Index += 1) {
+
+ if (DevicePathType (DevPathNode) == DevPathToTextTable[Index].Type &&
+ DevicePathSubType (DevPathNode) == DevPathToTextTable[Index].SubType
+ ) {
+ DumpNode = DevPathToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // If not found, use a generic function
+ //
+ if (!DumpNode) {
+ DumpNode = DevPathToTextNodeUnknown;
+ }
+ //
+ // Put a path seperator in if needed
+ //
+ if (Str.Len && DumpNode != DevPathToTextEndInstance) {
+ if (*(Str.Str + Str.Len / sizeof (CHAR16) - 1) != L',') {
+ CatPrint (&Str, L"/");
+ }
+ }
+ //
+ // Print this node of the device path
+ //
+ DumpNode (&Str, DevPathNode, DisplayOnly, AllowShortcuts);
+
+ //
+ // Next device path node
+ //
+ DevPathNode = NextDevicePathNode (DevPathNode);
+ }
+ //
+ // Shrink pool used for string allocation
+ //
+ gBS->FreePool (UnpackDevPath);
+
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);
+ Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);
+ ASSERT (Str.Str != NULL);
+ Str.Str[Str.Len] = 0;
+ return Str.Str;
+}
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
new file mode 100644
index 0000000000..2b54c76832
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
@@ -0,0 +1,421 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+ DevicePathUtilities.c
+
+Abstract:
+
+ Implementation file for Device Path Utilities Protocol
+
+--*/
+
+#include <protocol/DevicePathUtilities.h>
+#include <protocol/DevicePath.h>
+#include "DevicePath.h"
+
+UINTN
+GetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns the size of the device path, in bytes.
+
+ Arguments:
+ DevicePath - Points to the start of the EFI device path.
+
+ Returns:
+ Size - Size of the specified device path, in bytes, including the end-of-path tag.
+
+--*/
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = (EFI_DEVICE_PATH_PROTOCOL *) 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) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Create a duplicate of the specified path.
+
+ Arguments:
+ DevicePath - Points to the source EFI device path.
+
+ Returns:
+ Pointer - A pointer to the duplicate device path.
+ NULL - Insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN Size;
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ //
+ // Compute the size
+ //
+ Size = GetDevicePathSize (DevicePath);
+ if (Size == 0) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for duplicate device path
+ //
+ NewDevicePath = AllocateCopyPool (Size, (VOID *) DevicePath);
+
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+ )
+/*++
+
+ Routine Description:
+ Create a new path by appending the second device path to the first.
+
+ Arguments:
+ Src1 - Points to the first device path. If NULL, then it is ignored.
+ Src2 - Points to the second device path. If NULL, then it is ignored.
+
+ Returns:
+ Pointer - A pointer to the newly created device path.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+{
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath;
+
+ //
+ // If there's only 1 path, just duplicate it
+ //
+ if (Src1 == NULL) {
+ ASSERT (!IsDevicePathUnpacked (Src2));
+ return DuplicateDevicePath (Src2);
+ }
+
+ if (Src2 == NULL) {
+ ASSERT (!IsDevicePathUnpacked (Src1));
+ return DuplicateDevicePath (Src1);
+ }
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL
+ //
+ Size1 = GetDevicePathSize (Src1);
+ Size2 = GetDevicePathSize (Src2);
+ Size = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+ NewDevicePath = AllocateCopyPool (Size, (VOID *) Src1);
+
+ if (NewDevicePath != NULL) {
+ //
+ // Over write Src1 EndNode and do the copy
+ //
+ SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+ CopyMem (SecondDevicePath, (VOID *) Src2, Size2);
+ }
+
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDeviceNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the device node to the device path.
+
+ Arguments:
+ DevicePath - Points to the device path.
+ DeviceNode - Points to the device node.
+
+ Returns:
+ Pointer - A pointer to the allocated device node.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Temp;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN NodeLength;
+
+ if ((DevicePath == NULL) || (DeviceNode == NULL)) {
+ return NULL;
+ }
+
+ //
+ // Build a Node that has a terminator on it
+ //
+ NodeLength = DevicePathNodeLength (DeviceNode);
+
+ Temp = AllocateCopyPool (NodeLength + sizeof (EFI_DEVICE_PATH_PROTOCOL), (VOID *) DeviceNode);
+ if (Temp == NULL) {
+ return NULL;
+ }
+
+ //
+ // Add and end device path node to convert Node to device path
+ //
+ NextNode = NextDevicePathNode (Temp);
+ SetDevicePathEndNode (NextNode);
+
+ //
+ // Append device paths
+ //
+ NewDevicePath = AppendDevicePath (DevicePath, Temp);
+ gBS->FreePool (Temp);
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the specified device path instance to the specified device path.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+ DevicePathInstance - Points to the device path instance.
+
+ Returns:
+ Pointer - A pointer to the newly created device path
+ NULL - Memory could not be allocated or DevicePathInstance is NULL.
+
+--*/
+{
+ UINT8 *Ptr;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ UINTN SrcSize;
+ UINTN InstanceSize;
+
+ if (DevicePathInstance == NULL) {
+ return NULL;
+ }
+
+ if (DevicePath == NULL) {
+ return DuplicateDevicePath (DevicePathInstance);
+ }
+
+ SrcSize = GetDevicePathSize (DevicePath);
+ InstanceSize = GetDevicePathSize (DevicePathInstance);
+
+ Ptr = AllocateCopyPool (SrcSize + InstanceSize, (VOID *) DevicePath);
+ if (Ptr != NULL) {
+
+ DevPath = (EFI_DEVICE_PATH_PROTOCOL *) (Ptr + (SrcSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+ //
+ // Convert the End to an End Instance, since we are
+ // appending another instacne after this one its a good
+ // idea.
+ //
+ DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+ DevPath = NextDevicePathNode (DevPath);
+ CopyMem (DevPath, (VOID *) DevicePathInstance, InstanceSize);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
+ OUT UINTN *DevicePathInstanceSize
+ )
+/*++
+
+ Routine Description:
+ Creates a copy of the current device path instance and returns a pointer to the next device path instance.
+
+ Arguments:
+ DevicePathInstance - On input, this holds the pointer to the current device path
+ instance. On output, this holds the pointer to the next
+ device path instance or NULL if there are no more device
+ path instances in the device path.
+ DevicePathInstanceSize - On output, this holds the size of the device path instance,
+ in bytes or zero, if DevicePathInstance is zero.
+
+ Returns:
+ Pointer - A pointer to the copy of the current device path instance.
+ NULL - DevicePathInstace was NULL on entry or there was insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ EFI_DEVICE_PATH_PROTOCOL *ReturnValue;
+ UINT8 Temp;
+
+ if (*DevicePathInstance == NULL) {
+ if (DevicePathInstanceSize != NULL) {
+ *DevicePathInstanceSize = 0;
+ }
+
+ return NULL;
+ }
+
+ //
+ // Find the end of the device path instance
+ //
+ DevPath = *DevicePathInstance;
+ while (!IsDevicePathEndType (DevPath)) {
+ DevPath = NextDevicePathNode (DevPath);
+ }
+
+ //
+ // Compute the size of the device path instance
+ //
+ if (DevicePathInstanceSize != NULL) {
+ *DevicePathInstanceSize = ((UINTN) DevPath - (UINTN) (*DevicePathInstance)) + 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 (*DevicePathInstance);
+ 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) {
+ *DevicePathInstance = NULL;
+ } else {
+ *DevicePathInstance = NextDevicePathNode (DevPath);
+ }
+
+ return ReturnValue;
+}
+
+BOOLEAN
+IsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns whether a device path is multi-instance.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+
+ Returns:
+ TRUE - The device path has more than one instance
+ FALSE - The device path is empty or contains only a single instance.
+
+--*/
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (DevicePath == NULL) {
+ return FALSE;
+ }
+
+ Node = DevicePath;
+ while (!IsDevicePathEnd (Node)) {
+ if (EfiIsDevicePathEndInstance (Node)) {
+ return TRUE;
+ }
+
+ Node = NextDevicePathNode (Node);
+ }
+
+ return FALSE;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ )
+/*++
+
+ Routine Description:
+ Creates a device node
+
+ Arguments:
+ NodeType - NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+ the new device node.
+ NodeSubType - NodeSubType is the device node sub-type
+ EFI_DEVICE_PATH.SubType) for the new device node.
+ NodeLength - NodeLength is the length of the device node
+ (EFI_DEVICE_PATH.Length) for the new device node.
+
+ Returns:
+ Pointer - A pointer to the newly created device node.
+ NULL - NodeLength is less than
+ the size of the header or there was insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return NULL;
+ }
+
+ Node = (EFI_DEVICE_PATH_PROTOCOL *) AllocateZeroPool ((UINTN) NodeLength);
+ if (Node != NULL) {
+ Node->Type = NodeType;
+ Node->SubType = NodeSubType;
+ SetDevicePathNodeLength (Node, NodeLength);
+ }
+
+ return Node;
+}