From 7dbc50bd244d95fdc1741b9cfc561f0bfd724de1 Mon Sep 17 00:00:00 2001 From: Yonghong Zhu Date: Wed, 27 Dec 2017 14:12:29 +0800 Subject: [PATCH] BaseTools: Add DevicePath support for PCD values Use C code parse device path to output hex string, and Python run command when PCD Value need device path parse. https://bugzilla.tianocore.org/show_bug.cgi?id=541 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Yunhua Feng Signed-off-by: Yonghong Zhu Reviewed-by: Liming Gao --- BaseTools/BinWrappers/PosixLike/DevicePath | 29 + BaseTools/Source/BinaryFiles.txt | 3 +- BaseTools/Source/C/Common/CommonLib.c | 1629 ++++++++ BaseTools/Source/C/Common/CommonLib.h | 304 +- BaseTools/Source/C/DevicePath/DevicePath.c | 186 + .../Source/C/DevicePath/DevicePathFromText.c | 3349 +++++++++++++++++ .../Source/C/DevicePath/DevicePathUtilities.c | 875 +++++ BaseTools/Source/C/DevicePath/GNUmakefile | 30 + BaseTools/Source/C/DevicePath/Makefile | 24 + .../Source/C/DevicePath/UefiDevicePathLib.c | 298 ++ .../Source/C/DevicePath/UefiDevicePathLib.h | 452 +++ BaseTools/Source/C/GNUmakefile | 3 +- .../C/Include/IndustryStandard/Bluetooth.h | 62 + .../Source/C/Include/Protocol/DevicePath.h | 1391 +++++++ .../C/Include/Protocol/DevicePathUtilities.h | 294 ++ BaseTools/Source/C/Makefile | 5 +- BaseTools/Source/Python/Common/Misc.py | 34 +- 17 files changed, 8959 insertions(+), 9 deletions(-) create mode 100755 BaseTools/BinWrappers/PosixLike/DevicePath create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.c create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.c create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.c create mode 100644 BaseTools/Source/C/DevicePath/GNUmakefile create mode 100644 BaseTools/Source/C/DevicePath/Makefile create mode 100644 BaseTools/Source/C/DevicePath/UefiDevicePathLib.c create mode 100644 BaseTools/Source/C/DevicePath/UefiDevicePathLib.h create mode 100644 BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h create mode 100644 BaseTools/Source/C/Include/Protocol/DevicePath.h create mode 100644 BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h diff --git a/BaseTools/BinWrappers/PosixLike/DevicePath b/BaseTools/BinWrappers/PosixLike/DevicePath new file mode 100755 index 0000000000..0945d86d92 --- /dev/null +++ b/BaseTools/BinWrappers/PosixLike/DevicePath @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here +dir=$(dirname "$full_cmd") +cmd=${full_cmd##*/} + +if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ] +then + exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd" +elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ] +then + if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ] + then + echo "BaseTools C Tool binary was not found ($cmd)" + echo "You may need to run:" + echo " make -C $EDK_TOOLS_PATH/Source/C" + else + exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@" + fi +elif [ -e "$dir/../../Source/C/bin/$cmd" ] +then + exec "$dir/../../Source/C/bin/$cmd" "$@" +else + echo "Unable to find the real '$cmd' to run" + echo "This message was printed by" + echo " $0" + exit 127 +fi + diff --git a/BaseTools/Source/BinaryFiles.txt b/BaseTools/Source/BinaryFiles.txt index 7b014a71e4..a5273d4753 100644 --- a/BaseTools/Source/BinaryFiles.txt +++ b/BaseTools/Source/BinaryFiles.txt @@ -11,7 +11,7 @@ # must ensure that files that are required by the cx_freeze frozen binaries are # present in the Bin\Win32 directory. # -# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2014 - 2017, 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. @@ -59,6 +59,7 @@ UPT.exe VfrCompile.exe VolInfo.exe Pkcs7Sign.exe +DevicePath.exe [ExtraFiles.Win32] TestSigningPrivateKey.pem diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index 4a62bec85e..90cc578e61 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -24,6 +24,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "CommonLib.h" #include "EfiUtilityMsgs.h" +#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \ + do { \ + ASSERT (Expression); \ + if (!(Expression)) { \ + return Status; \ + } \ + } while (FALSE) + VOID PeiZeroMem ( IN VOID *Buffer, @@ -731,3 +739,1624 @@ Returns: return PathPointer; #endif } + +CHAR16 +InternalCharToUpper ( + CHAR16 Char + ) +{ + if (Char >= L'a' && Char <= L'z') { + return (CHAR16) (Char - (L'a' - L'A')); + } + + return Char; +} + +UINTN +StrnLenS ( + CONST CHAR16 *String, + UINTN MaxSize + ) +{ + UINTN Length; + + ASSERT (((UINTN) String & BIT0) == 0); + + // + // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero. + // + if ((String == NULL) || (MaxSize == 0)) { + return 0; + } + + Length = 0; + while (String[Length] != 0) { + if (Length >= MaxSize - 1) { + return MaxSize; + } + Length++; + } + return Length; +} + + +VOID * +InternalAllocatePool ( + UINTN AllocationSize + ) +{ + VOID * Memory; + + Memory = malloc(AllocationSize); + ASSERT(Memory != NULL); + return Memory; +} + + +VOID * +InternalReallocatePool ( + UINTN OldSize, + UINTN NewSize, + VOID *OldBuffer OPTIONAL + ) +{ + VOID *NewBuffer; + + NewBuffer = AllocateZeroPool (NewSize); + if (NewBuffer != NULL && OldBuffer != NULL) { + memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); + free(OldBuffer); + } + return NewBuffer; +} + +VOID * +ReallocatePool ( + UINTN OldSize, + UINTN NewSize, + VOID *OldBuffer OPTIONAL + ) +{ + return InternalReallocatePool (OldSize, NewSize, OldBuffer); +} + +/** + Returns the length of a Null-terminated Unicode string. + + This function returns the number of Unicode characters in the Null-terminated + Unicode string specified by String. + + If String is NULL, then ASSERT(). + If String is not aligned on a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + + @return The length of String. + +**/ +UINTN +StrLen ( + CONST CHAR16 *String + ) +{ + UINTN Length; + + ASSERT (String != NULL); + ASSERT (((UINTN) String & BIT0) == 0); + + for (Length = 0; *String != L'\0'; String++, Length++) { + // + // If PcdMaximumUnicodeStringLength is not zero, + // length should not more than PcdMaximumUnicodeStringLength + // + } + return Length; +} + +BOOLEAN +InternalSafeStringIsOverlap ( + IN VOID *Base1, + IN UINTN Size1, + IN VOID *Base2, + IN UINTN Size2 + ) +{ + if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) || + (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) { + return TRUE; + } + return FALSE; +} + +BOOLEAN +InternalSafeStringNoStrOverlap ( + IN CHAR16 *Str1, + IN UINTN Size1, + IN CHAR16 *Str2, + IN UINTN Size2 + ) +{ + return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16)); +} + +RETURN_STATUS +StrDecimalToUintnS ( + CONST CHAR16 *String, + CHAR16 **EndPointer, OPTIONAL + UINTN *Data + ) +{ + ASSERT (((UINTN) String & BIT0) == 0); + + // + // 1. Neither String nor Data shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER); + + // + // 2. The length of String shall not be greater than RSIZE_MAX. + // + if (RSIZE_MAX != 0) { + SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); + } + + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == L'0') { + String++; + } + + *Data = 0; + + while (InternalIsDecimalDigitCharacter (*String)) { + // + // If the number represented by String overflows according to the range + // defined by UINTN, then MAX_UINTN is stored in *Data and + // RETURN_UNSUPPORTED is returned. + // + if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) { + *Data = MAX_UINTN; + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + return RETURN_UNSUPPORTED; + } + + *Data = *Data * 10 + (*String - L'0'); + String++; + } + + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + return RETURN_SUCCESS; +} + +/** + Convert a Null-terminated Unicode decimal string to a value of type UINT64. + + This function outputs a value of type UINT64 by interpreting the contents of + the Unicode string specified by String as a decimal number. The format of the + input Unicode string String is: + + [spaces] [decimal digits]. + + The valid decimal digit character is in the range [0-9]. The function will + ignore the pad space, which includes spaces or tab characters, before + [decimal digits]. The running zero in the beginning of [decimal digits] will + be ignored. Then, the function stops at the first character that is a not a + valid decimal character or a Null-terminator, whichever one comes first. + + If String is NULL, then ASSERT(). + If Data is NULL, then ASSERT(). + If String is not aligned in a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + If String has no valid decimal digits in the above format, then 0 is stored + at the location pointed to by Data. + If the number represented by String exceeds the range defined by UINT64, then + MAX_UINT64 is stored at the location pointed to by Data. + + If EndPointer is not NULL, a pointer to the character that stopped the scan + is stored at the location pointed to by EndPointer. If String has no valid + decimal digits right after the optional pad spaces, the value of String is + stored at the location pointed to by EndPointer. + + @param String Pointer to a Null-terminated Unicode string. + @param EndPointer Pointer to character that stops scan. + @param Data Pointer to the converted value. + + @retval RETURN_SUCCESS Value is translated from String. + @retval RETURN_INVALID_PARAMETER If String is NULL. + If Data is NULL. + If PcdMaximumUnicodeStringLength is not + zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode + characters, not including the + Null-terminator. + @retval RETURN_UNSUPPORTED If the number represented by String exceeds + the range defined by UINT64. + +**/ +RETURN_STATUS +StrDecimalToUint64S ( + CONST CHAR16 *String, + CHAR16 **EndPointer, OPTIONAL + UINT64 *Data + ) +{ + ASSERT (((UINTN) String & BIT0) == 0); + + // + // 1. Neither String nor Data shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER); + + // + // 2. The length of String shall not be greater than RSIZE_MAX. + // + if (RSIZE_MAX != 0) { + SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); + } + + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == L'0') { + String++; + } + + *Data = 0; + + while (InternalIsDecimalDigitCharacter (*String)) { + // + // If the number represented by String overflows according to the range + // defined by UINT64, then MAX_UINT64 is stored in *Data and + // RETURN_UNSUPPORTED is returned. + // + if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) { + *Data = MAX_UINT64; + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + return RETURN_UNSUPPORTED; + } + + *Data = (*Data) * 10 + (*String - L'0'); + String++; + } + + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + return RETURN_SUCCESS; +} + +/** + Convert a Null-terminated Unicode hexadecimal string to a value of type + UINTN. + + This function outputs a value of type UINTN by interpreting the contents of + the Unicode string specified by String as a hexadecimal number. The format of + the input Unicode string String is: + + [spaces][zeros][x][hexadecimal digits]. + + The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. + If "x" appears in the input string, it must be prefixed with at least one 0. + The function will ignore the pad space, which includes spaces or tab + characters, before [zeros], [x] or [hexadecimal digit]. The running zero + before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts + after [x] or the first valid hexadecimal digit. Then, the function stops at + the first character that is a not a valid hexadecimal character or NULL, + whichever one comes first. + + If String is NULL, then ASSERT(). + If Data is NULL, then ASSERT(). + If String is not aligned in a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + If String has no valid hexadecimal digits in the above format, then 0 is + stored at the location pointed to by Data. + If the number represented by String exceeds the range defined by UINTN, then + MAX_UINTN is stored at the location pointed to by Data. + + If EndPointer is not NULL, a pointer to the character that stopped the scan + is stored at the location pointed to by EndPointer. If String has no valid + hexadecimal digits right after the optional pad spaces, the value of String + is stored at the location pointed to by EndPointer. + + @param String Pointer to a Null-terminated Unicode string. + @param EndPointer Pointer to character that stops scan. + @param Data Pointer to the converted value. + + @retval RETURN_SUCCESS Value is translated from String. + @retval RETURN_INVALID_PARAMETER If String is NULL. + If Data is NULL. + If PcdMaximumUnicodeStringLength is not + zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode + characters, not including the + Null-terminator. + @retval RETURN_UNSUPPORTED If the number represented by String exceeds + the range defined by UINTN. + +**/ +RETURN_STATUS +StrHexToUintnS ( + CONST CHAR16 *String, + CHAR16 **EndPointer, OPTIONAL + UINTN *Data + ) +{ + ASSERT (((UINTN) String & BIT0) == 0); + + // + // 1. Neither String nor Data shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER); + + // + // 2. The length of String shall not be greater than RSIZE_MAX. + // + if (RSIZE_MAX != 0) { + SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); + } + + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == L'0') { + String++; + } + + if (InternalCharToUpper (*String) == L'X') { + if (*(String - 1) != L'0') { + *Data = 0; + return RETURN_SUCCESS; + } + // + // Skip the 'X' + // + String++; + } + + *Data = 0; + + while (InternalIsHexaDecimalDigitCharacter (*String)) { + // + // If the number represented by String overflows according to the range + // defined by UINTN, then MAX_UINTN is stored in *Data and + // RETURN_UNSUPPORTED is returned. + // + if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) { + *Data = MAX_UINTN; + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + return RETURN_UNSUPPORTED; + } + + *Data = (*Data << 4) + InternalHexCharToUintn (*String); + String++; + } + + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + return RETURN_SUCCESS; +} +RETURN_STATUS +StrHexToUint64S ( + CONST CHAR16 *String, + CHAR16 **EndPointer, OPTIONAL + UINT64 *Data + ) +{ + ASSERT (((UINTN) String & BIT0) == 0); + + // + // 1. Neither String nor Data shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER); + + // + // 2. The length of String shall not be greater than RSIZE_MAX. + // + if (RSIZE_MAX != 0) { + SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); + } + + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == L'0') { + String++; + } + + if (InternalCharToUpper (*String) == L'X') { + if (*(String - 1) != L'0') { + *Data = 0; + return RETURN_SUCCESS; + } + // + // Skip the 'X' + // + String++; + } + + *Data = 0; + + while (InternalIsHexaDecimalDigitCharacter (*String)) { + // + // If the number represented by String overflows according to the range + // defined by UINT64, then MAX_UINT64 is stored in *Data and + // RETURN_UNSUPPORTED is returned. + // + if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) { + *Data = MAX_UINT64; + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + return RETURN_UNSUPPORTED; + } + + *Data = ((*Data) << 4) + InternalHexCharToUintn (*String); + String++; + } + + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) String; + } + return RETURN_SUCCESS; +} + +UINT64 +StrDecimalToUint64 ( + CONST CHAR16 *String + ) +{ + UINT64 Result; + + StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result); + return Result; +} + + +UINT64 +StrHexToUint64 ( + CONST CHAR16 *String + ) +{ + UINT64 Result; + + StrHexToUint64S (String, (CHAR16 **) NULL, &Result); + return Result; +} + +UINTN +StrDecimalToUintn ( + CONST CHAR16 *String + ) +{ + UINTN Result; + + StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result); + return Result; +} + +UINTN +StrHexToUintn ( + CONST CHAR16 *String + ) +{ + UINTN Result; + + StrHexToUintnS (String, (CHAR16 **) NULL, &Result); + return Result; +} + +UINTN +StrSize ( + CONST CHAR16 *String + ) +{ + return (StrLen (String) + 1) * sizeof (*String); +} + + +UINT64 +ReadUnaligned64 ( + CONST UINT64 *Buffer + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer; +} + +UINT64 +WriteUnaligned64 ( + UINT64 *Buffer, + UINT64 Value + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer = Value; +} + + +EFI_GUID * +CopyGuid ( + EFI_GUID *DestinationGuid, + CONST EFI_GUID *SourceGuid + ) +{ + WriteUnaligned64 ( + (UINT64*)DestinationGuid, + ReadUnaligned64 ((CONST UINT64*)SourceGuid) + ); + WriteUnaligned64 ( + (UINT64*)DestinationGuid + 1, + ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1) + ); + return DestinationGuid; +} + +UINT16 +SwapBytes16 ( + UINT16 Value + ) +{ + return (UINT16) ((Value<< 8) | (Value>> 8)); +} + + +UINT32 +SwapBytes32 ( + UINT32 Value + ) +{ + UINT32 LowerBytes; + UINT32 HigherBytes; + + LowerBytes = (UINT32) SwapBytes16 ((UINT16) Value); + HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16)); + return (LowerBytes << 16 | HigherBytes); +} + +BOOLEAN +InternalIsDecimalDigitCharacter ( + CHAR16 Char + ) +{ + return (BOOLEAN) (Char >= L'0' && Char <= L'9'); +} + +VOID * +InternalAllocateCopyPool ( + UINTN AllocationSize, + CONST VOID *Buffer + ) +{ + VOID *Memory; + + ASSERT (Buffer != NULL); + ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1)); + + Memory = malloc (AllocationSize); + if (Memory != NULL) { + Memory = memcpy (Memory, Buffer, AllocationSize); + } + return Memory; +} + +BOOLEAN +InternalIsHexaDecimalDigitCharacter ( + CHAR16 Char + ) +{ + + return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) || + (Char >= L'A' && Char <= L'F') || + (Char >= L'a' && Char <= L'f')); +} + +UINTN +InternalHexCharToUintn ( + CHAR16 Char + ) +{ + if (InternalIsDecimalDigitCharacter (Char)) { + return Char - L'0'; + } + + return (10 + InternalCharToUpper (Char) - L'A'); +} + + +/** + Convert a Null-terminated Unicode hexadecimal string to a byte array. + + This function outputs a byte array by interpreting the contents of + the Unicode string specified by String in hexadecimal format. The format of + the input Unicode string String is: + + [XX]* + + X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F]. + The function decodes every two hexadecimal digit characters as one byte. The + decoding stops after Length of characters and outputs Buffer containing + (Length / 2) bytes. + + If String is not aligned in a 16-bit boundary, then ASSERT(). + + If String is NULL, then ASSERT(). + + If Buffer is NULL, then ASSERT(). + + If Length is not multiple of 2, then ASSERT(). + + If PcdMaximumUnicodeStringLength is not zero and Length is greater than + PcdMaximumUnicodeStringLength, then ASSERT(). + + If MaxBufferSize is less than (Length / 2), then ASSERT(). + + @param String Pointer to a Null-terminated Unicode string. + @param Length The number of Unicode characters to decode. + @param Buffer Pointer to the converted bytes array. + @param MaxBufferSize The maximum size of Buffer. + + @retval RETURN_SUCCESS Buffer is translated from String. + @retval RETURN_INVALID_PARAMETER If String is NULL. + If Data is NULL. + If Length is not multiple of 2. + If PcdMaximumUnicodeStringLength is not zero, + and Length is greater than + PcdMaximumUnicodeStringLength. + @retval RETURN_UNSUPPORTED If Length of characters from String contain + a character that is not valid hexadecimal + digit characters, or a Null-terminator. + @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2). +**/ +RETURN_STATUS +StrHexToBytes ( + CONST CHAR16 *String, + UINTN Length, + UINT8 *Buffer, + UINTN MaxBufferSize + ) +{ + UINTN Index; + + ASSERT (((UINTN) String & BIT0) == 0); + + // + // 1. None of String or Buffer shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER); + + // + // 2. Length shall not be greater than RSIZE_MAX. + // + if (RSIZE_MAX != 0) { + SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER); + } + + // + // 3. Length shall not be odd. + // + SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER); + + // + // 4. MaxBufferSize shall equal to or greater than Length / 2. + // + SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL); + + // + // 5. String shall not contains invalid hexadecimal digits. + // + for (Index = 0; Index < Length; Index++) { + if (!InternalIsHexaDecimalDigitCharacter (String[Index])) { + break; + } + } + if (Index != Length) { + return RETURN_UNSUPPORTED; + } + + // + // Convert the hex string to bytes. + // + for(Index = 0; Index < Length; Index++) { + + // + // For even characters, write the upper nibble for each buffer byte, + // and for even characters, the lower nibble. + // + if ((Index & BIT0) == 0) { + Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4; + } else { + Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]); + } + } + return RETURN_SUCCESS; +} + +/** + Convert a Null-terminated Unicode GUID string to a value of type + EFI_GUID. + + This function outputs a GUID value by interpreting the contents of + the Unicode string specified by String. The format of the input + Unicode string String consists of 36 characters, as follows: + + aabbccdd-eeff-gghh-iijj-kkllmmnnoopp + + The pairs aa - pp are two characters in the range [0-9], [a-f] and + [A-F], with each pair representing a single byte hexadecimal value. + + The mapping between String and the EFI_GUID structure is as follows: + aa Data1[24:31] + bb Data1[16:23] + cc Data1[8:15] + dd Data1[0:7] + ee Data2[8:15] + ff Data2[0:7] + gg Data3[8:15] + hh Data3[0:7] + ii Data4[0:7] + jj Data4[8:15] + kk Data4[16:23] + ll Data4[24:31] + mm Data4[32:39] + nn Data4[40:47] + oo Data4[48:55] + pp Data4[56:63] + + If String is NULL, then ASSERT(). + If Guid is NULL, then ASSERT(). + If String is not aligned in a 16-bit boundary, then ASSERT(). + + @param String Pointer to a Null-terminated Unicode string. + @param Guid Pointer to the converted GUID. + + @retval RETURN_SUCCESS Guid is translated from String. + @retval RETURN_INVALID_PARAMETER If String is NULL. + If Data is NULL. + @retval RETURN_UNSUPPORTED If String is not as the above format. + +**/ +RETURN_STATUS +StrToGuid ( + CONST CHAR16 *String, + EFI_GUID *Guid + ) +{ + RETURN_STATUS Status; + EFI_GUID LocalGuid; + + ASSERT (((UINTN) String & BIT0) == 0); + + // + // 1. None of String or Guid shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER); + + // + // Get aabbccdd in big-endian. + // + Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1)); + if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') { + return RETURN_UNSUPPORTED; + } + // + // Convert big-endian to little-endian. + // + LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1); + String += 2 * sizeof (LocalGuid.Data1) + 1; + + // + // Get eeff in big-endian. + // + Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2)); + if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') { + return RETURN_UNSUPPORTED; + } + // + // Convert big-endian to little-endian. + // + LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2); + String += 2 * sizeof (LocalGuid.Data2) + 1; + + // + // Get gghh in big-endian. + // + Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3)); + if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') { + return RETURN_UNSUPPORTED; + } + // + // Convert big-endian to little-endian. + // + LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3); + String += 2 * sizeof (LocalGuid.Data3) + 1; + + // + // Get iijj. + // + Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2); + if (RETURN_ERROR (Status) || String[2 * 2] != L'-') { + return RETURN_UNSUPPORTED; + } + String += 2 * 2 + 1; + + // + // Get kkllmmnnoopp. + // + Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6); + if (RETURN_ERROR (Status)) { + return RETURN_UNSUPPORTED; + } + + CopyGuid (Guid, &LocalGuid); + return RETURN_SUCCESS; +} + +/** + Compares up to a specified length the contents of two Null-terminated Unicode strings, + and returns the difference between the first mismatched Unicode characters. + + This function compares the Null-terminated Unicode string FirstString to the + Null-terminated Unicode string SecondString. At most, Length Unicode + characters will be compared. If Length is 0, then 0 is returned. If + FirstString is identical to SecondString, then 0 is returned. Otherwise, the + value returned is the first mismatched Unicode character in SecondString + subtracted from the first mismatched Unicode character in FirstString. + + If Length > 0 and FirstString is NULL, then ASSERT(). + If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT(). + If Length > 0 and SecondString is NULL, then ASSERT(). + If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Length is greater than + PcdMaximumUnicodeStringLength, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, + then ASSERT(). + + @param FirstString A pointer to a Null-terminated Unicode string. + @param SecondString A pointer to a Null-terminated Unicode string. + @param Length The maximum number of Unicode characters to compare. + + @retval 0 FirstString is identical to SecondString. + @return others FirstString is not identical to SecondString. + +**/ +INTN +StrnCmp ( + CONST CHAR16 *FirstString, + CONST CHAR16 *SecondString, + UINTN Length + ) +{ + if (Length == 0) { + return 0; + } + + // + // ASSERT both strings are less long than PcdMaximumUnicodeStringLength. + // Length tests are performed inside StrLen(). + // + ASSERT (StrSize (FirstString) != 0); + ASSERT (StrSize (SecondString) != 0); + + while ((*FirstString != L'\0') && + (*SecondString != L'\0') && + (*FirstString == *SecondString) && + (Length > 1)) { + FirstString++; + SecondString++; + Length--; + } + + return *FirstString - *SecondString; +} + +VOID * +AllocateCopyPool ( + UINTN AllocationSize, + CONST VOID *Buffer + ) +{ + return InternalAllocateCopyPool (AllocationSize, Buffer); +} + +INTN +StrCmp ( + CONST CHAR16 *FirstString, + CONST CHAR16 *SecondString + ) +{ + // + // ASSERT both strings are less long than PcdMaximumUnicodeStringLength + // + ASSERT (StrSize (FirstString) != 0); + ASSERT (StrSize (SecondString) != 0); + + while ((*FirstString != L'\0') && (*FirstString == *SecondString)) { + FirstString++; + SecondString++; + } + return *FirstString - *SecondString; +} + +UINT64 +SwapBytes64 ( + UINT64 Value + ) +{ + return InternalMathSwapBytes64 (Value); +} + +UINT64 +InternalMathSwapBytes64 ( + UINT64 Operand + ) +{ + UINT64 LowerBytes; + UINT64 HigherBytes; + + LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand); + HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32)); + + return (LowerBytes << 32 | HigherBytes); +} + +RETURN_STATUS +StrToIpv4Address ( + CONST CHAR16 *String, + CHAR16 **EndPointer, + EFI_IPv4_ADDRESS *Address, + UINT8 *PrefixLength + ) +{ + RETURN_STATUS Status; + UINTN AddressIndex; + UINTN Uintn; + EFI_IPv4_ADDRESS LocalAddress; + UINT8 LocalPrefixLength; + CHAR16 *Pointer; + + LocalPrefixLength = MAX_UINT8; + LocalAddress.Addr[0] = 0; + + ASSERT (((UINTN) String & BIT0) == 0); + + // + // 1. None of String or Guid shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER); + + for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) { + if (!InternalIsDecimalDigitCharacter (*Pointer)) { + // + // D or P contains invalid characters. + // + break; + } + + // + // Get D or P. + // + Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer, &Uintn); + if (RETURN_ERROR (Status)) { + return RETURN_UNSUPPORTED; + } + if (AddressIndex == ARRAY_SIZE (Address->Addr)) { + // + // It's P. + // + if (Uintn > 32) { + return RETURN_UNSUPPORTED; + } + LocalPrefixLength = (UINT8) Uintn; + } else { + // + // It's D. + // + if (Uintn > MAX_UINT8) { + return RETURN_UNSUPPORTED; + } + LocalAddress.Addr[AddressIndex] = (UINT8) Uintn; + AddressIndex++; + } + + // + // Check the '.' or '/', depending on the AddressIndex. + // + if (AddressIndex == ARRAY_SIZE (Address->Addr)) { + if (*Pointer == L'/') { + // + // '/P' is in the String. + // Skip "/" and get P in next loop. + // + Pointer++; + } else { + // + // '/P' is not in the String. + // + break; + } + } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) { + if (*Pointer == L'.') { + // + // D should be followed by '.' + // + Pointer++; + } else { + return RETURN_UNSUPPORTED; + } + } + } + + if (AddressIndex < ARRAY_SIZE (Address->Addr)) { + return RETURN_UNSUPPORTED; + } + + memcpy (Address, &LocalAddress, sizeof (*Address)); + if (PrefixLength != NULL) { + *PrefixLength = LocalPrefixLength; + } + if (EndPointer != NULL) { + *EndPointer = Pointer; + } + + return RETURN_SUCCESS; +} + +RETURN_STATUS +StrToIpv6Address ( + CONST CHAR16 *String, + CHAR16 **EndPointer, + EFI_IPv6_ADDRESS *Address, + UINT8 *PrefixLength + ) +{ + RETURN_STATUS Status; + UINTN AddressIndex; + UINTN Uintn; + EFI_IPv6_ADDRESS LocalAddress; + UINT8 LocalPrefixLength; + CONST CHAR16 *Pointer; + CHAR16 *End; + UINTN CompressStart; + BOOLEAN ExpectPrefix; + + LocalPrefixLength = MAX_UINT8; + CompressStart = ARRAY_SIZE (Address->Addr); + ExpectPrefix = FALSE; + + ASSERT (((UINTN) String & BIT0) == 0); + + // + // 1. None of String or Guid shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER); + + for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) { + if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) { + if (*Pointer != L':') { + // + // ":" or "/" should be followed by digit characters. + // + return RETURN_UNSUPPORTED; + } + + // + // Meet second ":" after previous ":" or "/" + // or meet first ":" in the beginning of String. + // + if (ExpectPrefix) { + // + // ":" shall not be after "/" + // + return RETURN_UNSUPPORTED; + } + + if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) { + // + // "::" can only appear once. + // "::" can only appear when address is not full length. + // + return RETURN_UNSUPPORTED; + } else { + // + // Remember the start of zero compressing. + // + CompressStart = AddressIndex; + Pointer++; + + if (CompressStart == 0) { + if (*Pointer != L':') { + // + // Single ":" shall not be in the beginning of String. + // + return RETURN_UNSUPPORTED; + } + Pointer++; + } + } + } + + if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) { + if (*Pointer == L'/') { + // + // Might be optional "/P" after "::". + // + if (CompressStart != AddressIndex) { + return RETURN_UNSUPPORTED; + } + } else { + break; + } + } else { + if (!ExpectPrefix) { + // + // Get X. + // + Status = StrHexToUintnS (Pointer, &End, &Uintn); + if (RETURN_ERROR (Status) || End - Pointer > 4) { + // + // Number of hexadecimal digit characters is no more than 4. + // + return RETURN_UNSUPPORTED; + } + Pointer = End; + // + // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4. + // + ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr)); + LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8); + LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn; + AddressIndex += 2; + } else { + // + // Get P, then exit the loop. + // + Status = StrDecimalToUintnS (Pointer, &End, &Uintn); + if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) { + // + // Prefix length should not exceed 128. + // + return RETURN_UNSUPPORTED; + } + LocalPrefixLength = (UINT8) Uintn; + Pointer = End; + break; + } + } + + // + // Skip ':' or "/" + // + if (*Pointer == L'/') { + ExpectPrefix = TRUE; + } else if (*Pointer == L':') { + if (AddressIndex == ARRAY_SIZE (Address->Addr)) { + // + // Meet additional ":" after all 8 16-bit address + // + break; + } + } else { + // + // Meet other character that is not "/" or ":" after all 8 16-bit address + // + break; + } + Pointer++; + } + + if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) || + (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr)) + ) { + // + // Full length of address shall not have compressing zeros. + // Non-full length of address shall have compressing zeros. + // + return RETURN_UNSUPPORTED; + } + memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart); + memset (&Address->Addr[CompressStart], 0, ARRAY_SIZE (Address->Addr) - AddressIndex); + if (AddressIndex > CompressStart) { + memcpy ( + &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex], + &LocalAddress.Addr[CompressStart], + AddressIndex - CompressStart + ); + } + + if (PrefixLength != NULL) { + *PrefixLength = LocalPrefixLength; + } + if (EndPointer != NULL) { + *EndPointer = (CHAR16 *) Pointer; + } + + return RETURN_SUCCESS; +} + + +RETURN_STATUS +UnicodeStrToAsciiStrS ( + CONST CHAR16 *Source, + CHAR8 *Destination, + UINTN DestMax + ) +{ + UINTN SourceLen; + + ASSERT (((UINTN) Source & BIT0) == 0); + + // + // 1. Neither Destination nor Source shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER); + + // + // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX. + // + if (ASCII_RSIZE_MAX != 0) { + SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); + } + if (RSIZE_MAX != 0) { + SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); + } + + // + // 3. DestMax shall not equal zero. + // + SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER); + + // + // 4. DestMax shall be greater than StrnLenS (Source, DestMax). + // + SourceLen = StrnLenS (Source, DestMax); + SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); + + // + // 5. Copying shall not take place between objects that overlap. + // + SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED); + + // + // convert string + // + while (*Source != '\0') { + // + // If any Unicode characters in Source contain + // non-zero value in the upper 8 bits, then ASSERT(). + // + ASSERT (*Source < 0x100); + *(Destination++) = (CHAR8) *(Source++); + } + *Destination = '\0'; + + return RETURN_SUCCESS; +} + +RETURN_STATUS +StrCpyS ( + CHAR16 *Destination, + UINTN DestMax, + CONST CHAR16 *Source + ) +{ + UINTN SourceLen; + + ASSERT (((UINTN) Destination & BIT0) == 0); + ASSERT (((UINTN) Source & BIT0) == 0); + + // + // 1. Neither Destination nor Source shall be a null pointer. + // + SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER); + SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER); + + // + // 2. DestMax shall not be greater than RSIZE_MAX. + // + if (RSIZE_MAX != 0) { + SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); + } + + // + // 3. DestMax shall not equal zero. + // + SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER); + + // + // 4. DestMax shall be greater than StrnLenS(Source, DestMax). + // + SourceLen = StrnLenS (Source, DestMax); + SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); + + // + // 5. Copying shall not take place between objects that overlap. + // + SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); + + // + // The StrCpyS function copies the string pointed to by Source (including the terminating + // null character) into the array pointed to by Destination. + // + while (*Source != 0) { + *(Destination++) = *(Source++); + } + *Destination = 0; + + return RETURN_SUCCESS; +} + +VOID * +AllocateZeroPool ( + UINTN AllocationSize + ) +{ + VOID * Memory; + Memory = malloc(AllocationSize); + ASSERT (Memory != NULL); + if (Memory == NULL) { + fprintf(stderr, "Not memory for malloc\n"); + } + memset(Memory, 0, AllocationSize); + return Memory; +} + +VOID * +AllocatePool ( + UINTN AllocationSize + ) +{ + return InternalAllocatePool (AllocationSize); +} + +UINT16 +WriteUnaligned16 ( + UINT16 *Buffer, + UINT16 Value + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer = Value; +} + +UINT16 +ReadUnaligned16 ( + CONST UINT16 *Buffer + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer; +} +/** + Return whether the integer string is a hex string. + + @param Str The integer string + + @retval TRUE Hex string + @retval FALSE Decimal string + +**/ +BOOLEAN +IsHexStr ( + CHAR16 *Str + ) +{ + // + // skip preceeding white space + // + while ((*Str != 0) && *Str == L' ') { + Str ++; + } + // + // skip preceeding zeros + // + while ((*Str != 0) && *Str == L'0') { + Str ++; + } + + return (BOOLEAN) (*Str == L'x' || *Str == L'X'); +} + +/** + + Convert integer string to uint. + + @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. + + @return A UINTN value represented by Str + +**/ +UINTN +Strtoi ( + CHAR16 *Str + ) +{ + if (IsHexStr (Str)) { + return StrHexToUintn (Str); + } else { + return StrDecimalToUintn (Str); + } +} + +/** + + Convert integer string to 64 bit data. + + @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. + @param Data A pointer to the UINT64 value represented by Str + +**/ +VOID +Strtoi64 ( + CHAR16 *Str, + UINT64 *Data + ) +{ + if (IsHexStr (Str)) { + *Data = StrHexToUint64 (Str); + } else { + *Data = StrDecimalToUint64 (Str); + } +} + +/** + Converts a Unicode string to ASCII string. + + @param Str The equivalent Unicode string + @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points + to the next ASCII string next to it + +**/ +VOID +StrToAscii ( + CHAR16 *Str, + CHAR8 **AsciiStr + ) +{ + CHAR8 *Dest; + + Dest = *AsciiStr; + while (!IS_NULL (*Str)) { + *(Dest++) = (CHAR8) *(Str++); + } + *Dest = 0; + + // + // Return the string next to it + // + *AsciiStr = Dest + 1; +} + +/** + Gets current sub-string from a string list, before return + the list header is moved to next sub-string. The sub-string is separated + by the specified character. For example, the separator is ',', the string + list is "2,0,3", it returns "2", the remain list move to "0,3" + + @param List A string list separated by the specified separator + @param Separator The separator character + + @return A pointer to the current sub-string + +**/ +CHAR16 * +SplitStr ( + CHAR16 **List, + CHAR16 Separator + ) +{ + CHAR16 *Str; + CHAR16 *ReturnStr; + + Str = *List; + ReturnStr = Str; + + if (IS_NULL (*Str)) { + return ReturnStr; + } + + // + // Find first occurrence of the separator + // + while (!IS_NULL (*Str)) { + if (*Str == Separator) { + break; + } + Str++; + } + + if (*Str == Separator) { + // + // Find a sub-string, terminate it + // + *Str = L'\0'; + Str++; + } + + // + // Move to next sub-string + // + *List = Str; + return ReturnStr; +} + diff --git a/BaseTools/Source/C/Common/CommonLib.h b/BaseTools/Source/C/Common/CommonLib.h index 2041b89e2d..9da16e8cd3 100644 --- a/BaseTools/Source/C/Common/CommonLib.h +++ b/BaseTools/Source/C/Common/CommonLib.h @@ -1,7 +1,7 @@ /** @file Common library assistance routines. -Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2017, 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 @@ -17,10 +17,31 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include +#include #define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination #define MAX_LONG_FILE_PATH 500 +#define MAX_UINTN MAX_ADDRESS +#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL) +#define MAX_UINT16 ((UINT16)0xFFFF) +#define MAX_UINT8 ((UINT8)0xFF) +#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0])) +#define ASCII_RSIZE_MAX 1000000 +#ifndef RSIZE_MAX +#define RSIZE_MAX 1000000 +#endif + +#define IS_COMMA(a) ((a) == L',') +#define IS_HYPHEN(a) ((a) == L'-') +#define IS_DOT(a) ((a) == L'.') +#define IS_LEFT_PARENTH(a) ((a) == L'(') +#define IS_RIGHT_PARENTH(a) ((a) == L')') +#define IS_SLASH(a) ((a) == L'/') +#define IS_NULL(a) ((a) == L'\0') + +#define ASSERT(x) assert(x) + #ifdef __cplusplus extern "C" { #endif @@ -149,6 +170,285 @@ CHAR8 * LongFilePath ( IN CHAR8 *FileName ); + +UINTN +StrLen ( + CONST CHAR16 *String + ); + +VOID * +AllocateCopyPool ( + UINTN AllocationSize, + CONST VOID *Buffer + ); + +INTN +StrnCmp ( + CONST CHAR16 *FirstString, + CONST CHAR16 *SecondString, + UINTN Length + ); + +RETURN_STATUS +StrToGuid ( + CONST CHAR16 *String, + EFI_GUID *Guid + ); + +RETURN_STATUS +StrHexToBytes ( + CONST CHAR16 *String, + UINTN Length, + UINT8 *Buffer, + UINTN MaxBufferSize + ); + +UINTN +InternalHexCharToUintn ( + CHAR16 Char + ); + +VOID * +InternalAllocateCopyPool ( + UINTN AllocationSize, + CONST VOID *Buffer + ); + +BOOLEAN +InternalIsDecimalDigitCharacter ( + CHAR16 Char + ); + +UINT32 +SwapBytes32 ( + UINT32 Value + ); + +UINT16 +SwapBytes16 ( + UINT16 Value + ); + +EFI_GUID * +CopyGuid ( + EFI_GUID *DestinationGuid, + CONST EFI_GUID *SourceGuid + ); + +UINT64 +WriteUnaligned64 ( + UINT64 *Buffer, + UINT64 Value + ); + +UINT64 +ReadUnaligned64 ( + CONST UINT64 *Buffer + ); + +UINTN +StrSize ( + CONST CHAR16 *String + ); + +UINTN +StrHexToUintn ( + CONST CHAR16 *String + ); + +UINTN +StrDecimalToUintn ( + CONST CHAR16 *String + ); + +UINT64 +StrHexToUint64 ( + CONST CHAR16 *String + ); + +UINT64 +StrDecimalToUint64 ( + CONST CHAR16 *String + ); + +RETURN_STATUS +StrHexToUint64S ( + CONST CHAR16 *String, + CHAR16 **EndPointer, + UINT64 *Data + ); + +RETURN_STATUS +StrHexToUintnS ( + CONST CHAR16 *String, + CHAR16 **EndPointer, OPTIONAL + UINTN *Data + ); + +RETURN_STATUS +StrDecimalToUint64S ( + CONST CHAR16 *String, + CHAR16 **EndPointer, OPTIONAL + UINT64 *Data + ); + +RETURN_STATUS +StrDecimalToUintnS ( + CONST CHAR16 *String, + CHAR16 **EndPointer, OPTIONAL + UINTN *Data + ); + +VOID * +ReallocatePool ( + UINTN OldSize, + UINTN NewSize, + VOID *OldBuffer OPTIONAL + ); + +VOID * +InternalReallocatePool ( + UINTN OldSize, + UINTN NewSize, + VOID *OldBuffer OPTIONAL + ); + +VOID * +InternalAllocateZeroPool ( + UINTN AllocationSize + ) ; + +VOID * +InternalAllocatePool ( + UINTN AllocationSize + ); + +UINTN +StrnLenS ( + CONST CHAR16 *String, + UINTN MaxSize + ); + +CHAR16 +InternalCharToUpper ( + CHAR16 Char + ); + +INTN +StrCmp ( + CONST CHAR16 *FirstString, + CONST CHAR16 *SecondString + ); + +UINT64 +SwapBytes64 ( + UINT64 Value + ); + +UINT64 +InternalMathSwapBytes64 ( + UINT64 Operand + ); + +RETURN_STATUS +StrToIpv4Address ( + CONST CHAR16 *String, + CHAR16 **EndPointer, + EFI_IPv4_ADDRESS *Address, + UINT8 *PrefixLength + ); + +RETURN_STATUS +StrToIpv6Address ( + CONST CHAR16 *String, + CHAR16 **EndPointer, + EFI_IPv6_ADDRESS *Address, + UINT8 *PrefixLength + ); + +RETURN_STATUS +StrCpyS ( + CHAR16 *Destination, + UINTN DestMax, + CONST CHAR16 *Source + ); + +RETURN_STATUS +UnicodeStrToAsciiStrS ( + CONST CHAR16 *Source, + CHAR8 *Destination, + UINTN DestMax + ); +VOID * +AllocatePool ( + UINTN AllocationSize + ); + +UINT16 +WriteUnaligned16 ( + UINT16 *Buffer, + UINT16 Value + ); + +UINT16 +ReadUnaligned16 ( + CONST UINT16 *Buffer + ); + +VOID * +AllocateZeroPool ( + UINTN AllocationSize + ); + +BOOLEAN +InternalIsHexaDecimalDigitCharacter ( + CHAR16 Char + ); + +BOOLEAN +InternalSafeStringIsOverlap ( + IN VOID *Base1, + IN UINTN Size1, + IN VOID *Base2, + IN UINTN Size2 + ); + +BOOLEAN +InternalSafeStringNoStrOverlap ( + IN CHAR16 *Str1, + IN UINTN Size1, + IN CHAR16 *Str2, + IN UINTN Size2 + ); + +BOOLEAN +IsHexStr ( + CHAR16 *Str + ); + +UINTN +Strtoi ( + CHAR16 *Str + ); + +VOID +Strtoi64 ( + CHAR16 *Str, + UINT64 *Data + ); + +VOID +StrToAscii ( + CHAR16 *Str, + CHAR8 **AsciiStr + ); + +CHAR16 * +SplitStr ( + CHAR16 **List, + CHAR16 Separator + ); + /*++ Routine Description: @@ -166,8 +466,6 @@ Returns: } #endif -#define ASSERT(x) assert(x) - #ifdef __GNUC__ #include #include diff --git a/BaseTools/Source/C/DevicePath/DevicePath.c b/BaseTools/Source/C/DevicePath/DevicePath.c new file mode 100644 index 0000000000..4c87163209 --- /dev/null +++ b/BaseTools/Source/C/DevicePath/DevicePath.c @@ -0,0 +1,186 @@ +/** @file + Definition for Device Path Tool. + +Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "UefiDevicePathLib.h" + +// +// Utility Name +// +#define UTILITY_NAME "DevicePath" + +// +// Utility version information +// +#define UTILITY_MAJOR_VERSION 0 +#define UTILITY_MINOR_VERSION 1 + +EFI_GUID gEfiDebugPortDevicePathGuid = DEVICE_PATH_MESSAGING_DEBUGPORT; +EFI_GUID gEfiPcAnsiGuid = EFI_PC_ANSI_GUID; +EFI_GUID gEfiVT100Guid = EFI_VT_100_GUID; +EFI_GUID gEfiVT100PlusGuid = EFI_VT_100_PLUS_GUID; +EFI_GUID gEfiVTUTF8Guid = EFI_VT_UTF8_GUID; +EFI_GUID gEfiUartDevicePathGuid = EFI_UART_DEVICE_PATH_GUID; +EFI_GUID gEfiSasDevicePathGuid = EFI_SAS_DEVICE_PATH_GUID; +EFI_GUID gEfiVirtualDiskGuid = EFI_VIRTUAL_DISK_GUID; +EFI_GUID gEfiVirtualCdGuid = EFI_VIRTUAL_CD_GUID; +EFI_GUID gEfiPersistentVirtualDiskGuid = EFI_PERSISTENT_VIRTUAL_DISK_GUID; +EFI_GUID gEfiPersistentVirtualCdGuid = EFI_PERSISTENT_VIRTUAL_CD_GUID; + +STATIC +VOID +Version ( + VOID +) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION); +} + +STATIC +VOID +Usage ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + // + // Summary usage + // + fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME); + + // + // Copyright declaration + // + fprintf (stdout, "Copyright (c) 2017, Intel Corporation. All rights reserved.\n\n"); + // + // Details Option + // + fprintf (stdout, "Options:\n"); + fprintf (stdout, " DevicePathString Device Path string is specified, no space character.\n" + " Example: \"PciRoot(0)/Pci(0,0)\"\n"); + + fprintf (stdout, " --version Show program's version number and exit.\n"); + fprintf (stdout, " -h, --help Show this help message and exit.\n"); +} + + +void print_mem(void const *vp, size_t n) +{ + unsigned char const *p = vp; + for (size_t i=0; iType == END_DEVICE_PATH_TYPE) && (DevicePath->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)) ) + { + print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1] << 8)); + DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)DevicePath + (DevicePath->Length[0] | DevicePath->Length[1] << 8)); + } + print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1] << 8)); + putchar('\n'); + return STATUS_SUCCESS; +} diff --git a/BaseTools/Source/C/DevicePath/DevicePathFromText.c b/BaseTools/Source/C/DevicePath/DevicePathFromText.c new file mode 100644 index 0000000000..3d2f5a811c --- /dev/null +++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.c @@ -0,0 +1,3349 @@ +/** @file + DevicePathFromText protocol as defined in the UEFI 2.0 specification. + +Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "UefiDevicePathLib.h" + +/** + + Duplicates a string. + + @param Src Source string. + + @return The duplicated string. + +**/ +CHAR16 * +UefiDevicePathLibStrDuplicate ( + CONST CHAR16 *Src + ) +{ + return AllocateCopyPool (StrSize (Src), Src); +} + +/** + + Get parameter in a pair of parentheses follow the given node name. + For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1". + + @param Str Device Path Text. + @param NodeName Name of the node. + + @return Parameter text for the node. + +**/ +CHAR16 * +GetParamByNodeName ( + CHAR16 *Str, + CHAR16 *NodeName + ) +{ + CHAR16 *ParamStr; + CHAR16 *StrPointer; + UINTN NodeNameLength; + UINTN ParameterLength; + + // + // Check whether the node name matchs + // + NodeNameLength = StrLen (NodeName); + if (StrnCmp (Str, NodeName, NodeNameLength) != 0) { + return NULL; + } + + ParamStr = Str + NodeNameLength; + if (!IS_LEFT_PARENTH (*ParamStr)) { + return NULL; + } + + // + // Skip the found '(' and find first occurrence of ')' + // + ParamStr++; + ParameterLength = 0; + StrPointer = ParamStr; + while (!IS_NULL (*StrPointer)) { + if (IS_RIGHT_PARENTH (*StrPointer)) { + break; + } + StrPointer++; + ParameterLength++; + } + if (IS_NULL (*StrPointer)) { + // + // ')' not found + // + return NULL; + } + + ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr); + if (ParamStr == NULL) { + return NULL; + } + // + // Terminate the parameter string + // + ParamStr[ParameterLength] = L'\0'; + + return ParamStr; +} + +/** + Gets the next parameter string from the list. + + @param List A string list separated by the specified separator + + @return A pointer to the current sub-string + +**/ +CHAR16 * +GetNextParamStr ( + CHAR16 **List + ) +{ + // + // The separator is comma + // + return SplitStr (List, L','); +} + +/** + Get one device node from entire device path text. + + @param DevicePath On input, the current Device Path node; on output, the next device path node + @param IsInstanceEnd This node is the end of a device path instance + + @return A device node text or NULL if no more device node available + +**/ +CHAR16 * +GetNextDeviceNodeStr ( + CHAR16 **DevicePath, + BOOLEAN *IsInstanceEnd + ) +{ + CHAR16 *Str; + CHAR16 *ReturnStr; + UINTN ParenthesesStack; + + Str = *DevicePath; + if (IS_NULL (*Str)) { + return NULL; + } + + // + // Skip the leading '/', '(', ')' and ',' + // + while (!IS_NULL (*Str)) { + if (!IS_SLASH (*Str) && + !IS_COMMA (*Str) && + !IS_LEFT_PARENTH (*Str) && + !IS_RIGHT_PARENTH (*Str)) { + break; + } + Str++; + } + + ReturnStr = Str; + + // + // Scan for the separator of this device node, '/' or ',' + // + ParenthesesStack = 0; + while (!IS_NULL (*Str)) { + if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) { + break; + } + + if (IS_LEFT_PARENTH (*Str)) { + ParenthesesStack++; + } else if (IS_RIGHT_PARENTH (*Str)) { + ParenthesesStack--; + } + + Str++; + } + + if (ParenthesesStack != 0) { + // + // The '(' doesn't pair with ')', invalid device path text + // + return NULL; + } + + if (IS_COMMA (*Str)) { + *IsInstanceEnd = TRUE; + *Str = L'\0'; + Str++; + } else { + *IsInstanceEnd = FALSE; + if (!IS_NULL (*Str)) { + *Str = L'\0'; + Str++; + } + } + + *DevicePath = Str; + + return ReturnStr; +} + +/** + Converts a generic text device path node to device path structure. + + @param Type The type of the device path node. + @param TextDeviceNode The input text device path node. + + @return A pointer to device path structure. +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextGenericPath ( + UINT8 Type, + CHAR16 *TextDeviceNode + ) +{ + EFI_DEVICE_PATH_PROTOCOL *Node; + CHAR16 *SubtypeStr; + CHAR16 *DataStr; + UINTN DataLength; + + SubtypeStr = GetNextParamStr (&TextDeviceNode); + DataStr = GetNextParamStr (&TextDeviceNode); + + if (DataStr == NULL) { + DataLength = 0; + } else { + DataLength = StrLen (DataStr) / 2; + } + Node = CreateDeviceNode ( + Type, + (UINT8) Strtoi (SubtypeStr), + (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength) + ); + + StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength); + return Node; +} + +/** + Converts a generic text device path node to device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextPath ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *TypeStr; + + TypeStr = GetNextParamStr (&TextDeviceNode); + + return DevPathFromTextGenericPath ((UINT8) Strtoi (TypeStr), TextDeviceNode); +} + +/** + Converts a generic hardware text device path node to Hardware device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to Hardware device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextHardwarePath ( + CHAR16 *TextDeviceNode + ) +{ + return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, TextDeviceNode); +} + +/** + Converts a text device path node to Hardware PCI device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to Hardware PCI device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextPci ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *FunctionStr; + CHAR16 *DeviceStr; + PCI_DEVICE_PATH *Pci; + + DeviceStr = GetNextParamStr (&TextDeviceNode); + FunctionStr = GetNextParamStr (&TextDeviceNode); + Pci = (PCI_DEVICE_PATH *) CreateDeviceNode ( + HARDWARE_DEVICE_PATH, + HW_PCI_DP, + (UINT16) sizeof (PCI_DEVICE_PATH) + ); + + Pci->Function = (UINT8) Strtoi (FunctionStr); + Pci->Device = (UINT8) Strtoi (DeviceStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Pci; +} + +/** + Converts a text device path node to Hardware PC card device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to Hardware PC card device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextPcCard ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *FunctionNumberStr; + PCCARD_DEVICE_PATH *Pccard; + + FunctionNumberStr = GetNextParamStr (&TextDeviceNode); + Pccard = (PCCARD_DEVICE_PATH *) CreateDeviceNode ( + HARDWARE_DEVICE_PATH, + HW_PCCARD_DP, + (UINT16) sizeof (PCCARD_DEVICE_PATH) + ); + + Pccard->FunctionNumber = (UINT8) Strtoi (FunctionNumberStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Pccard; +} + +/** + Converts a text device path node to Hardware memory map device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to Hardware memory map device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextMemoryMapped ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *MemoryTypeStr; + CHAR16 *StartingAddressStr; + CHAR16 *EndingAddressStr; + MEMMAP_DEVICE_PATH *MemMap; + + MemoryTypeStr = GetNextParamStr (&TextDeviceNode); + StartingAddressStr = GetNextParamStr (&TextDeviceNode); + EndingAddressStr = GetNextParamStr (&TextDeviceNode); + MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode ( + HARDWARE_DEVICE_PATH, + HW_MEMMAP_DP, + (UINT16) sizeof (MEMMAP_DEVICE_PATH) + ); + + MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr); + Strtoi64 (StartingAddressStr, &MemMap->StartingAddress); + Strtoi64 (EndingAddressStr, &MemMap->EndingAddress); + + return (EFI_DEVICE_PATH_PROTOCOL *) MemMap; +} + +/** + Converts a text device path node to Vendor device path structure based on the input Type + and SubType. + + @param TextDeviceNode The input Text device path node. + @param Type The type of device path node. + @param SubType The subtype of device path node. + + @return A pointer to the newly-created Vendor device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +ConvertFromTextVendor ( + CHAR16 *TextDeviceNode, + UINT8 Type, + UINT8 SubType + ) +{ + CHAR16 *GuidStr; + CHAR16 *DataStr; + UINTN Length; + VENDOR_DEVICE_PATH *Vendor; + + GuidStr = GetNextParamStr (&TextDeviceNode); + + DataStr = GetNextParamStr (&TextDeviceNode); + Length = StrLen (DataStr); + // + // Two hex characters make up 1 buffer byte + // + Length = (Length + 1) / 2; + + Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( + Type, + SubType, + (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length) + ); + + StrToGuid (GuidStr, &Vendor->Guid); + StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length); + + return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; +} + +/** + Converts a text device path node to Vendor Hardware device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Vendor Hardware device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVenHw ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextVendor ( + TextDeviceNode, + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP + ); +} + +/** + Converts a text device path node to Hardware Controller device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Hardware Controller device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextCtrl ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *ControllerStr; + CONTROLLER_DEVICE_PATH *Controller; + + ControllerStr = GetNextParamStr (&TextDeviceNode); + Controller = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode ( + HARDWARE_DEVICE_PATH, + HW_CONTROLLER_DP, + (UINT16) sizeof (CONTROLLER_DEVICE_PATH) + ); + Controller->ControllerNumber = (UINT32) Strtoi (ControllerStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Controller; +} + +/** + Converts a text device path node to BMC device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created BMC device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextBmc ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *InterfaceTypeStr; + CHAR16 *BaseAddressStr; + BMC_DEVICE_PATH *BmcDp; + + InterfaceTypeStr = GetNextParamStr (&TextDeviceNode); + BaseAddressStr = GetNextParamStr (&TextDeviceNode); + BmcDp = (BMC_DEVICE_PATH *) CreateDeviceNode ( + HARDWARE_DEVICE_PATH, + HW_BMC_DP, + (UINT16) sizeof (BMC_DEVICE_PATH) + ); + + BmcDp->InterfaceType = (UINT8) Strtoi (InterfaceTypeStr); + WriteUnaligned64 ( + (UINT64 *) (&BmcDp->BaseAddress), + StrHexToUint64 (BaseAddressStr) + ); + + return (EFI_DEVICE_PATH_PROTOCOL *) BmcDp; +} + +/** + Converts a generic ACPI text device path node to ACPI device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to ACPI device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextAcpiPath ( + CHAR16 *TextDeviceNode + ) +{ + return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, TextDeviceNode); +} + +/** + Converts a string to EisaId. + + @param Text The input string. + + @return UINT32 EISA ID. +**/ +UINT32 +EisaIdFromText ( + CHAR16 *Text + ) +{ + return (((Text[0] - 'A' + 1) & 0x1f) << 10) + + (((Text[1] - 'A' + 1) & 0x1f) << 5) + + (((Text[2] - 'A' + 1) & 0x1f) << 0) + + (UINT32) (StrHexToUintn (&Text[3]) << 16) + ; +} + +/** + Converts a text device path node to ACPI HID device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created ACPI HID device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextAcpi ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *HIDStr; + CHAR16 *UIDStr; + ACPI_HID_DEVICE_PATH *Acpi; + + HIDStr = GetNextParamStr (&TextDeviceNode); + UIDStr = GetNextParamStr (&TextDeviceNode); + Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode ( + ACPI_DEVICE_PATH, + ACPI_DP, + (UINT16) sizeof (ACPI_HID_DEVICE_PATH) + ); + + Acpi->HID = EisaIdFromText (HIDStr); + Acpi->UID = (UINT32) Strtoi (UIDStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Acpi; +} + +/** + Converts a text device path node to ACPI HID device path structure. + + @param TextDeviceNode The input Text device path node. + @param PnPId The input plug and play identification. + + @return A pointer to the newly-created ACPI HID device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +ConvertFromTextAcpi ( + CHAR16 *TextDeviceNode, + UINT32 PnPId + ) +{ + CHAR16 *UIDStr; + ACPI_HID_DEVICE_PATH *Acpi; + + UIDStr = GetNextParamStr (&TextDeviceNode); + Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode ( + ACPI_DEVICE_PATH, + ACPI_DP, + (UINT16) sizeof (ACPI_HID_DEVICE_PATH) + ); + + Acpi->HID = EFI_PNP_ID (PnPId); + Acpi->UID = (UINT32) Strtoi (UIDStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Acpi; +} + +/** + Converts a text device path node to PCI root device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created PCI root device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextPciRoot ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextAcpi (TextDeviceNode, 0x0a03); +} + +/** + Converts a text device path node to PCIE root device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created PCIE root device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextPcieRoot ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextAcpi (TextDeviceNode, 0x0a08); +} + +/** + Converts a text device path node to Floppy device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Floppy device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextFloppy ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextAcpi (TextDeviceNode, 0x0604); +} + +/** + Converts a text device path node to Keyboard device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Keyboard device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextKeyboard ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextAcpi (TextDeviceNode, 0x0301); +} + +/** + Converts a text device path node to Serial device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Serial device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextSerial ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextAcpi (TextDeviceNode, 0x0501); +} + +/** + Converts a text device path node to Parallel Port device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Parallel Port device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextParallelPort ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextAcpi (TextDeviceNode, 0x0401); +} + +/** + Converts a text device path node to ACPI extension device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created ACPI extension device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextAcpiEx ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *HIDStr; + CHAR16 *CIDStr; + CHAR16 *UIDStr; + CHAR16 *HIDSTRStr; + CHAR16 *CIDSTRStr; + CHAR16 *UIDSTRStr; + CHAR8 *AsciiStr; + UINT16 Length; + ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; + + HIDStr = GetNextParamStr (&TextDeviceNode); + CIDStr = GetNextParamStr (&TextDeviceNode); + UIDStr = GetNextParamStr (&TextDeviceNode); + HIDSTRStr = GetNextParamStr (&TextDeviceNode); + CIDSTRStr = GetNextParamStr (&TextDeviceNode); + UIDSTRStr = GetNextParamStr (&TextDeviceNode); + + Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1); + Length = (UINT16) (Length + StrLen (UIDSTRStr) + 1); + Length = (UINT16) (Length + StrLen (CIDSTRStr) + 1); + AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode ( + ACPI_DEVICE_PATH, + ACPI_EXTENDED_DP, + Length + ); + + AcpiEx->HID = EisaIdFromText (HIDStr); + AcpiEx->CID = EisaIdFromText (CIDStr); + AcpiEx->UID = (UINT32) Strtoi (UIDStr); + + AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)); + StrToAscii (HIDSTRStr, &AsciiStr); + StrToAscii (UIDSTRStr, &AsciiStr); + StrToAscii (CIDSTRStr, &AsciiStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx; +} + +/** + Converts a text device path node to ACPI extension device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created ACPI extension device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextAcpiExp ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *HIDStr; + CHAR16 *CIDStr; + CHAR16 *UIDSTRStr; + CHAR8 *AsciiStr; + UINT16 Length; + ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; + + HIDStr = GetNextParamStr (&TextDeviceNode); + CIDStr = GetNextParamStr (&TextDeviceNode); + UIDSTRStr = GetNextParamStr (&TextDeviceNode); + Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3); + AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode ( + ACPI_DEVICE_PATH, + ACPI_EXTENDED_DP, + Length + ); + + AcpiEx->HID = EisaIdFromText (HIDStr); + AcpiEx->CID = EisaIdFromText (CIDStr); + AcpiEx->UID = 0; + + AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)); + // + // HID string is NULL + // + *AsciiStr = '\0'; + // + // Convert UID string + // + AsciiStr++; + StrToAscii (UIDSTRStr, &AsciiStr); + // + // CID string is NULL + // + *AsciiStr = '\0'; + + return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx; +} + +/** + Converts a text device path node to ACPI _ADR device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created ACPI _ADR device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextAcpiAdr ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *DisplayDeviceStr; + ACPI_ADR_DEVICE_PATH *AcpiAdr; + UINTN Index; + UINTN Length; + + AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode ( + ACPI_DEVICE_PATH, + ACPI_ADR_DP, + (UINT16) sizeof (ACPI_ADR_DEVICE_PATH) + ); + ASSERT (AcpiAdr != NULL); + + for (Index = 0; ; Index++) { + DisplayDeviceStr = GetNextParamStr (&TextDeviceNode); + if (IS_NULL (*DisplayDeviceStr)) { + break; + } + if (Index > 0) { + Length = DevicePathNodeLength (AcpiAdr); + AcpiAdr = ReallocatePool ( + Length, + Length + sizeof (UINT32), + AcpiAdr + ); + ASSERT (AcpiAdr != NULL); + SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32)); + } + + (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr); + } + + return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr; +} + +/** + Converts a generic messaging text device path node to messaging device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to messaging device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextMsg ( + CHAR16 *TextDeviceNode + ) +{ + return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, TextDeviceNode); +} + +/** + Converts a text device path node to Parallel Port device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Parallel Port device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextAta ( + CHAR16 *TextDeviceNode +) +{ + CHAR16 *PrimarySecondaryStr; + CHAR16 *SlaveMasterStr; + CHAR16 *LunStr; + ATAPI_DEVICE_PATH *Atapi; + + Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_ATAPI_DP, + (UINT16) sizeof (ATAPI_DEVICE_PATH) + ); + + PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode); + SlaveMasterStr = GetNextParamStr (&TextDeviceNode); + LunStr = GetNextParamStr (&TextDeviceNode); + + if (StrCmp (PrimarySecondaryStr, L"Primary") == 0) { + Atapi->PrimarySecondary = 0; + } else if (StrCmp (PrimarySecondaryStr, L"Secondary") == 0) { + Atapi->PrimarySecondary = 1; + } else { + Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr); + } + if (StrCmp (SlaveMasterStr, L"Master") == 0) { + Atapi->SlaveMaster = 0; + } else if (StrCmp (SlaveMasterStr, L"Slave") == 0) { + Atapi->SlaveMaster = 1; + } else { + Atapi->SlaveMaster = (UINT8) Strtoi (SlaveMasterStr); + } + + Atapi->Lun = (UINT16) Strtoi (LunStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Atapi; +} + +/** + Converts a text device path node to SCSI device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created SCSI device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextScsi ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *PunStr; + CHAR16 *LunStr; + SCSI_DEVICE_PATH *Scsi; + + PunStr = GetNextParamStr (&TextDeviceNode); + LunStr = GetNextParamStr (&TextDeviceNode); + Scsi = (SCSI_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_SCSI_DP, + (UINT16) sizeof (SCSI_DEVICE_PATH) + ); + + Scsi->Pun = (UINT16) Strtoi (PunStr); + Scsi->Lun = (UINT16) Strtoi (LunStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Scsi; +} + +/** + Converts a text device path node to Fibre device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Fibre device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextFibre ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *WWNStr; + CHAR16 *LunStr; + FIBRECHANNEL_DEVICE_PATH *Fibre; + + WWNStr = GetNextParamStr (&TextDeviceNode); + LunStr = GetNextParamStr (&TextDeviceNode); + Fibre = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_FIBRECHANNEL_DP, + (UINT16) sizeof (FIBRECHANNEL_DEVICE_PATH) + ); + + Fibre->Reserved = 0; + Strtoi64 (WWNStr, &Fibre->WWN); + Strtoi64 (LunStr, &Fibre->Lun); + + return (EFI_DEVICE_PATH_PROTOCOL *) Fibre; +} + +/** + Converts a text device path node to FibreEx device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created FibreEx device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextFibreEx ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *WWNStr; + CHAR16 *LunStr; + FIBRECHANNELEX_DEVICE_PATH *FibreEx; + + WWNStr = GetNextParamStr (&TextDeviceNode); + LunStr = GetNextParamStr (&TextDeviceNode); + FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_FIBRECHANNELEX_DP, + (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH) + ); + + FibreEx->Reserved = 0; + Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN)); + Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun)); + + *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx->WWN)); + *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun)); + + return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx; +} + +/** + Converts a text device path node to 1394 device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created 1394 device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromText1394 ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *GuidStr; + F1394_DEVICE_PATH *F1394DevPath; + + GuidStr = GetNextParamStr (&TextDeviceNode); + F1394DevPath = (F1394_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_1394_DP, + (UINT16) sizeof (F1394_DEVICE_PATH) + ); + + F1394DevPath->Reserved = 0; + F1394DevPath->Guid = StrHexToUint64 (GuidStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath; +} + +/** + Converts a text device path node to USB device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsb ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *PortStr; + CHAR16 *InterfaceStr; + USB_DEVICE_PATH *Usb; + + PortStr = GetNextParamStr (&TextDeviceNode); + InterfaceStr = GetNextParamStr (&TextDeviceNode); + Usb = (USB_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_USB_DP, + (UINT16) sizeof (USB_DEVICE_PATH) + ); + + Usb->ParentPortNumber = (UINT8) Strtoi (PortStr); + Usb->InterfaceNumber = (UINT8) Strtoi (InterfaceStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Usb; +} + +/** + Converts a text device path node to I20 device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created I20 device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextI2O ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *TIDStr; + I2O_DEVICE_PATH *I2ODevPath; + + TIDStr = GetNextParamStr (&TextDeviceNode); + I2ODevPath = (I2O_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_I2O_DP, + (UINT16) sizeof (I2O_DEVICE_PATH) + ); + + I2ODevPath->Tid = (UINT32) Strtoi (TIDStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath; +} + +/** + Converts a text device path node to Infini Band device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Infini Band device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextInfiniband ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *FlagsStr; + CHAR16 *GuidStr; + CHAR16 *SidStr; + CHAR16 *TidStr; + CHAR16 *DidStr; + INFINIBAND_DEVICE_PATH *InfiniBand; + + FlagsStr = GetNextParamStr (&TextDeviceNode); + GuidStr = GetNextParamStr (&TextDeviceNode); + SidStr = GetNextParamStr (&TextDeviceNode); + TidStr = GetNextParamStr (&TextDeviceNode); + DidStr = GetNextParamStr (&TextDeviceNode); + InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_INFINIBAND_DP, + (UINT16) sizeof (INFINIBAND_DEVICE_PATH) + ); + + InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr); + StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid); + Strtoi64 (SidStr, &InfiniBand->ServiceId); + Strtoi64 (TidStr, &InfiniBand->TargetPortId); + Strtoi64 (DidStr, &InfiniBand->DeviceId); + + return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand; +} + +/** + Converts a text device path node to Vendor-Defined Messaging device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Vendor-Defined Messaging device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVenMsg ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextVendor ( + TextDeviceNode, + MESSAGING_DEVICE_PATH, + MSG_VENDOR_DP + ); +} + +/** + Converts a text device path node to Vendor defined PC-ANSI device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Vendor defined PC-ANSI device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVenPcAnsi ( + CHAR16 *TextDeviceNode + ) +{ + VENDOR_DEVICE_PATH *Vendor; + + Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_VENDOR_DP, + (UINT16) sizeof (VENDOR_DEVICE_PATH)); + CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid); + + return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; +} + +/** + Converts a text device path node to Vendor defined VT100 device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Vendor defined VT100 device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVenVt100 ( + CHAR16 *TextDeviceNode + ) +{ + VENDOR_DEVICE_PATH *Vendor; + + Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_VENDOR_DP, + (UINT16) sizeof (VENDOR_DEVICE_PATH)); + CopyGuid (&Vendor->Guid, &gEfiVT100Guid); + + return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; +} + +/** + Converts a text device path node to Vendor defined VT100 Plus device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Vendor defined VT100 Plus device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVenVt100Plus ( + CHAR16 *TextDeviceNode + ) +{ + VENDOR_DEVICE_PATH *Vendor; + + Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_VENDOR_DP, + (UINT16) sizeof (VENDOR_DEVICE_PATH)); + CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid); + + return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; +} + +/** + Converts a text device path node to Vendor defined UTF8 device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Vendor defined UTF8 device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVenUtf8 ( + CHAR16 *TextDeviceNode + ) +{ + VENDOR_DEVICE_PATH *Vendor; + + Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_VENDOR_DP, + (UINT16) sizeof (VENDOR_DEVICE_PATH)); + CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid); + + return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; +} + +/** + Converts a text device path node to UART Flow Control device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created UART Flow Control device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUartFlowCtrl ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *ValueStr; + UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl; + + ValueStr = GetNextParamStr (&TextDeviceNode); + UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_VENDOR_DP, + (UINT16) sizeof (UART_FLOW_CONTROL_DEVICE_PATH) + ); + + CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid); + if (StrCmp (ValueStr, L"XonXoff") == 0) { + UartFlowControl->FlowControlMap = 2; + } else if (StrCmp (ValueStr, L"Hardware") == 0) { + UartFlowControl->FlowControlMap = 1; + } else { + UartFlowControl->FlowControlMap = 0; + } + + return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl; +} + +/** + Converts a text device path node to Serial Attached SCSI device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Serial Attached SCSI device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextSAS ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *AddressStr; + CHAR16 *LunStr; + CHAR16 *RTPStr; + CHAR16 *SASSATAStr; + CHAR16 *LocationStr; + CHAR16 *ConnectStr; + CHAR16 *DriveBayStr; + CHAR16 *ReservedStr; + UINT16 Info; + UINT16 Uint16; + SAS_DEVICE_PATH *Sas; + + AddressStr = GetNextParamStr (&TextDeviceNode); + LunStr = GetNextParamStr (&TextDeviceNode); + RTPStr = GetNextParamStr (&TextDeviceNode); + SASSATAStr = GetNextParamStr (&TextDeviceNode); + LocationStr = GetNextParamStr (&TextDeviceNode); + ConnectStr = GetNextParamStr (&TextDeviceNode); + DriveBayStr = GetNextParamStr (&TextDeviceNode); + ReservedStr = GetNextParamStr (&TextDeviceNode); + Sas = (SAS_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_VENDOR_DP, + (UINT16) sizeof (SAS_DEVICE_PATH) + ); + + CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid); + Strtoi64 (AddressStr, &Sas->SasAddress); + Strtoi64 (LunStr, &Sas->Lun); + Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr); + + if (StrCmp (SASSATAStr, L"NoTopology") == 0) { + Info = 0x0; + + } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) { + + Uint16 = (UINT16) Strtoi (DriveBayStr); + if (Uint16 == 0) { + Info = 0x1; + } else { + Info = (UINT16) (0x2 | ((Uint16 - 1) << 8)); + } + + if (StrCmp (SASSATAStr, L"SATA") == 0) { + Info |= BIT4; + } + + // + // Location is an integer between 0 and 1 or else + // the keyword Internal (0) or External (1). + // + if (StrCmp (LocationStr, L"External") == 0) { + Uint16 = 1; + } else if (StrCmp (LocationStr, L"Internal") == 0) { + Uint16 = 0; + } else { + Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0); + } + Info |= (Uint16 << 5); + + // + // Connect is an integer between 0 and 3 or else + // the keyword Direct (0) or Expanded (1). + // + if (StrCmp (ConnectStr, L"Expanded") == 0) { + Uint16 = 1; + } else if (StrCmp (ConnectStr, L"Direct") == 0) { + Uint16 = 0; + } else { + Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1)); + } + Info |= (Uint16 << 6); + + } else { + Info = (UINT16) Strtoi (SASSATAStr); + } + + Sas->DeviceTopology = Info; + Sas->Reserved = (UINT32) Strtoi (ReservedStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Sas; +} + +/** + Converts a text device path node to Serial Attached SCSI Ex device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Serial Attached SCSI Ex device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextSasEx ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *AddressStr; + CHAR16 *LunStr; + CHAR16 *RTPStr; + CHAR16 *SASSATAStr; + CHAR16 *LocationStr; + CHAR16 *ConnectStr; + CHAR16 *DriveBayStr; + UINT16 Info; + UINT16 Uint16; + UINT64 SasAddress; + UINT64 Lun; + SASEX_DEVICE_PATH *SasEx; + + AddressStr = GetNextParamStr (&TextDeviceNode); + LunStr = GetNextParamStr (&TextDeviceNode); + RTPStr = GetNextParamStr (&TextDeviceNode); + SASSATAStr = GetNextParamStr (&TextDeviceNode); + LocationStr = GetNextParamStr (&TextDeviceNode); + ConnectStr = GetNextParamStr (&TextDeviceNode); + DriveBayStr = GetNextParamStr (&TextDeviceNode); + SasEx = (SASEX_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_SASEX_DP, + (UINT16) sizeof (SASEX_DEVICE_PATH) + ); + + Strtoi64 (AddressStr, &SasAddress); + Strtoi64 (LunStr, &Lun); + WriteUnaligned64 ((UINT64 *) &SasEx->SasAddress, SwapBytes64 (SasAddress)); + WriteUnaligned64 ((UINT64 *) &SasEx->Lun, SwapBytes64 (Lun)); + SasEx->RelativeTargetPort = (UINT16) Strtoi (RTPStr); + + if (StrCmp (SASSATAStr, L"NoTopology") == 0) { + Info = 0x0; + + } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) { + + Uint16 = (UINT16) Strtoi (DriveBayStr); + if (Uint16 == 0) { + Info = 0x1; + } else { + Info = (UINT16) (0x2 | ((Uint16 - 1) << 8)); + } + + if (StrCmp (SASSATAStr, L"SATA") == 0) { + Info |= BIT4; + } + + // + // Location is an integer between 0 and 1 or else + // the keyword Internal (0) or External (1). + // + if (StrCmp (LocationStr, L"External") == 0) { + Uint16 = 1; + } else if (StrCmp (LocationStr, L"Internal") == 0) { + Uint16 = 0; + } else { + Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0); + } + Info |= (Uint16 << 5); + + // + // Connect is an integer between 0 and 3 or else + // the keyword Direct (0) or Expanded (1). + // + if (StrCmp (ConnectStr, L"Expanded") == 0) { + Uint16 = 1; + } else if (StrCmp (ConnectStr, L"Direct") == 0) { + Uint16 = 0; + } else { + Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1)); + } + Info |= (Uint16 << 6); + + } else { + Info = (UINT16) Strtoi (SASSATAStr); + } + + SasEx->DeviceTopology = Info; + + return (EFI_DEVICE_PATH_PROTOCOL *) SasEx; +} + +/** + Converts a text device path node to NVM Express Namespace device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created NVM Express Namespace device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextNVMe ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *NamespaceIdStr; + CHAR16 *NamespaceUuidStr; + NVME_NAMESPACE_DEVICE_PATH *Nvme; + UINT8 *Uuid; + UINTN Index; + + NamespaceIdStr = GetNextParamStr (&TextDeviceNode); + NamespaceUuidStr = GetNextParamStr (&TextDeviceNode); + Nvme = (NVME_NAMESPACE_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_NVME_NAMESPACE_DP, + (UINT16) sizeof (NVME_NAMESPACE_DEVICE_PATH) + ); + + Nvme->NamespaceId = (UINT32) Strtoi (NamespaceIdStr); + Uuid = (UINT8 *) &Nvme->NamespaceUuid; + + Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8); + while (Index-- != 0) { + Uuid[Index] = (UINT8) StrHexToUintn (SplitStr (&NamespaceUuidStr, L'-')); + } + + return (EFI_DEVICE_PATH_PROTOCOL *) Nvme; +} + +/** + Converts a text device path node to UFS device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created UFS device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUfs ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *PunStr; + CHAR16 *LunStr; + UFS_DEVICE_PATH *Ufs; + + PunStr = GetNextParamStr (&TextDeviceNode); + LunStr = GetNextParamStr (&TextDeviceNode); + Ufs = (UFS_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_UFS_DP, + (UINT16) sizeof (UFS_DEVICE_PATH) + ); + + Ufs->Pun = (UINT8) Strtoi (PunStr); + Ufs->Lun = (UINT8) Strtoi (LunStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Ufs; +} + +/** + Converts a text device path node to SD (Secure Digital) device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created SD device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextSd ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *SlotNumberStr; + SD_DEVICE_PATH *Sd; + + SlotNumberStr = GetNextParamStr (&TextDeviceNode); + Sd = (SD_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_SD_DP, + (UINT16) sizeof (SD_DEVICE_PATH) + ); + + Sd->SlotNumber = (UINT8) Strtoi (SlotNumberStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Sd; +} + +/** + Converts a text device path node to EMMC (Embedded MMC) device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created EMMC device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextEmmc ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *SlotNumberStr; + EMMC_DEVICE_PATH *Emmc; + + SlotNumberStr = GetNextParamStr (&TextDeviceNode); + Emmc = (EMMC_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_EMMC_DP, + (UINT16) sizeof (EMMC_DEVICE_PATH) + ); + + Emmc->SlotNumber = (UINT8) Strtoi (SlotNumberStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Emmc; +} + +/** + Converts a text device path node to Debug Port device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Debug Port device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextDebugPort ( + CHAR16 *TextDeviceNode + ) +{ + VENDOR_DEFINED_MESSAGING_DEVICE_PATH *Vend; + + Vend = (VENDOR_DEFINED_MESSAGING_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_VENDOR_DP, + (UINT16) sizeof (VENDOR_DEFINED_MESSAGING_DEVICE_PATH) + ); + + CopyGuid (&Vend->Guid, &gEfiDebugPortDevicePathGuid); + + return (EFI_DEVICE_PATH_PROTOCOL *) Vend; +} + +/** + Converts a text device path node to MAC device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created MAC device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextMAC ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *AddressStr; + CHAR16 *IfTypeStr; + UINTN Length; + MAC_ADDR_DEVICE_PATH *MACDevPath; + + AddressStr = GetNextParamStr (&TextDeviceNode); + IfTypeStr = GetNextParamStr (&TextDeviceNode); + MACDevPath = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_MAC_ADDR_DP, + (UINT16) sizeof (MAC_ADDR_DEVICE_PATH) + ); + + MACDevPath->IfType = (UINT8) Strtoi (IfTypeStr); + + Length = sizeof (EFI_MAC_ADDRESS); + if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) { + Length = 6; + } + + StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length); + + return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath; +} + + +/** + Converts a text format to the network protocol ID. + + @param Text String of protocol field. + + @return Network protocol ID . + +**/ +UINTN +NetworkProtocolFromText ( + CHAR16 *Text + ) +{ + if (StrCmp (Text, L"UDP") == 0) { + return RFC_1700_UDP_PROTOCOL; + } + + if (StrCmp (Text, L"TCP") == 0) { + return RFC_1700_TCP_PROTOCOL; + } + + return Strtoi (Text); +} + + +/** + Converts a text device path node to IPV4 device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created IPV4 device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextIPv4 ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *RemoteIPStr; + CHAR16 *ProtocolStr; + CHAR16 *TypeStr; + CHAR16 *LocalIPStr; + CHAR16 *GatewayIPStr; + CHAR16 *SubnetMaskStr; + IPv4_DEVICE_PATH *IPv4; + + RemoteIPStr = GetNextParamStr (&TextDeviceNode); + ProtocolStr = GetNextParamStr (&TextDeviceNode); + TypeStr = GetNextParamStr (&TextDeviceNode); + LocalIPStr = GetNextParamStr (&TextDeviceNode); + GatewayIPStr = GetNextParamStr (&TextDeviceNode); + SubnetMaskStr = GetNextParamStr (&TextDeviceNode); + IPv4 = (IPv4_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_IPv4_DP, + (UINT16) sizeof (IPv4_DEVICE_PATH) + ); + + StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL); + IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr); + if (StrCmp (TypeStr, L"Static") == 0) { + IPv4->StaticIpAddress = TRUE; + } else { + IPv4->StaticIpAddress = FALSE; + } + + StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL); + if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) { + StrToIpv4Address (GatewayIPStr, NULL, &IPv4->GatewayIpAddress, NULL); + StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask, NULL); + } else { + ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress)); + ZeroMem (&IPv4->SubnetMask, sizeof (IPv4->SubnetMask)); + } + + IPv4->LocalPort = 0; + IPv4->RemotePort = 0; + + return (EFI_DEVICE_PATH_PROTOCOL *) IPv4; +} + +/** + Converts a text device path node to IPV6 device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created IPV6 device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextIPv6 ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *RemoteIPStr; + CHAR16 *ProtocolStr; + CHAR16 *TypeStr; + CHAR16 *LocalIPStr; + CHAR16 *GatewayIPStr; + CHAR16 *PrefixLengthStr; + IPv6_DEVICE_PATH *IPv6; + + RemoteIPStr = GetNextParamStr (&TextDeviceNode); + ProtocolStr = GetNextParamStr (&TextDeviceNode); + TypeStr = GetNextParamStr (&TextDeviceNode); + LocalIPStr = GetNextParamStr (&TextDeviceNode); + PrefixLengthStr = GetNextParamStr (&TextDeviceNode); + GatewayIPStr = GetNextParamStr (&TextDeviceNode); + IPv6 = (IPv6_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_IPv6_DP, + (UINT16) sizeof (IPv6_DEVICE_PATH) + ); + + StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL); + IPv6->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr); + if (StrCmp (TypeStr, L"Static") == 0) { + IPv6->IpAddressOrigin = 0; + } else if (StrCmp (TypeStr, L"StatelessAutoConfigure") == 0) { + IPv6->IpAddressOrigin = 1; + } else { + IPv6->IpAddressOrigin = 2; + } + + StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL); + if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) { + StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL); + IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr); + } else { + ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress)); + IPv6->PrefixLength = 0; + } + + IPv6->LocalPort = 0; + IPv6->RemotePort = 0; + + return (EFI_DEVICE_PATH_PROTOCOL *) IPv6; +} + +/** + Converts a text device path node to UART device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created UART device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUart ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *BaudStr; + CHAR16 *DataBitsStr; + CHAR16 *ParityStr; + CHAR16 *StopBitsStr; + UART_DEVICE_PATH *Uart; + + BaudStr = GetNextParamStr (&TextDeviceNode); + DataBitsStr = GetNextParamStr (&TextDeviceNode); + ParityStr = GetNextParamStr (&TextDeviceNode); + StopBitsStr = GetNextParamStr (&TextDeviceNode); + Uart = (UART_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_UART_DP, + (UINT16) sizeof (UART_DEVICE_PATH) + ); + + if (StrCmp (BaudStr, L"DEFAULT") == 0) { + Uart->BaudRate = 115200; + } else { + Strtoi64 (BaudStr, &Uart->BaudRate); + } + Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr)); + switch (*ParityStr) { + case L'D': + Uart->Parity = 0; + break; + + case L'N': + Uart->Parity = 1; + break; + + case L'E': + Uart->Parity = 2; + break; + + case L'O': + Uart->Parity = 3; + break; + + case L'M': + Uart->Parity = 4; + break; + + case L'S': + Uart->Parity = 5; + break; + + default: + Uart->Parity = (UINT8) Strtoi (ParityStr); + break; + } + + if (StrCmp (StopBitsStr, L"D") == 0) { + Uart->StopBits = (UINT8) 0; + } else if (StrCmp (StopBitsStr, L"1") == 0) { + Uart->StopBits = (UINT8) 1; + } else if (StrCmp (StopBitsStr, L"1.5") == 0) { + Uart->StopBits = (UINT8) 2; + } else if (StrCmp (StopBitsStr, L"2") == 0) { + Uart->StopBits = (UINT8) 3; + } else { + Uart->StopBits = (UINT8) Strtoi (StopBitsStr); + } + + return (EFI_DEVICE_PATH_PROTOCOL *) Uart; +} + +/** + Converts a text device path node to USB class device path structure. + + @param TextDeviceNode The input Text device path node. + @param UsbClassText A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text. + + @return A pointer to the newly-created USB class device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +ConvertFromTextUsbClass ( + CHAR16 *TextDeviceNode, + USB_CLASS_TEXT *UsbClassText + ) +{ + CHAR16 *VIDStr; + CHAR16 *PIDStr; + CHAR16 *ClassStr; + CHAR16 *SubClassStr; + CHAR16 *ProtocolStr; + USB_CLASS_DEVICE_PATH *UsbClass; + + UsbClass = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_USB_CLASS_DP, + (UINT16) sizeof (USB_CLASS_DEVICE_PATH) + ); + + VIDStr = GetNextParamStr (&TextDeviceNode); + PIDStr = GetNextParamStr (&TextDeviceNode); + if (UsbClassText->ClassExist) { + ClassStr = GetNextParamStr (&TextDeviceNode); + UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr); + } else { + UsbClass->DeviceClass = UsbClassText->Class; + } + if (UsbClassText->SubClassExist) { + SubClassStr = GetNextParamStr (&TextDeviceNode); + UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr); + } else { + UsbClass->DeviceSubClass = UsbClassText->SubClass; + } + + ProtocolStr = GetNextParamStr (&TextDeviceNode); + + UsbClass->VendorId = (UINT16) Strtoi (VIDStr); + UsbClass->ProductId = (UINT16) Strtoi (PIDStr); + UsbClass->DeviceProtocol = (UINT8) Strtoi (ProtocolStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass; +} + + +/** + Converts a text device path node to USB class device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB class device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbClass ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = TRUE; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB audio device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB audio device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbAudio ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_AUDIO; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB CDC Control device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB CDC Control device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbCDCControl ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_CDCCONTROL; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB HID device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB HID device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbHID ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_HID; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB Image device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB Image device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbImage ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_IMAGE; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB Print device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB Print device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbPrinter ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_PRINTER; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB mass storage device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB mass storage device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbMassStorage ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_MASS_STORAGE; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB HUB device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB HUB device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbHub ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_HUB; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB CDC data device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB CDC data device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbCDCData ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_CDCDATA; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB smart card device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB smart card device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbSmartCard ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_SMART_CARD; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB video device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB video device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbVideo ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_VIDEO; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB diagnostic device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB diagnostic device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbDiagnostic ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_DIAGNOSTIC; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB wireless device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB wireless device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbWireless ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_WIRELESS; + UsbClassText.SubClassExist = TRUE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB device firmware update device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB device firmware update device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbDeviceFirmwareUpdate ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_RESERVE; + UsbClassText.SubClassExist = FALSE; + UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB IRDA bridge device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB IRDA bridge device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbIrdaBridge ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_RESERVE; + UsbClassText.SubClassExist = FALSE; + UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB text and measurement device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB text and measurement device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbTestAndMeasurement ( + CHAR16 *TextDeviceNode + ) +{ + USB_CLASS_TEXT UsbClassText; + + UsbClassText.ClassExist = FALSE; + UsbClassText.Class = USB_CLASS_RESERVE; + UsbClassText.SubClassExist = FALSE; + UsbClassText.SubClass = USB_SUBCLASS_TEST; + + return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); +} + +/** + Converts a text device path node to USB WWID device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created USB WWID device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUsbWwid ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *VIDStr; + CHAR16 *PIDStr; + CHAR16 *InterfaceNumStr; + CHAR16 *SerialNumberStr; + USB_WWID_DEVICE_PATH *UsbWwid; + UINTN SerialNumberStrLen; + + VIDStr = GetNextParamStr (&TextDeviceNode); + PIDStr = GetNextParamStr (&TextDeviceNode); + InterfaceNumStr = GetNextParamStr (&TextDeviceNode); + SerialNumberStr = GetNextParamStr (&TextDeviceNode); + SerialNumberStrLen = StrLen (SerialNumberStr); + if (SerialNumberStrLen >= 2 && + SerialNumberStr[0] == L'\"' && + SerialNumberStr[SerialNumberStrLen - 1] == L'\"' + ) { + SerialNumberStr[SerialNumberStrLen - 1] = L'\0'; + SerialNumberStr++; + SerialNumberStrLen -= 2; + } + UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_USB_WWID_DP, + (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16)) + ); + UsbWwid->VendorId = (UINT16) Strtoi (VIDStr); + UsbWwid->ProductId = (UINT16) Strtoi (PIDStr); + UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr); + + // + // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr. + // Therefore, the '\0' will not be copied. + // + memcpy ( + (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH), + SerialNumberStr, + SerialNumberStrLen * sizeof (CHAR16) + ); + + return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid; +} + +/** + Converts a text device path node to Logic Unit device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Logic Unit device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUnit ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *LunStr; + DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit; + + LunStr = GetNextParamStr (&TextDeviceNode); + LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_DEVICE_LOGICAL_UNIT_DP, + (UINT16) sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH) + ); + + LogicalUnit->Lun = (UINT8) Strtoi (LunStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit; +} + +/** + Converts a text device path node to iSCSI device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created iSCSI device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextiSCSI ( + CHAR16 *TextDeviceNode + ) +{ + UINT16 Options; + CHAR16 *NameStr; + CHAR16 *PortalGroupStr; + CHAR16 *LunStr; + CHAR16 *HeaderDigestStr; + CHAR16 *DataDigestStr; + CHAR16 *AuthenticationStr; + CHAR16 *ProtocolStr; + CHAR8 *AsciiStr; + ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath; + + NameStr = GetNextParamStr (&TextDeviceNode); + PortalGroupStr = GetNextParamStr (&TextDeviceNode); + LunStr = GetNextParamStr (&TextDeviceNode); + HeaderDigestStr = GetNextParamStr (&TextDeviceNode); + DataDigestStr = GetNextParamStr (&TextDeviceNode); + AuthenticationStr = GetNextParamStr (&TextDeviceNode); + ProtocolStr = GetNextParamStr (&TextDeviceNode); + ISCSIDevPath = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_ISCSI_DP, + (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr)) + ); + + AsciiStr = ISCSIDevPath->TargetName; + StrToAscii (NameStr, &AsciiStr); + + ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr); + Strtoi64 (LunStr, &ISCSIDevPath->Lun); + + Options = 0x0000; + if (StrCmp (HeaderDigestStr, L"CRC32C") == 0) { + Options |= 0x0002; + } + + if (StrCmp (DataDigestStr, L"CRC32C") == 0) { + Options |= 0x0008; + } + + if (StrCmp (AuthenticationStr, L"None") == 0) { + Options |= 0x0800; + } + + if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) { + Options |= 0x1000; + } + + ISCSIDevPath->LoginOption = (UINT16) Options; + + if (StrCmp (ProtocolStr, L"TCP") == 0) { + ISCSIDevPath->NetworkProtocol = 0; + } else { + // + // Undefined and reserved. + // + ISCSIDevPath->NetworkProtocol = 1; + } + + return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath; +} + +/** + Converts a text device path node to VLAN device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created VLAN device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVlan ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *VlanStr; + VLAN_DEVICE_PATH *Vlan; + + VlanStr = GetNextParamStr (&TextDeviceNode); + Vlan = (VLAN_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_VLAN_DP, + (UINT16) sizeof (VLAN_DEVICE_PATH) + ); + + Vlan->VlanId = (UINT16) Strtoi (VlanStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Vlan; +} + +/** + Converts a text device path node to Bluetooth device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Bluetooth device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextBluetooth ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *BluetoothStr; + BLUETOOTH_DEVICE_PATH *BluetoothDp; + + BluetoothStr = GetNextParamStr (&TextDeviceNode); + BluetoothDp = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_BLUETOOTH_DP, + (UINT16) sizeof (BLUETOOTH_DEVICE_PATH) + ); + StrHexToBytes ( + BluetoothStr, + sizeof (BLUETOOTH_ADDRESS) * 2, + BluetoothDp->BD_ADDR.Address, + sizeof (BLUETOOTH_ADDRESS) + ); + return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp; +} + +/** + Converts a text device path node to Wi-Fi device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Wi-Fi device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextWiFi ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *SSIdStr; + CHAR8 AsciiStr[33]; + UINTN DataLen; + WIFI_DEVICE_PATH *WiFiDp; + + SSIdStr = GetNextParamStr (&TextDeviceNode); + WiFiDp = (WIFI_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_WIFI_DP, + (UINT16) sizeof (WIFI_DEVICE_PATH) + ); + + if (NULL != SSIdStr) { + DataLen = StrLen (SSIdStr); + if (StrLen (SSIdStr) > 32) { + SSIdStr[32] = L'\0'; + DataLen = 32; + } + + UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr)); + memcpy (WiFiDp->SSId, AsciiStr, DataLen); + } + + return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp; +} + +/** + Converts a text device path node to URI device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created URI device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextUri ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *UriStr; + UINTN UriLength; + URI_DEVICE_PATH *Uri; + + UriStr = GetNextParamStr (&TextDeviceNode); + UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH)); + Uri = (URI_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_URI_DP, + (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength) + ); + + while (UriLength-- != 0) { + Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength]; + } + + return (EFI_DEVICE_PATH_PROTOCOL *) Uri; +} + +/** + Converts a media text device path node to media device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to media device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextMediaPath ( + CHAR16 *TextDeviceNode + ) +{ + return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode); +} + +/** + Converts a text device path node to HD device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created HD device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextHD ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *PartitionStr; + CHAR16 *TypeStr; + CHAR16 *SignatureStr; + CHAR16 *StartStr; + CHAR16 *SizeStr; + UINT32 Signature32; + HARDDRIVE_DEVICE_PATH *Hd; + + PartitionStr = GetNextParamStr (&TextDeviceNode); + TypeStr = GetNextParamStr (&TextDeviceNode); + SignatureStr = GetNextParamStr (&TextDeviceNode); + StartStr = GetNextParamStr (&TextDeviceNode); + SizeStr = GetNextParamStr (&TextDeviceNode); + Hd = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_HARDDRIVE_DP, + (UINT16) sizeof (HARDDRIVE_DEVICE_PATH) + ); + + Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr); + + ZeroMem (Hd->Signature, 16); + Hd->MBRType = (UINT8) 0; + + if (StrCmp (TypeStr, L"MBR") == 0) { + Hd->SignatureType = SIGNATURE_TYPE_MBR; + Hd->MBRType = 0x01; + + Signature32 = (UINT32) Strtoi (SignatureStr); + memcpy (Hd->Signature, &Signature32, sizeof (UINT32)); + } else if (StrCmp (TypeStr, L"GPT") == 0) { + Hd->SignatureType = SIGNATURE_TYPE_GUID; + Hd->MBRType = 0x02; + + StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature); + } else { + Hd->SignatureType = (UINT8) Strtoi (TypeStr); + } + + Strtoi64 (StartStr, &Hd->PartitionStart); + Strtoi64 (SizeStr, &Hd->PartitionSize); + + return (EFI_DEVICE_PATH_PROTOCOL *) Hd; +} + +/** + Converts a text device path node to CDROM device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created CDROM device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextCDROM ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *EntryStr; + CHAR16 *StartStr; + CHAR16 *SizeStr; + CDROM_DEVICE_PATH *CDROMDevPath; + + EntryStr = GetNextParamStr (&TextDeviceNode); + StartStr = GetNextParamStr (&TextDeviceNode); + SizeStr = GetNextParamStr (&TextDeviceNode); + CDROMDevPath = (CDROM_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_CDROM_DP, + (UINT16) sizeof (CDROM_DEVICE_PATH) + ); + + CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr); + Strtoi64 (StartStr, &CDROMDevPath->PartitionStart); + Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize); + + return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath; +} + +/** + Converts a text device path node to Vendor-defined media device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Vendor-defined media device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVenMedia ( + CHAR16 *TextDeviceNode + ) +{ + return ConvertFromTextVendor ( + TextDeviceNode, + MEDIA_DEVICE_PATH, + MEDIA_VENDOR_DP + ); +} + +/** + Converts a text device path node to File device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created File device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextFilePath ( + CHAR16 *TextDeviceNode + ) +{ + FILEPATH_DEVICE_PATH *File; + + File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_FILEPATH_DP, + (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2) + ); + + StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode); + + return (EFI_DEVICE_PATH_PROTOCOL *) File; +} + +/** + Converts a text device path node to Media protocol device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Media protocol device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextMedia ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *GuidStr; + MEDIA_PROTOCOL_DEVICE_PATH *Media; + + GuidStr = GetNextParamStr (&TextDeviceNode); + Media = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_PROTOCOL_DP, + (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH) + ); + + StrToGuid (GuidStr, &Media->Protocol); + + return (EFI_DEVICE_PATH_PROTOCOL *) Media; +} + +/** + Converts a text device path node to firmware volume device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created firmware volume device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextFv ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *GuidStr; + MEDIA_FW_VOL_DEVICE_PATH *Fv; + + GuidStr = GetNextParamStr (&TextDeviceNode); + Fv = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_PIWG_FW_VOL_DP, + (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH) + ); + + StrToGuid (GuidStr, &Fv->FvName); + + return (EFI_DEVICE_PATH_PROTOCOL *) Fv; +} + +/** + Converts a text device path node to firmware file device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created firmware file device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextFvFile ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *GuidStr; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile; + + GuidStr = GetNextParamStr (&TextDeviceNode); + FvFile = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_PIWG_FW_FILE_DP, + (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + ); + + StrToGuid (GuidStr, &FvFile->FvFileName); + + return (EFI_DEVICE_PATH_PROTOCOL *) FvFile; +} + +/** + Converts a text device path node to text relative offset device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Text device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextRelativeOffsetRange ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *StartingOffsetStr; + CHAR16 *EndingOffsetStr; + MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset; + + StartingOffsetStr = GetNextParamStr (&TextDeviceNode); + EndingOffsetStr = GetNextParamStr (&TextDeviceNode); + Offset = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_RELATIVE_OFFSET_RANGE_DP, + (UINT16) sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH) + ); + + Strtoi64 (StartingOffsetStr, &Offset->StartingOffset); + Strtoi64 (EndingOffsetStr, &Offset->EndingOffset); + + return (EFI_DEVICE_PATH_PROTOCOL *) Offset; +} + +/** + Converts a text device path node to text ram disk device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Text device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextRamDisk ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *StartingAddrStr; + CHAR16 *EndingAddrStr; + CHAR16 *TypeGuidStr; + CHAR16 *InstanceStr; + MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; + UINT64 StartingAddr; + UINT64 EndingAddr; + + StartingAddrStr = GetNextParamStr (&TextDeviceNode); + EndingAddrStr = GetNextParamStr (&TextDeviceNode); + InstanceStr = GetNextParamStr (&TextDeviceNode); + TypeGuidStr = GetNextParamStr (&TextDeviceNode); + RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_RAM_DISK_DP, + (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) + ); + + Strtoi64 (StartingAddrStr, &StartingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); + Strtoi64 (EndingAddrStr, &EndingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); + RamDisk->Instance = (UINT16) Strtoi (InstanceStr); + StrToGuid (TypeGuidStr, &RamDisk->TypeGuid); + + return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; +} + +/** + Converts a text device path node to text virtual disk device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Text device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVirtualDisk ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *StartingAddrStr; + CHAR16 *EndingAddrStr; + CHAR16 *InstanceStr; + MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; + UINT64 StartingAddr; + UINT64 EndingAddr; + + StartingAddrStr = GetNextParamStr (&TextDeviceNode); + EndingAddrStr = GetNextParamStr (&TextDeviceNode); + InstanceStr = GetNextParamStr (&TextDeviceNode); + + RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_RAM_DISK_DP, + (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) + ); + + Strtoi64 (StartingAddrStr, &StartingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); + Strtoi64 (EndingAddrStr, &EndingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); + RamDisk->Instance = (UINT16) Strtoi (InstanceStr); + CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid); + + return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; +} + +/** + Converts a text device path node to text virtual cd device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Text device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextVirtualCd ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *StartingAddrStr; + CHAR16 *EndingAddrStr; + CHAR16 *InstanceStr; + MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; + UINT64 StartingAddr; + UINT64 EndingAddr; + + StartingAddrStr = GetNextParamStr (&TextDeviceNode); + EndingAddrStr = GetNextParamStr (&TextDeviceNode); + InstanceStr = GetNextParamStr (&TextDeviceNode); + + RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_RAM_DISK_DP, + (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) + ); + + Strtoi64 (StartingAddrStr, &StartingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); + Strtoi64 (EndingAddrStr, &EndingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); + RamDisk->Instance = (UINT16) Strtoi (InstanceStr); + CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid); + + return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; +} + +/** + Converts a text device path node to text persistent virtual disk device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Text device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextPersistentVirtualDisk ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *StartingAddrStr; + CHAR16 *EndingAddrStr; + CHAR16 *InstanceStr; + MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; + UINT64 StartingAddr; + UINT64 EndingAddr; + + StartingAddrStr = GetNextParamStr (&TextDeviceNode); + EndingAddrStr = GetNextParamStr (&TextDeviceNode); + InstanceStr = GetNextParamStr (&TextDeviceNode); + + RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_RAM_DISK_DP, + (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) + ); + + Strtoi64 (StartingAddrStr, &StartingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); + Strtoi64 (EndingAddrStr, &EndingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); + RamDisk->Instance = (UINT16) Strtoi (InstanceStr); + CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid); + + return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; +} + +/** + Converts a text device path node to text persistent virtual cd device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created Text device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextPersistentVirtualCd ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *StartingAddrStr; + CHAR16 *EndingAddrStr; + CHAR16 *InstanceStr; + MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; + UINT64 StartingAddr; + UINT64 EndingAddr; + + StartingAddrStr = GetNextParamStr (&TextDeviceNode); + EndingAddrStr = GetNextParamStr (&TextDeviceNode); + InstanceStr = GetNextParamStr (&TextDeviceNode); + + RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( + MEDIA_DEVICE_PATH, + MEDIA_RAM_DISK_DP, + (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) + ); + + Strtoi64 (StartingAddrStr, &StartingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); + Strtoi64 (EndingAddrStr, &EndingAddr); + WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); + RamDisk->Instance = (UINT16) Strtoi (InstanceStr); + CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid); + + return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; +} + +/** + Converts a BBS text device path node to BBS device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to BBS device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextBbsPath ( + CHAR16 *TextDeviceNode + ) +{ + return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode); +} + +/** + Converts a text device path node to BIOS Boot Specification device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created BIOS Boot Specification device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextBBS ( + CHAR16 *TextDeviceNode + ) +{ + CHAR16 *TypeStr; + CHAR16 *IdStr; + CHAR16 *FlagsStr; + CHAR8 *AsciiStr; + BBS_BBS_DEVICE_PATH *Bbs; + + TypeStr = GetNextParamStr (&TextDeviceNode); + IdStr = GetNextParamStr (&TextDeviceNode); + FlagsStr = GetNextParamStr (&TextDeviceNode); + Bbs = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode ( + BBS_DEVICE_PATH, + BBS_BBS_DP, + (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr)) + ); + + if (StrCmp (TypeStr, L"Floppy") == 0) { + Bbs->DeviceType = BBS_TYPE_FLOPPY; + } else if (StrCmp (TypeStr, L"HD") == 0) { + Bbs->DeviceType = BBS_TYPE_HARDDRIVE; + } else if (StrCmp (TypeStr, L"CDROM") == 0) { + Bbs->DeviceType = BBS_TYPE_CDROM; + } else if (StrCmp (TypeStr, L"PCMCIA") == 0) { + Bbs->DeviceType = BBS_TYPE_PCMCIA; + } else if (StrCmp (TypeStr, L"USB") == 0) { + Bbs->DeviceType = BBS_TYPE_USB; + } else if (StrCmp (TypeStr, L"Network") == 0) { + Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK; + } else { + Bbs->DeviceType = (UINT16) Strtoi (TypeStr); + } + + AsciiStr = Bbs->String; + StrToAscii (IdStr, &AsciiStr); + + Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr); + + return (EFI_DEVICE_PATH_PROTOCOL *) Bbs; +} + +/** + Converts a text device path node to SATA device path structure. + + @param TextDeviceNode The input Text device path node. + + @return A pointer to the newly-created SATA device path structure. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DevPathFromTextSata ( + CHAR16 *TextDeviceNode + ) +{ + SATA_DEVICE_PATH *Sata; + CHAR16 *Param1; + CHAR16 *Param2; + CHAR16 *Param3; + + Param1 = GetNextParamStr (&TextDeviceNode); + Param2 = GetNextParamStr (&TextDeviceNode); + Param3 = GetNextParamStr (&TextDeviceNode); + + Sata = (SATA_DEVICE_PATH *) CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_SATA_DP, + (UINT16) sizeof (SATA_DEVICE_PATH) + ); + Sata->HBAPortNumber = (UINT16) Strtoi (Param1); + Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2); + Sata->Lun = (UINT16) Strtoi (Param3); + + return (EFI_DEVICE_PATH_PROTOCOL *) Sata; +} + +DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = { + {L"Path", DevPathFromTextPath }, + + {L"HardwarePath", DevPathFromTextHardwarePath }, + {L"Pci", DevPathFromTextPci }, + {L"PcCard", DevPathFromTextPcCard }, + {L"MemoryMapped", DevPathFromTextMemoryMapped }, + {L"VenHw", DevPathFromTextVenHw }, + {L"Ctrl", DevPathFromTextCtrl }, + {L"BMC", DevPathFromTextBmc }, + + {L"AcpiPath", DevPathFromTextAcpiPath }, + {L"Acpi", DevPathFromTextAcpi }, + {L"PciRoot", DevPathFromTextPciRoot }, + {L"PcieRoot", DevPathFromTextPcieRoot }, + {L"Floppy", DevPathFromTextFloppy }, + {L"Keyboard", DevPathFromTextKeyboard }, + {L"Serial", DevPathFromTextSerial }, + {L"ParallelPort", DevPathFromTextParallelPort }, + {L"AcpiEx", DevPathFromTextAcpiEx }, + {L"AcpiExp", DevPathFromTextAcpiExp }, + {L"AcpiAdr", DevPathFromTextAcpiAdr }, + + {L"Msg", DevPathFromTextMsg }, + {L"Ata", DevPathFromTextAta }, + {L"Scsi", DevPathFromTextScsi }, + {L"Fibre", DevPathFromTextFibre }, + {L"FibreEx", DevPathFromTextFibreEx }, + {L"I1394", DevPathFromText1394 }, + {L"USB", DevPathFromTextUsb }, + {L"I2O", DevPathFromTextI2O }, + {L"Infiniband", DevPathFromTextInfiniband }, + {L"VenMsg", DevPathFromTextVenMsg }, + {L"VenPcAnsi", DevPathFromTextVenPcAnsi }, + {L"VenVt100", DevPathFromTextVenVt100 }, + {L"VenVt100Plus", DevPathFromTextVenVt100Plus }, + {L"VenUtf8", DevPathFromTextVenUtf8 }, + {L"UartFlowCtrl", DevPathFromTextUartFlowCtrl }, + {L"SAS", DevPathFromTextSAS }, + {L"SasEx", DevPathFromTextSasEx }, + {L"NVMe", DevPathFromTextNVMe }, + {L"UFS", DevPathFromTextUfs }, + {L"SD", DevPathFromTextSd }, + {L"eMMC", DevPathFromTextEmmc }, + {L"DebugPort", DevPathFromTextDebugPort }, + {L"MAC", DevPathFromTextMAC }, + {L"IPv4", DevPathFromTextIPv4 }, + {L"IPv6", DevPathFromTextIPv6 }, + {L"Uart", DevPathFromTextUart }, + {L"UsbClass", DevPathFromTextUsbClass }, + {L"UsbAudio", DevPathFromTextUsbAudio }, + {L"UsbCDCControl", DevPathFromTextUsbCDCControl }, + {L"UsbHID", DevPathFromTextUsbHID }, + {L"UsbImage", DevPathFromTextUsbImage }, + {L"UsbPrinter", DevPathFromTextUsbPrinter }, + {L"UsbMassStorage", DevPathFromTextUsbMassStorage }, + {L"UsbHub", DevPathFromTextUsbHub }, + {L"UsbCDCData", DevPathFromTextUsbCDCData }, + {L"UsbSmartCard", DevPathFromTextUsbSmartCard }, + {L"UsbVideo", DevPathFromTextUsbVideo }, + {L"UsbDiagnostic", DevPathFromTextUsbDiagnostic }, + {L"UsbWireless", DevPathFromTextUsbWireless }, + {L"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate }, + {L"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge }, + {L"UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement }, + {L"UsbWwid", DevPathFromTextUsbWwid }, + {L"Unit", DevPathFromTextUnit }, + {L"iSCSI", DevPathFromTextiSCSI }, + {L"Vlan", DevPathFromTextVlan }, + {L"Uri", DevPathFromTextUri }, + {L"Bluetooth", DevPathFromTextBluetooth }, + {L"Wi-Fi", DevPathFromTextWiFi }, + {L"MediaPath", DevPathFromTextMediaPath }, + {L"HD", DevPathFromTextHD }, + {L"CDROM", DevPathFromTextCDROM }, + {L"VenMedia", DevPathFromTextVenMedia }, + {L"Media", DevPathFromTextMedia }, + {L"Fv", DevPathFromTextFv }, + {L"FvFile", DevPathFromTextFvFile }, + {L"Offset", DevPathFromTextRelativeOffsetRange }, + {L"RamDisk", DevPathFromTextRamDisk }, + {L"VirtualDisk", DevPathFromTextVirtualDisk }, + {L"VirtualCD", DevPathFromTextVirtualCd }, + {L"PersistentVirtualDisk", DevPathFromTextPersistentVirtualDisk }, + {L"PersistentVirtualCD", DevPathFromTextPersistentVirtualCd }, + + {L"BbsPath", DevPathFromTextBbsPath }, + {L"BBS", DevPathFromTextBBS }, + {L"Sata", DevPathFromTextSata }, + {NULL, NULL} +}; + +/** + Convert text to the binary representation of a device node. + + @param TextDeviceNode TextDeviceNode points to the text representation of a device + node. Conversion starts with the first character and continues + until the first non-device node character. + + @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was + insufficient memory or text unsupported. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibConvertTextToDeviceNode ( + CONST CHAR16 *TextDeviceNode + ) +{ + DEVICE_PATH_FROM_TEXT FromText; + CHAR16 *ParamStr; + EFI_DEVICE_PATH_PROTOCOL *DeviceNode; + CHAR16 *DeviceNodeStr; + UINTN Index; + + if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) { + return NULL; + } + + ParamStr = NULL; + FromText = NULL; + DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode); + ASSERT (DeviceNodeStr != NULL); + + for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) { + ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText); + if (ParamStr != NULL) { + FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function; + break; + } + } + + if (FromText == NULL) { + // + // A file path + // + FromText = DevPathFromTextFilePath; + DeviceNode = FromText (DeviceNodeStr); + } else { + DeviceNode = FromText (ParamStr); + free (ParamStr); + } + + free (DeviceNodeStr); + + return DeviceNode; +} + +/** + Convert text to the binary representation of a device path. + + + @param TextDevicePath TextDevicePath points to the text representation of a device + path. Conversion starts with the first character and continues + until the first non-device node character. + + @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or + there was insufficient memory. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibConvertTextToDevicePath ( + CONST CHAR16 *TextDevicePath + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DeviceNode; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + CHAR16 *DevicePathStr; + CHAR16 *Str; + CHAR16 *DeviceNodeStr; + BOOLEAN IsInstanceEnd; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) { + return NULL; + } + + DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH); + ASSERT (DevicePath != NULL); + SetDevicePathEndNode (DevicePath); + + DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath); + + Str = DevicePathStr; + while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) { + DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr); + + NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode); + free (DevicePath); + free (DeviceNode); + DevicePath = NewDevicePath; + + if (IsInstanceEnd) { + DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH); + ASSERT (DeviceNode != NULL); + SetDevicePathEndNode (DeviceNode); + DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; + + NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode); + free (DevicePath); + free (DeviceNode); + DevicePath = NewDevicePath; + } + } + + free (DevicePathStr); + return DevicePath; +} diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.c b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c new file mode 100644 index 0000000000..d4ec2742b7 --- /dev/null +++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c @@ -0,0 +1,875 @@ +/** @file + Device Path services. The thing to remember is device paths are built out of + nodes. The device path is terminated by an end node that is length + sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL) + all over this file. + + The only place where multi-instance device paths are supported is in + environment varibles. Multi-instance device paths should never be placed + on a Handle. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "UefiDevicePathLib.h" +#include + +// +// Template for an end-of-device path node. +// +CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } +}; + +/** + Determine whether a given device path is valid. + If DevicePath is NULL, then ASSERT(). + + @param DevicePath A pointer to a device path data structure. + @param MaxSize The maximum size of the device path data structure. + + @retval TRUE DevicePath is valid. + @retval FALSE The length of any node node in the DevicePath is less + than sizeof (EFI_DEVICE_PATH_PROTOCOL). + @retval FALSE If MaxSize is not zero, the size of the DevicePath + exceeds MaxSize. + @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node + count of the DevicePath exceeds PcdMaximumDevicePathNodeCount. +**/ +BOOLEAN +IsDevicePathValid ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + UINTN MaxSize + ) +{ + UINTN Count; + UINTN Size; + UINTN NodeLength; + + ASSERT (DevicePath != NULL); + + if (MaxSize == 0) { + MaxSize = MAX_UINTN; + } + + // + // Validate the input size big enough to touch the first node. + // + if (MaxSize < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { + return FALSE; + } + + for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) { + NodeLength = DevicePathNodeLength (DevicePath); + if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { + return FALSE; + } + + if (NodeLength > MAX_UINTN - Size) { + return FALSE; + } + Size += NodeLength; + + // + // Validate next node before touch it. + // + if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) { + return FALSE; + } + + Count++; + if (Count >= MAX_DEVICE_PATH_NODE_COUNT) { + return FALSE; + } + + } + + // + // Only return TRUE when the End Device Path node is valid. + // + return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH); +} + + +/** + Returns the Type field of a device path node. + + Returns the Type field of the device path node specified by Node. + + If Node is NULL, then ASSERT(). + + @param Node A pointer to a device path node data structure. + + @return The Type field of the device path node specified by Node. + +**/ +UINT8 +DevicePathType ( + CONST VOID *Node + ) +{ + ASSERT (Node != NULL); + return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type; +} + +/** + Returns the SubType field of a device path node. + + Returns the SubType field of the device path node specified by Node. + + If Node is NULL, then ASSERT(). + + @param Node A pointer to a device path node data structure. + + @return The SubType field of the device path node specified by Node. + +**/ +UINT8 +DevicePathSubType ( + CONST VOID *Node + ) +{ + ASSERT (Node != NULL); + return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType; +} + +/** + Returns the 16-bit Length field of a device path node. + + Returns the 16-bit Length field of the device path node specified by Node. + Node is not required to be aligned on a 16-bit boundary, so it is recommended + that a function such as ReadUnaligned16() be used to extract the contents of + the Length field. + + If Node is NULL, then ASSERT(). + + @param Node A pointer to a device path node data structure. + + @return The 16-bit Length field of the device path node specified by Node. + +**/ +UINTN +DevicePathNodeLength ( + CONST VOID *Node + ) +{ + ASSERT (Node != NULL); + return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]); +} + +/** + Returns a pointer to the next node in a device path. + + Returns a pointer to the device path node that follows the device path node + specified by Node. + + If Node is NULL, then ASSERT(). + + @param Node A pointer to a device path node data structure. + + @return a pointer to the device path node that follows the device path node + specified by Node. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +NextDevicePathNode ( + CONST VOID *Node + ) +{ + ASSERT (Node != NULL); + return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength(Node)); +} + +/** + Determines if a device path node is an end node of a device path. + This includes nodes that are the end of a device path instance and nodes that + are the end of an entire device path. + + Determines if the device path node specified by Node is an end node of a device path. + This includes nodes that are the end of a device path instance and nodes that are the + end of an entire device path. If Node represents an end node of a device path, + then TRUE is returned. Otherwise, FALSE is returned. + + If Node is NULL, then ASSERT(). + + @param Node A pointer to a device path node data structure. + + @retval TRUE The device path node specified by Node is an end node of a + device path. + @retval FALSE The device path node specified by Node is not an end node of + a device path. + +**/ +BOOLEAN +IsDevicePathEndType ( + CONST VOID *Node + ) +{ + ASSERT (Node != NULL); + return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE); +} + +/** + Determines if a device path node is an end node of an entire device path. + + Determines if a device path node specified by Node is an end node of an entire + device path. If Node represents the end of an entire device path, then TRUE is + returned. Otherwise, FALSE is returned. + + If Node is NULL, then ASSERT(). + + @param Node A pointer to a device path node data structure. + + @retval TRUE The device path node specified by Node is the end of an entire + device path. + @retval FALSE The device path node specified by Node is not the end of an + entire device path. + +**/ +BOOLEAN +IsDevicePathEnd ( + CONST VOID *Node + ) +{ + ASSERT (Node != NULL); + return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE); +} + +/** + Determines if a device path node is an end node of a device path instance. + + Determines if a device path node specified by Node is an end node of a device + path instance. If Node represents the end of a device path instance, then TRUE + is returned. Otherwise, FALSE is returned. + + If Node is NULL, then ASSERT(). + + @param Node A pointer to a device path node data structure. + + @retval TRUE The device path node specified by Node is the end of a device + path instance. + @retval FALSE The device path node specified by Node is not the end of a + device path instance. + +**/ +BOOLEAN +IsDevicePathEndInstance ( + CONST VOID *Node + ) +{ + ASSERT (Node != NULL); + return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE); +} + +/** + Sets the length, in bytes, of a device path node. + + Sets the length of the device path node specified by Node to the value specified + by NodeLength. NodeLength is returned. Node is not required to be aligned on + a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16() + be used to set the contents of the Length field. + + If Node is NULL, then ASSERT(). + If NodeLength >= SIZE_64KB, then ASSERT(). + If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT(). + + @param Node A pointer to a device path node data structure. + @param Length The length, in bytes, of the device path node. + + @return Length + +**/ +UINT16 +SetDevicePathNodeLength ( + VOID *Node, + UINTN Length + ) +{ + ASSERT (Node != NULL); + ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB)); + return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length)); +} + +/** + Fills in all the fields of a device path node that is the end of an entire device path. + + Fills in all the fields of a device path node specified by Node so Node represents + the end of an entire device path. The Type field of Node is set to + END_DEVICE_PATH_TYPE, the SubType field of Node is set to + END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to + END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary, + so it is recommended that a function such as WriteUnaligned16() be used to set + the contents of the Length field. + + If Node is NULL, then ASSERT(). + + @param Node A pointer to a device path node data structure. + +**/ +VOID +SetDevicePathEndNode ( + VOID *Node + ) +{ + ASSERT (Node != NULL); + memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath)); +} + +/** + Returns the size of a device path in bytes. + + This function returns the size, in bytes, of the device path data structure + specified by DevicePath including the end of device path node. + If DevicePath is NULL or invalid, then 0 is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval 0 If DevicePath is NULL or invalid. + @retval Others The size of a device path in bytes. + +**/ +UINTN +UefiDevicePathLibGetDevicePathSize ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + CONST EFI_DEVICE_PATH_PROTOCOL *Start; + + if (DevicePath == NULL) { + return 0; + } + + if (!IsDevicePathValid (DevicePath, 0)) { + return 0; + } + + // + // Search for the end of the device path structure + // + Start = DevicePath; + while (!IsDevicePathEnd (DevicePath)) { + DevicePath = NextDevicePathNode (DevicePath); + } + + // + // Compute the size and add back in the size of the end device path structure + // + return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath); +} + +/** + Creates a new copy of an existing device path. + + This function allocates space for a new copy of the device path specified by DevicePath. + If DevicePath is NULL, then NULL is returned. If the memory is successfully + allocated, then the contents of DevicePath are copied to the newly allocated + buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned. + The memory for the new device path is allocated from EFI boot services memory. + It is the responsibility of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + + @retval NULL DevicePath is NULL or invalid. + @retval Others A pointer to the duplicated device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibDuplicateDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + UINTN Size; + + // + // Compute the size + // + Size = GetDevicePathSize (DevicePath); + if (Size == 0) { + return NULL; + } + + // + // Allocate space for duplicate device path + // + + return AllocateCopyPool (Size, DevicePath); +} + +/** + Creates a new device path by appending a second device path to a first device path. + + This function creates a new device path by appending a copy of SecondDevicePath + to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path + device node from SecondDevicePath is retained. The newly created device path is + returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of + SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored, + and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and + SecondDevicePath are NULL, then a copy of an end-of-device-path is returned. + + If there is not enough memory for the newly allocated buffer, then NULL is returned. + The memory for the new device path is allocated from EFI boot services memory. + It is the responsibility of the caller to free the memory allocated. + + @param FirstDevicePath A pointer to a device path data structure. + @param SecondDevicePath A pointer to a device path data structure. + + @retval NULL If there is not enough memory for the newly allocated buffer. + @retval NULL If FirstDevicePath or SecondDevicePath is invalid. + @retval Others A pointer to the new device path if success. + Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath + ) +{ + UINTN Size; + UINTN Size1; + UINTN Size2; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePath2; + + // + // If there's only 1 path, just duplicate it. + // + if (FirstDevicePath == NULL) { + return DuplicateDevicePath ((SecondDevicePath != NULL) ? SecondDevicePath : &mUefiDevicePathLibEndDevicePath); + } + + if (SecondDevicePath == NULL) { + return DuplicateDevicePath (FirstDevicePath); + } + + if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) { + return NULL; + } + + // + // Allocate space for the combined device path. It only has one end node of + // length EFI_DEVICE_PATH_PROTOCOL. + // + Size1 = GetDevicePathSize (FirstDevicePath); + Size2 = GetDevicePathSize (SecondDevicePath); + Size = Size1 + Size2 - END_DEVICE_PATH_LENGTH; + + NewDevicePath = AllocatePool (Size); + + if (NewDevicePath != NULL) { + NewDevicePath = memcpy (NewDevicePath, FirstDevicePath, Size1); + // + // Over write FirstDevicePath EndNode and do the copy + // + DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + + (Size1 - END_DEVICE_PATH_LENGTH)); + memcpy (DevicePath2, SecondDevicePath, Size2); + } + + return NewDevicePath; +} + +/** + Creates a new path by appending the device node to the device path. + + This function creates a new device path by appending a copy of the device node + specified by DevicePathNode to a copy of the device path specified by DevicePath + in an allocated buffer. The end-of-device-path device node is moved after the + end of the appended device node. + If DevicePathNode is NULL then a copy of DevicePath is returned. + If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device + path device node is returned. + If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path + device node is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + @param DevicePathNode A pointer to a single device path node. + + @retval NULL If there is not enough memory for the new device path. + @retval Others A pointer to the new device path if success. + A copy of DevicePathNode followed by an end-of-device-path node + if both FirstDevicePath and SecondDevicePath are NULL. + A copy of an end-of-device-path node if both FirstDevicePath + and SecondDevicePath are NULL. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePathNode ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode + ) +{ + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *NextNode; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + UINTN NodeLength; + + if (DevicePathNode == NULL) { + return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : &mUefiDevicePathLibEndDevicePath); + } + // + // Build a Node that has a terminator on it + // + NodeLength = DevicePathNodeLength (DevicePathNode); + + TempDevicePath = AllocatePool (NodeLength + END_DEVICE_PATH_LENGTH); + if (TempDevicePath == NULL) { + return NULL; + } + TempDevicePath = memcpy (TempDevicePath, DevicePathNode, NodeLength); + // + // Add and end device path node to convert Node to device path + // + NextNode = NextDevicePathNode (TempDevicePath); + SetDevicePathEndNode (NextNode); + // + // Append device paths + // + NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath); + + free (TempDevicePath); + + return NewDevicePath; +} + +/** + Creates a new device path by appending the specified device path instance to the specified device + path. + + This function creates a new device path by appending a copy of the device path + instance specified by DevicePathInstance to a copy of the device path specified + by DevicePath in a allocated buffer. + The end-of-device-path device node is moved after the end of the appended device + path instance and a new end-of-device-path-instance node is inserted between. + If DevicePath is NULL, then a copy if DevicePathInstance is returned. + If DevicePathInstance is NULL, then NULL is returned. + If DevicePath or DevicePathInstance is invalid, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + @param DevicePathInstance A pointer to a device path instance. + + @return A pointer to the new device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePathInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance + ) +{ + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + UINTN SrcSize; + UINTN InstanceSize; + + if (DevicePath == NULL) { + return DuplicateDevicePath (DevicePathInstance); + } + + if (DevicePathInstance == NULL) { + return NULL; + } + + if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid (DevicePathInstance, 0)) { + return NULL; + } + + SrcSize = GetDevicePathSize (DevicePath); + InstanceSize = GetDevicePathSize (DevicePathInstance); + + NewDevicePath = AllocatePool (SrcSize + InstanceSize); + if (NewDevicePath != NULL) { + + TempDevicePath = memcpy (NewDevicePath, DevicePath, SrcSize);; + + while (!IsDevicePathEnd (TempDevicePath)) { + TempDevicePath = NextDevicePathNode (TempDevicePath); + } + + TempDevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; + TempDevicePath = NextDevicePathNode (TempDevicePath); + memcpy (TempDevicePath, DevicePathInstance, InstanceSize); + } + + return NewDevicePath; +} + +/** + Creates a copy of the current device path instance and returns a pointer to the next device path + instance. + + This function creates a copy of the current device path instance. It also updates + DevicePath to point to the next device path instance in the device path (or NULL + if no more) and updates Size to hold the size of the device path instance copy. + If DevicePath is NULL, then NULL is returned. + If DevicePath points to a invalid device path, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + If Size is NULL, then ASSERT(). + + @param DevicePath On input, this holds the pointer to the current + device path instance. On output, this holds + the pointer to the next device path instance + or NULL if there are no more device path + instances in the device path pointer to a + device path data structure. + @param Size On output, this holds the size of the device + path instance, in bytes or zero, if DevicePath + is NULL. + + @return A pointer to the current device path instance. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibGetNextDevicePathInstance ( + EFI_DEVICE_PATH_PROTOCOL **DevicePath, + UINTN *Size + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevPath; + EFI_DEVICE_PATH_PROTOCOL *ReturnValue; + UINT8 Temp; + + ASSERT (Size != NULL); + + if (DevicePath == NULL || *DevicePath == NULL) { + *Size = 0; + return NULL; + } + + if (!IsDevicePathValid (*DevicePath, 0)) { + return NULL; + } + + // + // Find the end of the device path instance + // + DevPath = *DevicePath; + while (!IsDevicePathEndType (DevPath)) { + DevPath = NextDevicePathNode (DevPath); + } + + // + // Compute the size of the device path instance + // + *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL); + + // + // Make a copy and return the device path instance + // + Temp = DevPath->SubType; + DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; + ReturnValue = DuplicateDevicePath (*DevicePath); + DevPath->SubType = Temp; + + // + // If DevPath is the end of an entire device path, then another instance + // does not follow, so *DevicePath is set to NULL. + // + if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { + *DevicePath = NULL; + } else { + *DevicePath = NextDevicePathNode (DevPath); + } + + return ReturnValue; +} + +/** + Creates a device node. + + This function creates a new device node in a newly allocated buffer of size + NodeLength and initializes the device path node header with NodeType and NodeSubType. + The new device path node is returned. + If NodeLength is smaller than a device path header, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param NodeType The device node type for the new device node. + @param NodeSubType The device node sub-type for the new device node. + @param NodeLength The length of the new device node. + + @return The new device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibCreateDeviceNode ( + UINT8 NodeType, + UINT8 NodeSubType, + UINT16 NodeLength + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { + // + // NodeLength is less than the size of the header. + // + return NULL; + } + + DevicePath = AllocateZeroPool (NodeLength); + if (DevicePath != NULL) { + DevicePath->Type = NodeType; + DevicePath->SubType = NodeSubType; + SetDevicePathNodeLength (DevicePath, NodeLength); + } + + return DevicePath; +} + +/** + Determines if a device path is single or multi-instance. + + This function returns TRUE if the device path specified by DevicePath is + multi-instance. + Otherwise, FALSE is returned. + If DevicePath is NULL or invalid, then FALSE is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval TRUE DevicePath is multi-instance. + @retval FALSE DevicePath is not multi-instance, or DevicePath + is NULL or invalid. + +**/ +BOOLEAN +UefiDevicePathLibIsDevicePathMultiInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + CONST EFI_DEVICE_PATH_PROTOCOL *Node; + + if (DevicePath == NULL) { + return FALSE; + } + + if (!IsDevicePathValid (DevicePath, 0)) { + return FALSE; + } + + Node = DevicePath; + while (!IsDevicePathEnd (Node)) { + if (IsDevicePathEndInstance (Node)) { + return TRUE; + } + + Node = NextDevicePathNode (Node); + } + + return FALSE; +} + + +/** + Retrieves the device path protocol from a handle. + + This function returns the device path protocol from the handle specified by Handle. + If Handle is NULL or Handle does not contain a device path protocol, then NULL + is returned. + + @param Handle The handle from which to retrieve the device + path protocol. + + @return The device path protocol from the handle specified by Handle. + +**/ +/* +EFI_DEVICE_PATH_PROTOCOL * +DevicePathFromHandle ( + EFI_HANDLE Handle + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_STATUS Status; + + Status = gBS->HandleProtocol ( + Handle, + &gEfiDevicePathProtocolGuid, + (VOID *) &DevicePath + ); + if (EFI_ERROR (Status)) { + DevicePath = NULL; + } + return DevicePath; +} +*/ +/** + Allocates a device path for a file and appends it to an existing device path. + + If Device is a valid device handle that contains a device path protocol, then a device path for + the file specified by FileName is allocated and appended to the device path associated with the + handle Device. The allocated device path is returned. If Device is NULL or Device is a handle + that does not support the device path protocol, then a device path containing a single device + path node for the file specified by FileName is allocated and returned. + The memory for the new device path is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + If FileName is NULL, then ASSERT(). + If FileName is not aligned on a 16-bit boundary, then ASSERT(). + + @param Device A pointer to a device handle. This parameter + is optional and may be NULL. + @param FileName A pointer to a Null-terminated Unicode string. + + @return The allocated device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +FileDevicePath ( + EFI_HANDLE Device, OPTIONAL + CONST CHAR16 *FileName + ) +{ + UINTN Size; + FILEPATH_DEVICE_PATH *FilePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; + + DevicePath = NULL; + + Size = StrSize (FileName); + FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH); + if (FileDevicePath != NULL) { + FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath; + FilePath->Header.Type = MEDIA_DEVICE_PATH; + FilePath->Header.SubType = MEDIA_FILEPATH_DP; + memcpy (&FilePath->PathName, FileName, Size); + SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); + SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header)); + + //if (Device != NULL) { + // DevicePath = DevicePathFromHandle (Device); + //} + + DevicePath = AppendDevicePath (DevicePath, FileDevicePath); + free (FileDevicePath); + } + + return DevicePath; +} diff --git a/BaseTools/Source/C/DevicePath/GNUmakefile b/BaseTools/Source/C/DevicePath/GNUmakefile new file mode 100644 index 0000000000..27f6fa1cb0 --- /dev/null +++ b/BaseTools/Source/C/DevicePath/GNUmakefile @@ -0,0 +1,30 @@ +## @file +# GNU/Linux makefile for 'DevicePath' module build. +# +# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +ARCH ?= IA32 +MAKEROOT ?= .. + +APPNAME = DevicePath + +OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o DevicePathUtilities.o + +include $(MAKEROOT)/Makefiles/app.makefile + +LIBS = -lCommon +ifeq ($(CYGWIN), CYGWIN) + LIBS += -L/lib/e2fsprogs -luuid +endif + +ifeq ($(LINUX), Linux) + LIBS += -luuid +endif + diff --git a/BaseTools/Source/C/DevicePath/Makefile b/BaseTools/Source/C/DevicePath/Makefile new file mode 100644 index 0000000000..a069c227f2 --- /dev/null +++ b/BaseTools/Source/C/DevicePath/Makefile @@ -0,0 +1,24 @@ +## @file +# Windows makefile for 'DevicePath' module build. +# +# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +!INCLUDE ..\Makefiles\ms.common + +APPNAME = DevicePath + +LIBS = $(LIB_PATH)\Common.lib + +OBJECTS = DevicePath.obj UefiDevicePathLib.obj DevicePathFromText.obj DevicePathUtilities.obj + +#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib + +!INCLUDE ..\Makefiles\ms.app + diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c new file mode 100644 index 0000000000..a2e0322e27 --- /dev/null +++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c @@ -0,0 +1,298 @@ +/** @file + Device Path services. The thing to remember is device paths are built out of + nodes. The device path is terminated by an end node that is length + sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL) + all over this file. + + The only place where multi-instance device paths are supported is in + environment varibles. Multi-instance device paths should never be placed + on a Handle. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "UefiDevicePathLib.h" + +/** + Returns the size of a device path in bytes. + + This function returns the size, in bytes, of the device path data structure + specified by DevicePath including the end of device path node. + If DevicePath is NULL or invalid, then 0 is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval 0 If DevicePath is NULL or invalid. + @retval Others The size of a device path in bytes. + +**/ +UINTN +GetDevicePathSize ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + return UefiDevicePathLibGetDevicePathSize (DevicePath); +} + +/** + Creates a new copy of an existing device path. + + This function allocates space for a new copy of the device path specified by DevicePath. + If DevicePath is NULL, then NULL is returned. If the memory is successfully + allocated, then the contents of DevicePath are copied to the newly allocated + buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned. + The memory for the new device path is allocated from EFI boot services memory. + It is the responsibility of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + + @retval NULL DevicePath is NULL or invalid. + @retval Others A pointer to the duplicated device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +DuplicateDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + return UefiDevicePathLibDuplicateDevicePath (DevicePath); +} + +/** + Creates a new device path by appending a second device path to a first device path. + + This function creates a new device path by appending a copy of SecondDevicePath + to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path + device node from SecondDevicePath is retained. The newly created device path is + returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of + SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored, + and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and + SecondDevicePath are NULL, then a copy of an end-of-device-path is returned. + + If there is not enough memory for the newly allocated buffer, then NULL is returned. + The memory for the new device path is allocated from EFI boot services memory. + It is the responsibility of the caller to free the memory allocated. + + @param FirstDevicePath A pointer to a device path data structure. + @param SecondDevicePath A pointer to a device path data structure. + + @retval NULL If there is not enough memory for the newly allocated buffer. + @retval NULL If FirstDevicePath or SecondDevicePath is invalid. + @retval Others A pointer to the new device path if success. + Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +AppendDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL + ) +{ + return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath); +} + +/** + Creates a new path by appending the device node to the device path. + + This function creates a new device path by appending a copy of the device node + specified by DevicePathNode to a copy of the device path specified by DevicePath + in an allocated buffer. The end-of-device-path device node is moved after the + end of the appended device node. + If DevicePathNode is NULL then a copy of DevicePath is returned. + If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device + path device node is returned. + If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path + device node is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + @param DevicePathNode A pointer to a single device path node. + + @retval NULL If there is not enough memory for the new device path. + @retval Others A pointer to the new device path if success. + A copy of DevicePathNode followed by an end-of-device-path node + if both FirstDevicePath and SecondDevicePath are NULL. + A copy of an end-of-device-path node if both FirstDevicePath + and SecondDevicePath are NULL. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +AppendDevicePathNode ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL + ) +{ + return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode); +} + +/** + Creates a new device path by appending the specified device path instance to the specified device + path. + + This function creates a new device path by appending a copy of the device path + instance specified by DevicePathInstance to a copy of the device path specified + by DevicePath in a allocated buffer. + The end-of-device-path device node is moved after the end of the appended device + path instance and a new end-of-device-path-instance node is inserted between. + If DevicePath is NULL, then a copy if DevicePathInstance is returned. + If DevicePathInstance is NULL, then NULL is returned. + If DevicePath or DevicePathInstance is invalid, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + @param DevicePathInstance A pointer to a device path instance. + + @return A pointer to the new device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +AppendDevicePathInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL + ) +{ + return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance); +} + +/** + Creates a copy of the current device path instance and returns a pointer to the next device path + instance. + + This function creates a copy of the current device path instance. It also updates + DevicePath to point to the next device path instance in the device path (or NULL + if no more) and updates Size to hold the size of the device path instance copy. + If DevicePath is NULL, then NULL is returned. + If DevicePath points to a invalid device path, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + If Size is NULL, then ASSERT(). + + @param DevicePath On input, this holds the pointer to the current + device path instance. On output, this holds + the pointer to the next device path instance + or NULL if there are no more device path + instances in the device path pointer to a + device path data structure. + @param Size On output, this holds the size of the device + path instance, in bytes or zero, if DevicePath + is NULL. + + @return A pointer to the current device path instance. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +GetNextDevicePathInstance ( + EFI_DEVICE_PATH_PROTOCOL **DevicePath, + UINTN *Size + ) +{ + return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size); +} + +/** + Creates a device node. + + This function creates a new device node in a newly allocated buffer of size + NodeLength and initializes the device path node header with NodeType and NodeSubType. + The new device path node is returned. + If NodeLength is smaller than a device path header, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param NodeType The device node type for the new device node. + @param NodeSubType The device node sub-type for the new device node. + @param NodeLength The length of the new device node. + + @return The new device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +CreateDeviceNode ( + UINT8 NodeType, + UINT8 NodeSubType, + UINT16 NodeLength + ) +{ + return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength); +} + +/** + Determines if a device path is single or multi-instance. + + This function returns TRUE if the device path specified by DevicePath is + multi-instance. + Otherwise, FALSE is returned. + If DevicePath is NULL or invalid, then FALSE is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval TRUE DevicePath is multi-instance. + @retval FALSE DevicePath is not multi-instance, or DevicePath + is NULL or invalid. + +**/ +BOOLEAN +IsDevicePathMultiInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath); +} + +/** + Convert text to the binary representation of a device node. + + @param TextDeviceNode TextDeviceNode points to the text representation of a device + node. Conversion starts with the first character and continues + until the first non-device node character. + + @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was + insufficient memory or text unsupported. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +ConvertTextToDeviceNode ( + CONST CHAR16 *TextDeviceNode + ) +{ + return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode); +} + +/** + Convert text to the binary representation of a device path. + + + @param TextDevicePath TextDevicePath points to the text representation of a device + path. Conversion starts with the first character and continues + until the first non-device node character. + + @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or + there was insufficient memory. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +ConvertTextToDevicePath ( + CONST CHAR16 *TextDevicePath + ) +{ + return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath); +} diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h new file mode 100644 index 0000000000..7bc974d771 --- /dev/null +++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h @@ -0,0 +1,452 @@ +/** @file + Definition for Device Path library. + +Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#ifndef _UEFI_DEVICE_PATH_LIB_H_ +#define _UEFI_DEVICE_PATH_LIB_H_ + +#include +#include +#include +#include +#include +#ifdef __GNUC__ +#include +#else +#include +#endif +#include +#include +#include +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" + +#define END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL)) +#define MAX_DEVICE_PATH_NODE_COUNT 1024 +#define SIZE_64KB 0x00010000 + +// +// Private Data structure +// +typedef +EFI_DEVICE_PATH_PROTOCOL * +(*DEVICE_PATH_FROM_TEXT) ( + IN CHAR16 *Str + ); + +typedef struct { + CHAR16 *Str; + UINTN Count; + UINTN Capacity; +} POOL_PRINT; + + +typedef struct { + CHAR16 *DevicePathNodeText; + DEVICE_PATH_FROM_TEXT Function; +} DEVICE_PATH_FROM_TEXT_TABLE; + +typedef struct { + BOOLEAN ClassExist; + UINT8 Class; + BOOLEAN SubClassExist; + UINT8 SubClass; +} USB_CLASS_TEXT; + +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_CDCCONTROL 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_IMAGE 6 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_CDCDATA 10 +#define USB_CLASS_SMART_CARD 11 +#define USB_CLASS_VIDEO 14 +#define USB_CLASS_DIAGNOSTIC 220 +#define USB_CLASS_WIRELESS 224 + +#define USB_CLASS_RESERVE 254 +#define USB_SUBCLASS_FW_UPDATE 1 +#define USB_SUBCLASS_IRDA_BRIDGE 2 +#define USB_SUBCLASS_TEST 3 + +#define RFC_1700_UDP_PROTOCOL 17 +#define RFC_1700_TCP_PROTOCOL 6 + +#pragma pack(1) + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_GUID Guid; + UINT8 VendorDefinedData[1]; +} VENDOR_DEFINED_HARDWARE_DEVICE_PATH; + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_GUID Guid; + UINT8 VendorDefinedData[1]; +} VENDOR_DEFINED_MESSAGING_DEVICE_PATH; + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_GUID Guid; + UINT8 VendorDefinedData[1]; +} VENDOR_DEFINED_MEDIA_DEVICE_PATH; + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 Hid; + UINT32 Uid; + UINT32 Cid; + CHAR8 HidUidCidStr[3]; +} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR; + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT16 NetworkProtocol; + UINT16 LoginOption; + UINT64 Lun; + UINT16 TargetPortalGroupTag; + CHAR8 TargetName[1]; +} ISCSI_DEVICE_PATH_WITH_NAME; + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_GUID Guid; + UINT8 VendorDefinedData[1]; +} VENDOR_DEVICE_PATH_WITH_DATA; + +#pragma pack() + +/** + Returns the size of a device path in bytes. + + This function returns the size, in bytes, of the device path data structure + specified by DevicePath including the end of device path node. + If DevicePath is NULL or invalid, then 0 is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval 0 If DevicePath is NULL or invalid. + @retval Others The size of a device path in bytes. + +**/ +UINTN +UefiDevicePathLibGetDevicePathSize ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +/** + Creates a new copy of an existing device path. + + This function allocates space for a new copy of the device path specified by DevicePath. + If DevicePath is NULL, then NULL is returned. If the memory is successfully + allocated, then the contents of DevicePath are copied to the newly allocated + buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned. + The memory for the new device path is allocated from EFI boot services memory. + It is the responsibility of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + + @retval NULL DevicePath is NULL or invalid. + @retval Others A pointer to the duplicated device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibDuplicateDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +/** + Creates a new device path by appending a second device path to a first device path. + + This function creates a new device path by appending a copy of SecondDevicePath + to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path + device node from SecondDevicePath is retained. The newly created device path is + returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of + SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored, + and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and + SecondDevicePath are NULL, then a copy of an end-of-device-path is returned. + + If there is not enough memory for the newly allocated buffer, then NULL is returned. + The memory for the new device path is allocated from EFI boot services memory. + It is the responsibility of the caller to free the memory allocated. + + @param FirstDevicePath A pointer to a device path data structure. + @param SecondDevicePath A pointer to a device path data structure. + + @retval NULL If there is not enough memory for the newly allocated buffer. + @retval NULL If FirstDevicePath or SecondDevicePath is invalid. + @retval Others A pointer to the new device path if success. + Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL + ); + +/** + Creates a new path by appending the device node to the device path. + + This function creates a new device path by appending a copy of the device node + specified by DevicePathNode to a copy of the device path specified by DevicePath + in an allocated buffer. The end-of-device-path device node is moved after the + end of the appended device node. + If DevicePathNode is NULL then a copy of DevicePath is returned. + If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device + path device node is returned. + If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path + device node is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + @param DevicePathNode A pointer to a single device path node. + + @retval NULL If there is not enough memory for the new device path. + @retval Others A pointer to the new device path if success. + A copy of DevicePathNode followed by an end-of-device-path node + if both FirstDevicePath and SecondDevicePath are NULL. + A copy of an end-of-device-path node if both FirstDevicePath + and SecondDevicePath are NULL. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePathNode ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL + ); + +/** + Creates a new device path by appending the specified device path instance to the specified device + path. + + This function creates a new device path by appending a copy of the device path + instance specified by DevicePathInstance to a copy of the device path specified + by DevicePath in a allocated buffer. + The end-of-device-path device node is moved after the end of the appended device + path instance and a new end-of-device-path-instance node is inserted between. + If DevicePath is NULL, then a copy if DevicePathInstance is returned. + If DevicePathInstance is NULL, then NULL is returned. + If DevicePath or DevicePathInstance is invalid, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param DevicePath A pointer to a device path data structure. + @param DevicePathInstance A pointer to a device path instance. + + @return A pointer to the new device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePathInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL + ); + +/** + Creates a copy of the current device path instance and returns a pointer to the next device path + instance. + + This function creates a copy of the current device path instance. It also updates + DevicePath to point to the next device path instance in the device path (or NULL + if no more) and updates Size to hold the size of the device path instance copy. + If DevicePath is NULL, then NULL is returned. + If DevicePath points to a invalid device path, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + If Size is NULL, then ASSERT(). + + @param DevicePath On input, this holds the pointer to the current + device path instance. On output, this holds + the pointer to the next device path instance + or NULL if there are no more device path + instances in the device path pointer to a + device path data structure. + @param Size On output, this holds the size of the device + path instance, in bytes or zero, if DevicePath + is NULL. + + @return A pointer to the current device path instance. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibGetNextDevicePathInstance ( + EFI_DEVICE_PATH_PROTOCOL **DevicePath, + UINTN *Size + ); + +/** + Creates a device node. + + This function creates a new device node in a newly allocated buffer of size + NodeLength and initializes the device path node header with NodeType and NodeSubType. + The new device path node is returned. + If NodeLength is smaller than a device path header, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility + of the caller to free the memory allocated. + + @param NodeType The device node type for the new device node. + @param NodeSubType The device node sub-type for the new device node. + @param NodeLength The length of the new device node. + + @return The new device path. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibCreateDeviceNode ( + UINT8 NodeType, + UINT8 NodeSubType, + UINT16 NodeLength + ); + +/** + Determines if a device path is single or multi-instance. + + This function returns TRUE if the device path specified by DevicePath is + multi-instance. + Otherwise, FALSE is returned. + If DevicePath is NULL or invalid, then FALSE is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval TRUE DevicePath is multi-instance. + @retval FALSE DevicePath is not multi-instance, or DevicePath + is NULL or invalid. + +**/ +BOOLEAN +UefiDevicePathLibIsDevicePathMultiInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +/** + Convert text to the binary representation of a device node. + + @param TextDeviceNode TextDeviceNode points to the text representation of a device + node. Conversion starts with the first character and continues + until the first non-device node character. + + @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was + insufficient memory or text unsupported. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibConvertTextToDeviceNode ( + CONST CHAR16 *TextDeviceNode + ); + +/** + Convert text to the binary representation of a device path. + + + @param TextDevicePath TextDevicePath points to the text representation of a device + path. Conversion starts with the first character and continues + until the first non-device node character. + + @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or + there was insufficient memory. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibConvertTextToDevicePath ( + CONST CHAR16 *TextDevicePath + ); + +EFI_DEVICE_PATH_PROTOCOL * +CreateDeviceNode ( + UINT8 NodeType, + UINT8 NodeSubType, + UINT16 NodeLength + ); + + EFI_DEVICE_PATH_PROTOCOL * +CreateDeviceNode ( + UINT8 NodeType, + UINT8 NodeSubType, + UINT16 NodeLength + ); + +BOOLEAN +IsDevicePathMultiInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +EFI_DEVICE_PATH_PROTOCOL * +GetNextDevicePathInstance ( + EFI_DEVICE_PATH_PROTOCOL **DevicePath, + UINTN *Size + ); + +EFI_DEVICE_PATH_PROTOCOL * +AppendDevicePathInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL + ); + +EFI_DEVICE_PATH_PROTOCOL * +AppendDevicePathNode ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL + ); +EFI_DEVICE_PATH_PROTOCOL * +AppendDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL + CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL + ); + +EFI_DEVICE_PATH_PROTOCOL * +DuplicateDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +UINTN +GetDevicePathSize ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +CHAR16 * +ConvertDeviceNodeToText ( + CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode, + BOOLEAN DisplayOnly, + BOOLEAN AllowShortcuts + ); + +CHAR16 * +ConvertDevicePathToText ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + BOOLEAN DisplayOnly, + BOOLEAN AllowShortcuts + ); + +EFI_DEVICE_PATH_PROTOCOL * +ConvertTextToDeviceNode ( + CONST CHAR16 *TextDeviceNode + ); + +EFI_DEVICE_PATH_PROTOCOL * +ConvertTextToDevicePath ( + CONST CHAR16 *TextDevicePath + ); + +#endif diff --git a/BaseTools/Source/C/GNUmakefile b/BaseTools/Source/C/GNUmakefile index 0dc748267d..37421ad9f0 100644 --- a/BaseTools/Source/C/GNUmakefile +++ b/BaseTools/Source/C/GNUmakefile @@ -67,7 +67,8 @@ APPLICATIONS = \ LzmaCompress \ Split \ TianoCompress \ - VolInfo + VolInfo \ + DevicePath SUBDIRS := $(LIBRARIES) $(APPLICATIONS) diff --git a/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h b/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h new file mode 100644 index 0000000000..d6e6d75981 --- /dev/null +++ b/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h @@ -0,0 +1,62 @@ +/** @file + This file contains the Bluetooth definitions that are consumed by drivers. + These definitions are from Bluetooth Core Specification Version 4.0 June, 2010 + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _BLUETOOTH_H_ +#define _BLUETOOTH_H_ + +#pragma pack(1) + +/// +/// BLUETOOTH_ADDRESS +/// +typedef struct { + /// + /// 48bit Bluetooth device address. + /// + UINT8 Address[6]; +} BLUETOOTH_ADDRESS; + +/// +/// BLUETOOTH_CLASS_OF_DEVICE. See Bluetooth specification for detail. +/// +typedef struct { + UINT8 FormatType:2; + UINT8 MinorDeviceClass: 6; + UINT16 MajorDeviceClass: 5; + UINT16 MajorServiceClass:11; +} BLUETOOTH_CLASS_OF_DEVICE; + +/// +/// BLUETOOTH_LE_ADDRESS +/// +typedef struct { + /// + /// 48-bit Bluetooth device address + /// + UINT8 Address[6]; + /// + /// 0x00 - Public Device Address + /// 0x01 - Random Device Address + /// + UINT8 Type; +} BLUETOOTH_LE_ADDRESS; + +#pragma pack() + +#define BLUETOOTH_HCI_COMMAND_LOCAL_READABLE_NAME_MAX_SIZE 248 + +#define BLUETOOTH_HCI_LINK_KEY_SIZE 16 + +#endif diff --git a/BaseTools/Source/C/Include/Protocol/DevicePath.h b/BaseTools/Source/C/Include/Protocol/DevicePath.h new file mode 100644 index 0000000000..a5d8eea9bc --- /dev/null +++ b/BaseTools/Source/C/Include/Protocol/DevicePath.h @@ -0,0 +1,1391 @@ +/** @file + The device path protocol as defined in UEFI 2.0. + + The device path represents a programmatic path to a device, + from a software point of view. The path must persist from boot to boot, so + it can not contain things like PCI bus numbers that change from boot to boot. + +Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __EFI_DEVICE_PATH_H__ +#define __EFI_DEVICE_PATH_H__ + +#include +#include +#include + +/// +/// Device Path protocol. +/// +#define EFI_DEVICE_PATH_PROTOCOL_GUID \ + { \ + 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +/// +/// Device Path guid definition for backward-compatible with EFI1.1. +/// +#define DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL_GUID + +#pragma pack(1) + +/** + This protocol can be used on any device handle to obtain generic path/location + information concerning the physical device or logical device. If the handle does + not logically map to a physical device, the handle may not necessarily support + the device path protocol. The device path describes the location of the device + the handle is for. The size of the Device Path can be determined from the structures + that make up the Device Path. +**/ +typedef struct { + UINT8 Type; ///< 0x01 Hardware Device Path. + ///< 0x02 ACPI Device Path. + ///< 0x03 Messaging Device Path. + ///< 0x04 Media Device Path. + ///< 0x05 BIOS Boot Specification Device Path. + ///< 0x7F End of Hardware Device Path. + + UINT8 SubType; ///< Varies by Type + ///< 0xFF End Entire Device Path, or + ///< 0x01 End This Instance of a Device Path and start a new + ///< Device Path. + + UINT8 Length[2]; ///< Specific Device Path data. Type and Sub-Type define + ///< type of data. Size of data is included in Length. + +} EFI_DEVICE_PATH_PROTOCOL; + +/// +/// Device Path protocol definition for backward-compatible with EFI1.1. +/// +typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH; + +/// +/// Hardware Device Paths. +/// +#define HARDWARE_DEVICE_PATH 0x01 + +/// +/// PCI Device Path SubType. +/// +#define HW_PCI_DP 0x01 + +/// +/// PCI Device Path. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// PCI Function Number. + /// + UINT8 Function; + /// + /// PCI Device Number. + /// + UINT8 Device; +} PCI_DEVICE_PATH; + +/// +/// PCCARD Device Path SubType. +/// +#define HW_PCCARD_DP 0x02 + +/// +/// PCCARD Device Path. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Function Number (0 = First Function). + /// + UINT8 FunctionNumber; +} PCCARD_DEVICE_PATH; + +/// +/// Memory Mapped Device Path SubType. +/// +#define HW_MEMMAP_DP 0x03 + +/// +/// Memory Mapped Device Path. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// EFI_MEMORY_TYPE + /// + UINT32 MemoryType; + /// + /// Starting Memory Address. + /// + EFI_PHYSICAL_ADDRESS StartingAddress; + /// + /// Ending Memory Address. + /// + EFI_PHYSICAL_ADDRESS EndingAddress; +} MEMMAP_DEVICE_PATH; + +/// +/// Hardware Vendor Device Path SubType. +/// +#define HW_VENDOR_DP 0x04 + +/// +/// The Vendor Device Path allows the creation of vendor-defined Device Paths. A vendor must +/// allocate a Vendor GUID for a Device Path. The Vendor GUID can then be used to define the +/// contents on the n bytes that follow in the Vendor Device Path node. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Vendor-assigned GUID that defines the data that follows. + /// + EFI_GUID Guid; + /// + /// Vendor-defined variable size data. + /// +} VENDOR_DEVICE_PATH; + +/// +/// Controller Device Path SubType. +/// +#define HW_CONTROLLER_DP 0x05 + +/// +/// Controller Device Path. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Controller number. + /// + UINT32 ControllerNumber; +} CONTROLLER_DEVICE_PATH; + +/// +/// BMC Device Path SubType. +/// +#define HW_BMC_DP 0x06 + +/// +/// BMC Device Path. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Interface Type. + /// + UINT8 InterfaceType; + /// + /// Base Address. + /// + UINT8 BaseAddress[8]; +} BMC_DEVICE_PATH; + +/// +/// ACPI Device Paths. +/// +#define ACPI_DEVICE_PATH 0x02 + +/// +/// ACPI Device Path SubType. +/// +#define ACPI_DP 0x01 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Device's PnP hardware ID stored in a numeric 32-bit + /// compressed EISA-type ID. This value must match the + /// corresponding _HID in the ACPI name space. + /// + UINT32 HID; + /// + /// Unique ID that is required by ACPI if two devices have the + /// same _HID. This value must also match the corresponding + /// _UID/_HID pair in the ACPI name space. Only the 32-bit + /// numeric value type of _UID is supported. Thus, strings must + /// not be used for the _UID in the ACPI name space. + /// + UINT32 UID; +} ACPI_HID_DEVICE_PATH; + +/// +/// Expanded ACPI Device Path SubType. +/// +#define ACPI_EXTENDED_DP 0x02 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Device's PnP hardware ID stored in a numeric 32-bit + /// compressed EISA-type ID. This value must match the + /// corresponding _HID in the ACPI name space. + /// + UINT32 HID; + /// + /// Unique ID that is required by ACPI if two devices have the + /// same _HID. This value must also match the corresponding + /// _UID/_HID pair in the ACPI name space. + /// + UINT32 UID; + /// + /// Device's compatible PnP hardware ID stored in a numeric + /// 32-bit compressed EISA-type ID. This value must match at + /// least one of the compatible device IDs returned by the + /// corresponding _CID in the ACPI name space. + /// + UINT32 CID; + /// + /// Optional variable length _HIDSTR. + /// Optional variable length _UIDSTR. + /// Optional variable length _CIDSTR. + /// +} ACPI_EXTENDED_HID_DEVICE_PATH; + +// +// EISA ID Macro +// EISA ID Definition 32-bits +// bits[15:0] - three character compressed ASCII EISA ID. +// bits[31:16] - binary number +// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' +// +#define PNP_EISA_ID_CONST 0x41d0 +#define EISA_ID(_Name, _Num) ((UINT32)((_Name) | (_Num) << 16)) +#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) +#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) + +#define PNP_EISA_ID_MASK 0xffff +#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) + +/// +/// ACPI _ADR Device Path SubType. +/// +#define ACPI_ADR_DP 0x03 + +/// +/// The _ADR device path is used to contain video output device attributes to support the Graphics +/// Output Protocol. The device path can contain multiple _ADR entries if multiple video output +/// devices are displaying the same output. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// _ADR value. For video output devices the value of this + /// field comes from Table B-2 of the ACPI 3.0 specification. At + /// least one _ADR value is required. + /// + UINT32 ADR; + // + // This device path may optionally contain more than one _ADR entry. + // +} ACPI_ADR_DEVICE_PATH; + +#define ACPI_ADR_DISPLAY_TYPE_OTHER 0 +#define ACPI_ADR_DISPLAY_TYPE_VGA 1 +#define ACPI_ADR_DISPLAY_TYPE_TV 2 +#define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL 3 +#define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL 4 + +#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \ + ((UINT32)( ((UINT32)((_DeviceIdScheme) & 0x1) << 31) | \ + (((_HeadId) & 0x7) << 18) | \ + (((_NonVgaOutput) & 0x1) << 17) | \ + (((_BiosCanDetect) & 0x1) << 16) | \ + (((_VendorInfo) & 0xf) << 12) | \ + (((_Type) & 0xf) << 8) | \ + (((_Port) & 0xf) << 4) | \ + ((_Index) & 0xf) )) + +/// +/// Messaging Device Paths. +/// This Device Path is used to describe the connection of devices outside the resource domain of the +/// system. This Device Path can describe physical messaging information like SCSI ID, or abstract +/// information like networking protocol IP addresses. +/// +#define MESSAGING_DEVICE_PATH 0x03 + +/// +/// ATAPI Device Path SubType +/// +#define MSG_ATAPI_DP 0x01 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Set to zero for primary, or one for secondary. + /// + UINT8 PrimarySecondary; + /// + /// Set to zero for master, or one for slave mode. + /// + UINT8 SlaveMaster; + /// + /// Logical Unit Number. + /// + UINT16 Lun; +} ATAPI_DEVICE_PATH; + +/// +/// SCSI Device Path SubType. +/// +#define MSG_SCSI_DP 0x02 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Target ID on the SCSI bus (PUN). + /// + UINT16 Pun; + /// + /// Logical Unit Number (LUN). + /// + UINT16 Lun; +} SCSI_DEVICE_PATH; + +/// +/// Fibre Channel SubType. +/// +#define MSG_FIBRECHANNEL_DP 0x03 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Reserved for the future. + /// + UINT32 Reserved; + /// + /// Fibre Channel World Wide Number. + /// + UINT64 WWN; + /// + /// Fibre Channel Logical Unit Number. + /// + UINT64 Lun; +} FIBRECHANNEL_DEVICE_PATH; + +/// +/// Fibre Channel Ex SubType. +/// +#define MSG_FIBRECHANNELEX_DP 0x15 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Reserved for the future. + /// + UINT32 Reserved; + /// + /// 8 byte array containing Fibre Channel End Device Port Name. + /// + UINT8 WWN[8]; + /// + /// 8 byte array containing Fibre Channel Logical Unit Number. + /// + UINT8 Lun[8]; +} FIBRECHANNELEX_DEVICE_PATH; + +/// +/// 1394 Device Path SubType +/// +#define MSG_1394_DP 0x04 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Reserved for the future. + /// + UINT32 Reserved; + /// + /// 1394 Global Unique ID (GUID). + /// + UINT64 Guid; +} F1394_DEVICE_PATH; + +/// +/// USB Device Path SubType. +/// +#define MSG_USB_DP 0x05 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// USB Parent Port Number. + /// + UINT8 ParentPortNumber; + /// + /// USB Interface Number. + /// + UINT8 InterfaceNumber; +} USB_DEVICE_PATH; + +/// +/// USB Class Device Path SubType. +/// +#define MSG_USB_CLASS_DP 0x0f +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Vendor ID assigned by USB-IF. A value of 0xFFFF will + /// match any Vendor ID. + /// + UINT16 VendorId; + /// + /// Product ID assigned by USB-IF. A value of 0xFFFF will + /// match any Product ID. + /// + UINT16 ProductId; + /// + /// The class code assigned by the USB-IF. A value of 0xFF + /// will match any class code. + /// + UINT8 DeviceClass; + /// + /// The subclass code assigned by the USB-IF. A value of + /// 0xFF will match any subclass code. + /// + UINT8 DeviceSubClass; + /// + /// The protocol code assigned by the USB-IF. A value of + /// 0xFF will match any protocol code. + /// + UINT8 DeviceProtocol; +} USB_CLASS_DEVICE_PATH; + +/// +/// USB WWID Device Path SubType. +/// +#define MSG_USB_WWID_DP 0x10 + +/// +/// This device path describes a USB device using its serial number. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// USB interface number. + /// + UINT16 InterfaceNumber; + /// + /// USB vendor id of the device. + /// + UINT16 VendorId; + /// + /// USB product id of the device. + /// + UINT16 ProductId; + /// + /// Last 64-or-fewer UTF-16 characters of the USB + /// serial number. The length of the string is + /// determined by the Length field less the offset of the + /// Serial Number field (10) + /// + /// CHAR16 SerialNumber[...]; +} USB_WWID_DEVICE_PATH; + +/// +/// Device Logical Unit SubType. +/// +#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Logical Unit Number for the interface. + /// + UINT8 Lun; +} DEVICE_LOGICAL_UNIT_DEVICE_PATH; + +/// +/// SATA Device Path SubType. +/// +#define MSG_SATA_DP 0x12 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// The HBA port number that facilitates the connection to the + /// device or a port multiplier. The value 0xFFFF is reserved. + /// + UINT16 HBAPortNumber; + /// + /// The Port multiplier port number that facilitates the connection + /// to the device. Must be set to 0xFFFF if the device is directly + /// connected to the HBA. + /// + UINT16 PortMultiplierPortNumber; + /// + /// Logical Unit Number. + /// + UINT16 Lun; +} SATA_DEVICE_PATH; + +/// +/// Flag for if the device is directly connected to the HBA. +/// +#define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000 + +/// +/// I2O Device Path SubType. +/// +#define MSG_I2O_DP 0x06 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Target ID (TID) for a device. + /// + UINT32 Tid; +} I2O_DEVICE_PATH; + +/// +/// MAC Address Device Path SubType. +/// +#define MSG_MAC_ADDR_DP 0x0b +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// The MAC address for a network interface padded with 0s. + /// + EFI_MAC_ADDRESS MacAddress; + /// + /// Network interface type(i.e. 802.3, FDDI). + /// + UINT8 IfType; +} MAC_ADDR_DEVICE_PATH; + +/// +/// IPv4 Device Path SubType +/// +#define MSG_IPv4_DP 0x0c +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// The local IPv4 address. + /// + EFI_IPv4_ADDRESS LocalIpAddress; + /// + /// The remote IPv4 address. + /// + EFI_IPv4_ADDRESS RemoteIpAddress; + /// + /// The local port number. + /// + UINT16 LocalPort; + /// + /// The remote port number. + /// + UINT16 RemotePort; + /// + /// The network protocol(i.e. UDP, TCP). + /// + UINT16 Protocol; + /// + /// 0x00 - The Source IP Address was assigned though DHCP. + /// 0x01 - The Source IP Address is statically bound. + /// + BOOLEAN StaticIpAddress; + /// + /// The gateway IP address + /// + EFI_IPv4_ADDRESS GatewayIpAddress; + /// + /// The subnet mask + /// + EFI_IPv4_ADDRESS SubnetMask; +} IPv4_DEVICE_PATH; + +/// +/// IPv6 Device Path SubType. +/// +#define MSG_IPv6_DP 0x0d +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// The local IPv6 address. + /// + EFI_IPv6_ADDRESS LocalIpAddress; + /// + /// The remote IPv6 address. + /// + EFI_IPv6_ADDRESS RemoteIpAddress; + /// + /// The local port number. + /// + UINT16 LocalPort; + /// + /// The remote port number. + /// + UINT16 RemotePort; + /// + /// The network protocol(i.e. UDP, TCP). + /// + UINT16 Protocol; + /// + /// 0x00 - The Local IP Address was manually configured. + /// 0x01 - The Local IP Address is assigned through IPv6 + /// stateless auto-configuration. + /// 0x02 - The Local IP Address is assigned through IPv6 + /// stateful configuration. + /// + UINT8 IpAddressOrigin; + /// + /// The prefix length + /// + UINT8 PrefixLength; + /// + /// The gateway IP address + /// + EFI_IPv6_ADDRESS GatewayIpAddress; +} IPv6_DEVICE_PATH; + +/// +/// InfiniBand Device Path SubType. +/// +#define MSG_INFINIBAND_DP 0x09 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Flags to help identify/manage InfiniBand device path elements: + /// Bit 0 - IOC/Service (0b = IOC, 1b = Service). + /// Bit 1 - Extend Boot Environment. + /// Bit 2 - Console Protocol. + /// Bit 3 - Storage Protocol. + /// Bit 4 - Network Protocol. + /// All other bits are reserved. + /// + UINT32 ResourceFlags; + /// + /// 128-bit Global Identifier for remote fabric port. + /// + UINT8 PortGid[16]; + /// + /// 64-bit unique identifier to remote IOC or server process. + /// Interpretation of field specified by Resource Flags (bit 0). + /// + UINT64 ServiceId; + /// + /// 64-bit persistent ID of remote IOC port. + /// + UINT64 TargetPortId; + /// + /// 64-bit persistent ID of remote device. + /// + UINT64 DeviceId; +} INFINIBAND_DEVICE_PATH; + +#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01 +#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02 +#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04 +#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08 +#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10 + +/// +/// UART Device Path SubType. +/// +#define MSG_UART_DP 0x0e +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Reserved. + /// + UINT32 Reserved; + /// + /// The baud rate setting for the UART style device. A value of 0 + /// means that the device's default baud rate will be used. + /// + UINT64 BaudRate; + /// + /// The number of data bits for the UART style device. A value + /// of 0 means that the device's default number of data bits will be used. + /// + UINT8 DataBits; + /// + /// The parity setting for the UART style device. + /// Parity 0x00 - Default Parity. + /// Parity 0x01 - No Parity. + /// Parity 0x02 - Even Parity. + /// Parity 0x03 - Odd Parity. + /// Parity 0x04 - Mark Parity. + /// Parity 0x05 - Space Parity. + /// + UINT8 Parity; + /// + /// The number of stop bits for the UART style device. + /// Stop Bits 0x00 - Default Stop Bits. + /// Stop Bits 0x01 - 1 Stop Bit. + /// Stop Bits 0x02 - 1.5 Stop Bits. + /// Stop Bits 0x03 - 2 Stop Bits. + /// + UINT8 StopBits; +} UART_DEVICE_PATH; + +// +// Use VENDOR_DEVICE_PATH struct +// +#define MSG_VENDOR_DP 0x0a +typedef VENDOR_DEVICE_PATH VENDOR_DEFINED_DEVICE_PATH; + +#define DEVICE_PATH_MESSAGING_PC_ANSI EFI_PC_ANSI_GUID +#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID +#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID +#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID + +/// +/// A new device path node is defined to declare flow control characteristics. +/// UART Flow Control Messaging Device Path +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL GUID. + /// + EFI_GUID Guid; + /// + /// Bitmap of supported flow control types. + /// Bit 0 set indicates hardware flow control. + /// Bit 1 set indicates Xon/Xoff flow control. + /// All other bits are reserved and are clear. + /// + UINT32 FlowControlMap; +} UART_FLOW_CONTROL_DEVICE_PATH; + +#define UART_FLOW_CONTROL_HARDWARE 0x00000001 +#define UART_FLOW_CONTROL_XON_XOFF 0x00000010 + +#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID +/// +/// Serial Attached SCSI (SAS) Device Path. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// DEVICE_PATH_MESSAGING_SAS GUID. + /// + EFI_GUID Guid; + /// + /// Reserved for future use. + /// + UINT32 Reserved; + /// + /// SAS Address for Serial Attached SCSI Target. + /// + UINT64 SasAddress; + /// + /// SAS Logical Unit Number. + /// + UINT64 Lun; + /// + /// More Information about the device and its interconnect. + /// + UINT16 DeviceTopology; + /// + /// Relative Target Port (RTP). + /// + UINT16 RelativeTargetPort; +} SAS_DEVICE_PATH; + +/// +/// Serial Attached SCSI (SAS) Ex Device Path SubType +/// +#define MSG_SASEX_DP 0x16 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// 8-byte array of the SAS Address for Serial Attached SCSI Target Port. + /// + UINT8 SasAddress[8]; + /// + /// 8-byte array of the SAS Logical Unit Number. + /// + UINT8 Lun[8]; + /// + /// More Information about the device and its interconnect. + /// + UINT16 DeviceTopology; + /// + /// Relative Target Port (RTP). + /// + UINT16 RelativeTargetPort; +} SASEX_DEVICE_PATH; + +/// +/// NvmExpress Namespace Device Path SubType. +/// +#define MSG_NVME_NAMESPACE_DP 0x17 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 NamespaceId; + UINT64 NamespaceUuid; +} NVME_NAMESPACE_DEVICE_PATH; + +/// +/// DNS Device Path SubType +/// +#define MSG_DNS_DP 0x1F +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Indicates the DNS server address is IPv4 or IPv6 address. + /// + UINT8 IsIPv6; + /// + /// Instance of the DNS server address. + /// + EFI_IP_ADDRESS DnsServerIp[1024]; +} DNS_DEVICE_PATH; + +/// +/// Uniform Resource Identifiers (URI) Device Path SubType +/// +#define MSG_URI_DP 0x18 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Instance of the URI pursuant to RFC 3986. + /// + CHAR8 Uri[1024]; +} URI_DEVICE_PATH; + +/// +/// Universal Flash Storage (UFS) Device Path SubType. +/// +#define MSG_UFS_DP 0x19 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Target ID on the UFS bus (PUN). + /// + UINT8 Pun; + /// + /// Logical Unit Number (LUN). + /// + UINT8 Lun; +} UFS_DEVICE_PATH; + +/// +/// SD (Secure Digital) Device Path SubType. +/// +#define MSG_SD_DP 0x1A +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT8 SlotNumber; +} SD_DEVICE_PATH; + +/// +/// EMMC (Embedded MMC) Device Path SubType. +/// +#define MSG_EMMC_DP 0x1D +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT8 SlotNumber; +} EMMC_DEVICE_PATH; + +/// +/// iSCSI Device Path SubType +/// +#define MSG_ISCSI_DP 0x13 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Network Protocol (0 = TCP, 1+ = reserved). + /// + UINT16 NetworkProtocol; + /// + /// iSCSI Login Options. + /// + UINT16 LoginOption; + /// + /// iSCSI Logical Unit Number. + /// + UINT64 Lun; + /// + /// iSCSI Target Portal group tag the initiator intends + /// to establish a session with. + /// + UINT16 TargetPortalGroupTag; + /// + /// iSCSI NodeTarget Name. The length of the name + /// is determined by subtracting the offset of this field from Length. + /// + /// CHAR8 iSCSI Target Name. +} ISCSI_DEVICE_PATH; + +#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST 0x0000 +#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C 0x0002 +#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST 0x0000 +#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C 0x0008 +#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP 0x0000 +#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON 0x1000 +#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000 +#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000 + +/// +/// VLAN Device Path SubType. +/// +#define MSG_VLAN_DP 0x14 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// VLAN identifier (0-4094). + /// + UINT16 VlanId; +} VLAN_DEVICE_PATH; + +/// +/// Bluetooth Device Path SubType. +/// +#define MSG_BLUETOOTH_DP 0x1b +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// 48bit Bluetooth device address. + /// + BLUETOOTH_ADDRESS BD_ADDR; +} BLUETOOTH_DEVICE_PATH; + +/// +/// Wi-Fi Device Path SubType. +/// +#define MSG_WIFI_DP 0x1C +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Service set identifier. A 32-byte octets string. + /// + UINT8 SSId[32]; +} WIFI_DEVICE_PATH; + +/// +/// Bluetooth LE Device Path SubType. +/// +#define MSG_BLUETOOTH_LE_DP 0x1E +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + BLUETOOTH_LE_ADDRESS Address; +} BLUETOOTH_LE_DEVICE_PATH; + +// +// Media Device Path +// +#define MEDIA_DEVICE_PATH 0x04 + +/// +/// Hard Drive Media Device Path SubType. +/// +#define MEDIA_HARDDRIVE_DP 0x01 + +/// +/// The Hard Drive Media Device Path is used to represent a partition on a hard drive. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Describes the entry in a partition table, starting with entry 1. + /// Partition number zero represents the entire device. Valid + /// partition numbers for a MBR partition are [1, 4]. Valid + /// partition numbers for a GPT partition are [1, NumberOfPartitionEntries]. + /// + UINT32 PartitionNumber; + /// + /// Starting LBA of the partition on the hard drive. + /// + UINT64 PartitionStart; + /// + /// Size of the partition in units of Logical Blocks. + /// + UINT64 PartitionSize; + /// + /// Signature unique to this partition: + /// If SignatureType is 0, this field has to be initialized with 16 zeros. + /// If SignatureType is 1, the MBR signature is stored in the first 4 bytes of this field. + /// The other 12 bytes are initialized with zeros. + /// If SignatureType is 2, this field contains a 16 byte signature. + /// + UINT8 Signature[16]; + /// + /// Partition Format: (Unused values reserved). + /// 0x01 - PC-AT compatible legacy MBR. + /// 0x02 - GUID Partition Table. + /// + UINT8 MBRType; + /// + /// Type of Disk Signature: (Unused values reserved). + /// 0x00 - No Disk Signature. + /// 0x01 - 32-bit signature from address 0x1b8 of the type 0x01 MBR. + /// 0x02 - GUID signature. + /// + UINT8 SignatureType; +} HARDDRIVE_DEVICE_PATH; + +#define MBR_TYPE_PCAT 0x01 +#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 + +#define NO_DISK_SIGNATURE 0x00 +#define SIGNATURE_TYPE_MBR 0x01 +#define SIGNATURE_TYPE_GUID 0x02 + +/// +/// CD-ROM Media Device Path SubType. +/// +#define MEDIA_CDROM_DP 0x02 + +/// +/// The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Boot Entry number from the Boot Catalog. The Initial/Default entry is defined as zero. + /// + UINT32 BootEntry; + /// + /// Starting RBA of the partition on the medium. CD-ROMs use Relative logical Block Addressing. + /// + UINT64 PartitionStart; + /// + /// Size of the partition in units of Blocks, also called Sectors. + /// + UINT64 PartitionSize; +} CDROM_DEVICE_PATH; + +// +// Use VENDOR_DEVICE_PATH struct +// +#define MEDIA_VENDOR_DP 0x03 ///< Media vendor device path subtype. + +/// +/// File Path Media Device Path SubType +/// +#define MEDIA_FILEPATH_DP 0x04 +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// A NULL-terminated Path string including directory and file names. + /// + CHAR16 PathName[1]; +} FILEPATH_DEVICE_PATH; + +#define SIZE_OF_FILEPATH_DEVICE_PATH OFFSET_OF(FILEPATH_DEVICE_PATH,PathName) + +/// +/// Media Protocol Device Path SubType. +/// +#define MEDIA_PROTOCOL_DP 0x05 + +/// +/// The Media Protocol Device Path is used to denote the protocol that is being +/// used in a device path at the location of the path specified. +/// Many protocols are inherent to the style of device path. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// The ID of the protocol. + /// + EFI_GUID Protocol; +} MEDIA_PROTOCOL_DEVICE_PATH; + +/// +/// PIWG Firmware File SubType. +/// +#define MEDIA_PIWG_FW_FILE_DP 0x06 + +/// +/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware file. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Firmware file name + /// + EFI_GUID FvFileName; +} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH; + +/// +/// PIWG Firmware Volume Device Path SubType. +/// +#define MEDIA_PIWG_FW_VOL_DP 0x07 + +/// +/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware volume. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Firmware volume name. + /// + EFI_GUID FvName; +} MEDIA_FW_VOL_DEVICE_PATH; + +/// +/// Media relative offset range device path. +/// +#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08 + +/// +/// Used to describe the offset range of media relative. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 Reserved; + UINT64 StartingOffset; + UINT64 EndingOffset; +} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH; + +/// +/// This GUID defines a RAM Disk supporting a raw disk format in volatile memory. +/// +#define EFI_VIRTUAL_DISK_GUID \ + { \ + 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E } \ + } + +extern EFI_GUID gEfiVirtualDiskGuid; + +/// +/// This GUID defines a RAM Disk supporting an ISO image in volatile memory. +/// +#define EFI_VIRTUAL_CD_GUID \ + { \ + 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB } \ + } +extern EFI_GUID gEfiVirtualCdGuid; + +/// +/// This GUID defines a RAM Disk supporting a raw disk format in persistent memory. +/// +#define EFI_PERSISTENT_VIRTUAL_DISK_GUID \ + { \ + 0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 } \ + } + +extern EFI_GUID gEfiPersistentVirtualDiskGuid; + +/// +/// This GUID defines a RAM Disk supporting an ISO image in persistent memory. +/// +#define EFI_PERSISTENT_VIRTUAL_CD_GUID \ + { \ + 0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D } \ + } + +extern EFI_GUID gEfiPersistentVirtualCdGuid; + +/// +/// Media ram disk device path. +/// +#define MEDIA_RAM_DISK_DP 0x09 + +/// +/// Used to describe the ram disk device path. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Starting Memory Address. + /// + UINT32 StartingAddr[2]; + /// + /// Ending Memory Address. + /// + UINT32 EndingAddr[2]; + /// + /// GUID that defines the type of the RAM Disk. + /// + EFI_GUID TypeGuid; + /// + /// RAM Diskinstance number, if supported. The default value is zero. + /// + UINT16 Instance; +} MEDIA_RAM_DISK_DEVICE_PATH; + +/// +/// BIOS Boot Specification Device Path. +/// +#define BBS_DEVICE_PATH 0x05 + +/// +/// BIOS Boot Specification Device Path SubType. +/// +#define BBS_BBS_DP 0x01 + +/// +/// This Device Path is used to describe the booting of non-EFI-aware operating systems. +/// +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + /// + /// Device Type as defined by the BIOS Boot Specification. + /// + UINT16 DeviceType; + /// + /// Status Flags as defined by the BIOS Boot Specification. + /// + UINT16 StatusFlag; + /// + /// Null-terminated ASCII string that describes the boot device to a user. + /// + CHAR8 String[1]; +} BBS_BBS_DEVICE_PATH; + +// +// DeviceType definitions - from BBS specification +// +#define BBS_TYPE_FLOPPY 0x01 +#define BBS_TYPE_HARDDRIVE 0x02 +#define BBS_TYPE_CDROM 0x03 +#define BBS_TYPE_PCMCIA 0x04 +#define BBS_TYPE_USB 0x05 +#define BBS_TYPE_EMBEDDED_NETWORK 0x06 +#define BBS_TYPE_BEV 0x80 +#define BBS_TYPE_UNKNOWN 0xFF + + +/// +/// Union of all possible Device Paths and pointers to Device Paths. +/// +typedef union { + EFI_DEVICE_PATH_PROTOCOL DevPath; + PCI_DEVICE_PATH Pci; + PCCARD_DEVICE_PATH PcCard; + MEMMAP_DEVICE_PATH MemMap; + VENDOR_DEVICE_PATH Vendor; + + CONTROLLER_DEVICE_PATH Controller; + BMC_DEVICE_PATH Bmc; + ACPI_HID_DEVICE_PATH Acpi; + ACPI_EXTENDED_HID_DEVICE_PATH ExtendedAcpi; + ACPI_ADR_DEVICE_PATH AcpiAdr; + + ATAPI_DEVICE_PATH Atapi; + SCSI_DEVICE_PATH Scsi; + ISCSI_DEVICE_PATH Iscsi; + FIBRECHANNEL_DEVICE_PATH FibreChannel; + FIBRECHANNELEX_DEVICE_PATH FibreChannelEx; + + F1394_DEVICE_PATH F1394; + USB_DEVICE_PATH Usb; + SATA_DEVICE_PATH Sata; + USB_CLASS_DEVICE_PATH UsbClass; + USB_WWID_DEVICE_PATH UsbWwid; + DEVICE_LOGICAL_UNIT_DEVICE_PATH LogicUnit; + I2O_DEVICE_PATH I2O; + MAC_ADDR_DEVICE_PATH MacAddr; + IPv4_DEVICE_PATH Ipv4; + IPv6_DEVICE_PATH Ipv6; + VLAN_DEVICE_PATH Vlan; + INFINIBAND_DEVICE_PATH InfiniBand; + UART_DEVICE_PATH Uart; + UART_FLOW_CONTROL_DEVICE_PATH UartFlowControl; + SAS_DEVICE_PATH Sas; + SASEX_DEVICE_PATH SasEx; + NVME_NAMESPACE_DEVICE_PATH NvmeNamespace; + DNS_DEVICE_PATH Dns; + URI_DEVICE_PATH Uri; + BLUETOOTH_DEVICE_PATH Bluetooth; + WIFI_DEVICE_PATH WiFi; + UFS_DEVICE_PATH Ufs; + SD_DEVICE_PATH Sd; + EMMC_DEVICE_PATH Emmc; + HARDDRIVE_DEVICE_PATH HardDrive; + CDROM_DEVICE_PATH CD; + + FILEPATH_DEVICE_PATH FilePath; + MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; + + MEDIA_FW_VOL_DEVICE_PATH FirmwareVolume; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FirmwareFile; + MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH Offset; + MEDIA_RAM_DISK_DEVICE_PATH RamDisk; + BBS_BBS_DEVICE_PATH Bbs; +} EFI_DEV_PATH; + + + +typedef union { + EFI_DEVICE_PATH_PROTOCOL *DevPath; + PCI_DEVICE_PATH *Pci; + PCCARD_DEVICE_PATH *PcCard; + MEMMAP_DEVICE_PATH *MemMap; + VENDOR_DEVICE_PATH *Vendor; + + CONTROLLER_DEVICE_PATH *Controller; + BMC_DEVICE_PATH *Bmc; + ACPI_HID_DEVICE_PATH *Acpi; + ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi; + ACPI_ADR_DEVICE_PATH *AcpiAdr; + + ATAPI_DEVICE_PATH *Atapi; + SCSI_DEVICE_PATH *Scsi; + ISCSI_DEVICE_PATH *Iscsi; + FIBRECHANNEL_DEVICE_PATH *FibreChannel; + FIBRECHANNELEX_DEVICE_PATH *FibreChannelEx; + + F1394_DEVICE_PATH *F1394; + USB_DEVICE_PATH *Usb; + SATA_DEVICE_PATH *Sata; + USB_CLASS_DEVICE_PATH *UsbClass; + USB_WWID_DEVICE_PATH *UsbWwid; + DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicUnit; + I2O_DEVICE_PATH *I2O; + MAC_ADDR_DEVICE_PATH *MacAddr; + IPv4_DEVICE_PATH *Ipv4; + IPv6_DEVICE_PATH *Ipv6; + VLAN_DEVICE_PATH *Vlan; + INFINIBAND_DEVICE_PATH *InfiniBand; + UART_DEVICE_PATH *Uart; + UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl; + SAS_DEVICE_PATH *Sas; + SASEX_DEVICE_PATH *SasEx; + NVME_NAMESPACE_DEVICE_PATH *NvmeNamespace; + DNS_DEVICE_PATH *Dns; + URI_DEVICE_PATH *Uri; + BLUETOOTH_DEVICE_PATH *Bluetooth; + WIFI_DEVICE_PATH *WiFi; + UFS_DEVICE_PATH *Ufs; + SD_DEVICE_PATH *Sd; + EMMC_DEVICE_PATH *Emmc; + HARDDRIVE_DEVICE_PATH *HardDrive; + CDROM_DEVICE_PATH *CD; + + FILEPATH_DEVICE_PATH *FilePath; + MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; + + MEDIA_FW_VOL_DEVICE_PATH *FirmwareVolume; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FirmwareFile; + MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset; + MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; + BBS_BBS_DEVICE_PATH *Bbs; + UINT8 *Raw; +} EFI_DEV_PATH_PTR; + +#define EFI_DEBUGPORT_PROTOCOL_GUID \ + { \ + 0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ + } +// +// DEBUGPORT variable definitions... +// +#define EFI_DEBUGPORT_VARIABLE_NAME L"DEBUGPORT" +#define EFI_DEBUGPORT_VARIABLE_GUID EFI_DEBUGPORT_PROTOCOL_GUID +extern EFI_GUID gEfiDebugPortVariableGuid; + +// +// DebugPort device path definitions... +// +#define DEVICE_PATH_MESSAGING_DEBUGPORT EFI_DEBUGPORT_PROTOCOL_GUID +extern EFI_GUID gEfiDebugPortDevicePathGuid; + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_GUID Guid; +} DEBUGPORT_DEVICE_PATH; + +#pragma pack() + +#define END_DEVICE_PATH_TYPE 0x7f +#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF +#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 + +extern EFI_GUID gEfiDevicePathProtocolGuid; + +#endif diff --git a/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h b/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h new file mode 100644 index 0000000000..d046c86453 --- /dev/null +++ b/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h @@ -0,0 +1,294 @@ +/** @file + EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0. + Use to create and manipulate device paths and device nodes. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __DEVICE_PATH_UTILITIES_H__ +#define __DEVICE_PATH_UTILITIES_H__ + +/// +/// Device Path Utilities protocol +/// +#define EFI_DEVICE_PATH_UTILITIES_GUID \ + { \ + 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \ + } + +/** + Returns the size of the device path, in bytes. + + @param DevicePath Points to the start of the EFI device path. + + @return Size Size of the specified device path, in bytes, including the end-of-path tag. + @retval 0 DevicePath is NULL + +**/ +typedef +UINTN +( *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + + +/** + Create a duplicate of the specified path. + + @param DevicePath Points to the source EFI device path. + + @retval Pointer A pointer to the duplicate device path. + @retval NULL insufficient memory or DevicePath is NULL + +**/ +typedef +EFI_DEVICE_PATH_PROTOCOL* +( *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +/** + Create a new path by appending the second device path to the first. + If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned. + If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned. + If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is returned. + + @param Src1 Points to the first device path. + @param Src2 Points to the second device path. + + @retval Pointer A pointer to the newly created device path. + @retval NULL Memory could not be allocated + +**/ +typedef +EFI_DEVICE_PATH_PROTOCOL* +( *EFI_DEVICE_PATH_UTILS_APPEND_PATH)( + CONST EFI_DEVICE_PATH_PROTOCOL *Src1, + CONST EFI_DEVICE_PATH_PROTOCOL *Src2 + ); + +/** + Creates a new path by appending the device node to the device path. + If DeviceNode is NULL then a copy of DevicePath is returned. + If DevicePath is NULL then a copy of DeviceNode, followed by an end-of-device path device node is returned. + If both DeviceNode and DevicePath are NULL then a copy of an end-of-device-path device node is returned. + + @param DevicePath Points to the device path. + @param DeviceNode Points to the device node. + + @retval Pointer A pointer to the allocated device node. + @retval NULL There was insufficient memory. + +**/ +typedef +EFI_DEVICE_PATH_PROTOCOL* +( *EFI_DEVICE_PATH_UTILS_APPEND_NODE)( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode + ); + +/** + Creates a new path by appending the specified device path instance to the specified device path. + + @param DevicePath Points to the device path. If NULL, then ignored. + @param DevicePathInstance Points to the device path instance. + + @retval Pointer A pointer to the newly created device path + @retval NULL Memory could not be allocated or DevicePathInstance is NULL. + +**/ +typedef +EFI_DEVICE_PATH_PROTOCOL* +( *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance + ); + +/** + Creates a copy of the current device path instance and returns a pointer to the next device path + instance. + + @param DevicePathInstance On input, this holds the pointer to the current device path + instance. On output, this holds the pointer to the next + device path instance or NULL if there are no more device + path instances in the device path. + @param DevicePathInstanceSize On output, this holds the size of the device path instance, + in bytes or zero, if DevicePathInstance is NULL. + If NULL, then the instance size is not output. + + @retval Pointer A pointer to the copy of the current device path instance. + @retval NULL DevicePathInstace was NULL on entry or there was insufficient memory. + +**/ +typedef +EFI_DEVICE_PATH_PROTOCOL* +( *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)( + EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance, + UINTN *DevicePathInstanceSize + ); + +/** + Creates a device node + + @param NodeType NodeType is the device node type (EFI_DEVICE_PATH.Type) for + the new device node. + @param NodeSubType NodeSubType is the device node sub-type + EFI_DEVICE_PATH.SubType) for the new device node. + @param NodeLength NodeLength is the length of the device node + (EFI_DEVICE_PATH.Length) for the new device node. + + @retval Pointer A pointer to the newly created device node. + @retval NULL NodeLength is less than + the size of the header or there was insufficient memory. + +**/ +typedef +EFI_DEVICE_PATH_PROTOCOL* +( *EFI_DEVICE_PATH_UTILS_CREATE_NODE)( + UINT8 NodeType, + UINT8 NodeSubType, + UINT16 NodeLength +); + +/** + Returns whether a device path is multi-instance. + + @param DevicePath Points to the device path. If NULL, then ignored. + + @retval TRUE The device path has more than one instance + @retval FALSE The device path is empty or contains only a single instance. + +**/ +typedef +BOOLEAN +( *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +/// +/// This protocol is used to creates and manipulates device paths and device nodes. +/// +typedef struct { + EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize; + EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath; + EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath; + EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode; + EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance; + EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance; + EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance; + EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode; +} EFI_DEVICE_PATH_UTILITIES_PROTOCOL; + +extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid; + +VOID +SetDevicePathEndNode ( + VOID *Node + ); + +BOOLEAN +IsDevicePathValid ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + UINTN MaxSize + ); + +UINT8 +DevicePathType ( + CONST VOID *Node + ); + +UINT8 +DevicePathSubType ( + CONST VOID *Node + ); + +UINTN +DevicePathNodeLength ( + CONST VOID *Node + ); + +EFI_DEVICE_PATH_PROTOCOL * +NextDevicePathNode ( + CONST VOID *Node + ); + +BOOLEAN +IsDevicePathEndType ( + CONST VOID *Node + ); + +BOOLEAN +IsDevicePathEnd ( + CONST VOID *Node + ); +BOOLEAN +IsDevicePathEndInstance ( + CONST VOID *Node + ); + +UINT16 +SetDevicePathNodeLength ( + VOID *Node, + UINTN Length + ); + +VOID +SetDevicePathEndNode ( + VOID *Node + ); + +UINTN +UefiDevicePathLibGetDevicePathSize ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibDuplicateDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePathNode ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePathInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibGetNextDevicePathInstance ( + EFI_DEVICE_PATH_PROTOCOL **DevicePath, + UINTN *Size + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibCreateDeviceNode ( + UINT8 NodeType, + UINT8 NodeSubType, + UINT16 NodeLength + ); + +BOOLEAN +UefiDevicePathLibIsDevicePathMultiInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +#endif diff --git a/BaseTools/Source/C/Makefile b/BaseTools/Source/C/Makefile index 50be773d57..542818044d 100644 --- a/BaseTools/Source/C/Makefile +++ b/BaseTools/Source/C/Makefile @@ -1,7 +1,7 @@ ## @file # Windows makefile for C tools build. # -# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2009 - 2017, 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 @@ -32,7 +32,8 @@ APPLICATIONS = \ Split \ TianoCompress \ VolInfo \ - VfrCompile + VfrCompile \ + DevicePath all: libs apps install diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py index 59d1ba2639..15ad9e4f2e 100644 --- a/BaseTools/Source/Python/Common/Misc.py +++ b/BaseTools/Source/Python/Common/Misc.py @@ -38,7 +38,7 @@ from Common.LongFilePathSupport import OpenLongFilePath as open from Common.MultipleWorkspace import MultipleWorkspace as mws import uuid from CommonDataClass.Exceptions import BadExpression - +import subprocess ## Regular expression used to find out place holders in string template gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE) @@ -1474,7 +1474,37 @@ def AnalyzePcdExpression(Setting): return FieldList def ParseDevPathValue (Value): - pass + DevPathList = [ "Path","HardwarePath","Pci","PcCard","MemoryMapped","VenHw","Ctrl","BMC","AcpiPath","Acpi","PciRoot", + "PcieRoot","Floppy","Keyboard","Serial","ParallelPort","AcpiEx","AcpiExp","AcpiAdr","Msg","Ata","Scsi", + "Fibre","FibreEx","I1394","USB","I2O","Infiniband","VenMsg","VenPcAnsi","VenVt100","VenVt100Plus", + "VenUtf8","UartFlowCtrl","SAS","SasEx","NVMe","UFS","SD","eMMC","DebugPort","MAC","IPv4","IPv6","Uart", + "UsbClass","UsbAudio","UsbCDCControl","UsbHID","UsbImage","UsbPrinter","UsbMassStorage","UsbHub", + "UsbCDCData","UsbSmartCard","UsbVideo","UsbDiagnostic","UsbWireless","UsbDeviceFirmwareUpdate", + "UsbIrdaBridge","UsbTestAndMeasurement","UsbWwid","Unit","iSCSI","Vlan","Uri","Bluetooth","Wi-Fi", + "MediaPath","HD","CDROM","VenMedia","Media","Fv","FvFile","Offset","RamDisk","VirtualDisk","VirtualCD", + "PersistentVirtualDisk","PersistentVirtualCD","BbsPath","BBS","Sata" ] + if '\\' in Value: + Value.replace('\\', '/').replace(' ', '') + for Item in Value.split('/'): + Key = Item.strip().split('(')[0] + if Key not in DevPathList: + pass + + Cmd = 'DevicePath ' + '"' + Value + '"' + try: + p = subprocess.Popen(Cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + out, err = p.communicate() + except Exception, X: + raise BadExpression("DevicePath: %s" % (str(X)) ) + finally: + subprocess._cleanup() + p.stdout.close() + p.stderr.close() + if err: + raise BadExpression("DevicePath: %s" % str(err)) + Size = len(out.split()) + out = ','.join(out.split()) + return '{' + out + '}', Size def ParseFieldValue (Value): if type(Value) == type(0): -- 2.39.2