From 562d28495df348923812281161e64bc9514e15e6 Mon Sep 17 00:00:00 2001 From: ljin6 Date: Tue, 18 Jul 2006 04:13:40 +0000 Subject: Add DevicePathUtilities DevicePathToText DevciePathFromText USB2HostController protocols git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1037 6f19259b-4bc3-4df7-8a09-765794883524 --- EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c | 107 + EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h | 422 ++++ .../Universal/DevicePath/Dxe/DevicePath.msa | 109 + .../Universal/DevicePath/Dxe/DevicePathFromText.c | 2434 ++++++++++++++++++++ .../Universal/DevicePath/Dxe/DevicePathToText.c | 1526 ++++++++++++ .../Universal/DevicePath/Dxe/DevicePathUtilities.c | 421 ++++ 6 files changed, 5019 insertions(+) create mode 100644 EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c create mode 100644 EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h create mode 100644 EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa create mode 100644 EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c create mode 100644 EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c create mode 100644 EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c (limited to 'EdkModulePkg/Universal') 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 +#include +#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 @@ + + + + + + + DevicePath + DXE_DRIVER + 9B680FCE-AD6B-4F3A-B60B-F59899003443 + 1.0 + Component description file for Device Path Driver. + This driver is for DevicePathUtilities, DevicePahtToText and DevicePathFromText + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + DevicePath + + + + DebugLib + + + PrintLib + + + UefiDriverEntryPoint + + + UefiLib + + + BaseLib + + + BaseMemoryLib + + + MemoryAllocationLib + + + UefiBootServicesTableLib + + + + DevicePath.c + DevicePath.h + DevicePathFromText.c + DevicePathToText.c + DevicePathUtilities.c + + + + + + + + gEfiDebugPortProtocolGuid + + + gEfiDevicePathProtocolGuid + + + gEfiDevicePathUtilitiesProtocolGuid + + + gEfiDevicePathFromTextProtocolGuid + + + gEfiDevicePathToTextProtocolGuid + + + + + gEfiPcAnsiGuid + + + gEfiVT100PlusGuid + + + gEfiVT100Guid + + + gEfiVTUTF8Guid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00090000 + + DevicePathEntryPoint + + + 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 +#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 +#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 +#include +#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; +} -- cgit v1.2.3