* [Patch 0/2] BaseTools: Add Flexible PCD Value support
@ 2017-12-26 16:40 Yonghong Zhu
2017-12-26 16:40 ` [Patch 1/2] BaseTools: Support PCD flexible values format Yonghong Zhu
2017-12-26 16:40 ` [Patch 2/2] BaseTools: Add DevicePath support for PCD values Yonghong Zhu
0 siblings, 2 replies; 4+ messages in thread
From: Yonghong Zhu @ 2017-12-26 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Yunhua Feng
https://bugzilla.tianocore.org/show_bug.cgi?id=541
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Yonghong Zhu (2):
BaseTools: Support PCD flexible values format
BaseTools: Add DevicePath support for PCD values
BaseTools/Source/BinaryFiles.txt | 3 +-
BaseTools/Source/C/DevicePath/DevicePath.c | 188 ++
BaseTools/Source/C/DevicePath/DevicePath.h | 1380 ++++++++
BaseTools/Source/C/DevicePath/DevicePathFromText.c | 3503 ++++++++++++++++++++
BaseTools/Source/C/DevicePath/DevicePathFromText.h | 72 +
.../Source/C/DevicePath/DevicePathUtilities.c | 2352 +++++++++++++
.../Source/C/DevicePath/DevicePathUtilities.h | 555 ++++
BaseTools/Source/C/DevicePath/GNUmakefile | 30 +
BaseTools/Source/C/DevicePath/Makefile | 24 +
BaseTools/Source/C/DevicePath/UefiDevicePathLib.c | 298 ++
BaseTools/Source/C/DevicePath/UefiDevicePathLib.h | 473 +++
BaseTools/Source/C/GNUmakefile | 3 +-
BaseTools/Source/C/Makefile | 5 +-
BaseTools/Source/Python/AutoGen/AutoGen.py | 39 +
BaseTools/Source/Python/AutoGen/GenC.py | 2 +
BaseTools/Source/Python/Common/Expression.py | 241 +-
BaseTools/Source/Python/Common/Misc.py | 236 +-
BaseTools/Source/Python/Workspace/DscBuildData.py | 14 +-
BaseTools/Source/Python/Workspace/InfBuildData.py | 7 +
.../Source/Python/Workspace/MetaFileParser.py | 17 +-
.../Source/Python/Workspace/WorkspaceCommon.py | 6 +-
BaseTools/Source/Python/build/BuildReport.py | 6 +
22 files changed, 9338 insertions(+), 116 deletions(-)
create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.h
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.h
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.h
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
--
2.6.1.windows.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Patch 1/2] BaseTools: Support PCD flexible values format
2017-12-26 16:40 [Patch 0/2] BaseTools: Add Flexible PCD Value support Yonghong Zhu
@ 2017-12-26 16:40 ` Yonghong Zhu
2017-12-26 16:40 ` [Patch 2/2] BaseTools: Add DevicePath support for PCD values Yonghong Zhu
1 sibling, 0 replies; 4+ messages in thread
From: Yonghong Zhu @ 2017-12-26 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Yunhua Feng
https://bugzilla.tianocore.org/show_bug.cgi?id=541
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/Python/AutoGen/AutoGen.py | 39 ++++
BaseTools/Source/Python/AutoGen/GenC.py | 2 +
BaseTools/Source/Python/Common/Expression.py | 246 ++++++++++++++++++++-
BaseTools/Source/Python/Common/Misc.py | 203 +++++++++--------
BaseTools/Source/Python/Workspace/DscBuildData.py | 14 +-
BaseTools/Source/Python/Workspace/InfBuildData.py | 7 +
.../Source/Python/Workspace/MetaFileParser.py | 17 +-
.../Source/Python/Workspace/WorkspaceCommon.py | 8 +-
BaseTools/Source/Python/build/BuildReport.py | 6 +
9 files changed, 429 insertions(+), 113 deletions(-)
diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index cacd009..8be5bfc 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -269,10 +269,11 @@ class WorkspaceAutoGen(AutoGen):
self.AutoGenObjectList = []
self._BuildDir = None
self._FvDir = None
self._MakeFileDir = None
self._BuildCommand = None
+ self._GuidDict = {}
# there's many relative directory operations, so ...
os.chdir(self.WorkspaceDir)
#
@@ -417,24 +418,42 @@ class WorkspaceAutoGen(AutoGen):
TokenSpaceGuidCNameList = []
FoundFlag = False
PcdDatumType = ''
NewValue = ''
for package in PGen.PackageList:
+ Guids = package.Guids
+ self._GuidDict.update(Guids)
+ for package in PGen.PackageList:
for key in package.Pcds:
PcdItem = package.Pcds[key]
if HasTokenSpace:
if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
PcdDatumType = PcdItem.DatumType
+ if pcdvalue.startswith('H'):
+ try:
+ pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
+ except BadExpression, Value:
+ if Value.result > 1:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
+ (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
+ pcdvalue = 'H' + pcdvalue
NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
FoundFlag = True
else:
if PcdItem.TokenCName == TokenCName:
if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
if len (TokenSpaceGuidCNameList) < 1:
TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
PcdDatumType = PcdItem.DatumType
TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
+ if pcdvalue.startswith('H'):
+ try:
+ pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
+ except BadExpression, Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
+ (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
+ pcdvalue = 'H' + pcdvalue
NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
FoundFlag = True
else:
EdkLogger.error(
'build',
@@ -2444,10 +2463,30 @@ class PlatformAutoGen(AutoGen):
ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
if FromPcd.DatumType not in [None, '']:
ToPcd.DatumType = FromPcd.DatumType
if FromPcd.SkuInfoList not in [None, '', []]:
ToPcd.SkuInfoList = FromPcd.SkuInfoList
+ # Add Flexible PCD format parse
+ PcdValue = ToPcd.DefaultValue
+ if PcdValue:
+ try:
+ ToPcd.DefaultValue = ValueExpression(PcdValue)(True)
+ except WrnExpression, Value:
+ ToPcd.DefaultValue = Value.result
+ except BadExpression, Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, ToPcd.DefaultValue, Value),
+ File=self.MetaFile)
+ if ToPcd.DefaultValue:
+ _GuidDict = {}
+ for Pkg in self.PackageList:
+ Guids = Pkg.Guids
+ _GuidDict.update(Guids)
+ try:
+ ToPcd.DefaultValue = ValueExpressionEx(ToPcd.DefaultValue, ToPcd.DatumType, _GuidDict)(True)
+ except BadExpression, Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, ToPcd.DefaultValue, Value),
+ File=self.MetaFile)
# check the validation of datum
IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
if not IsValid:
EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index 6b95cd4..3e98506 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -1031,10 +1031,12 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
elif BoolValue == 'FALSE' or BoolValue == '0':
Value = '0U'
if Pcd.DatumType in ['UINT64', 'UINT32', 'UINT16', 'UINT8']:
try:
+ if Value.upper().endswith('L'):
+ Value = Value[:-1]
if Value.upper().startswith('0X'):
ValueNumber = int (Value, 16)
else:
ValueNumber = int (Value)
except:
diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py
index ba83e02..4d8bd14 100644
--- a/BaseTools/Source/Python/Common/Expression.py
+++ b/BaseTools/Source/Python/Common/Expression.py
@@ -13,11 +13,13 @@
## Import Modules
#
from Common.GlobalData import *
from CommonDataClass.Exceptions import BadExpression
from CommonDataClass.Exceptions import WrnExpression
-from Misc import GuidStringToGuidStructureString
+from Misc import GuidStringToGuidStructureString, ParseFieldValue
+import Common.EdkLogger as EdkLogger
+import copy
ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].'
ERR_SNYTAX = 'Syntax error, the rest of expression cannot be evaluated: [%s].'
ERR_MATCH = 'No matching right parenthesis.'
ERR_STRING_TOKEN = 'Bad string token: [%s].'
@@ -112,10 +114,19 @@ def ReplaceExprMacro(String, Macros, ExceptionList = None):
String = RetStr
MacroStartPos = String.find('$(')
StrList[i] = RetStr
return ''.join(StrList)
+# transfer int to string for in/not in expression
+def IntToStr(Value):
+ StrList = []
+ while Value > 0:
+ StrList.append(chr(Value & 0xff))
+ Value = Value >> 8
+ Value = '"' + ''.join(StrList) + '"'
+ return Value
+
SupportedInMacroList = ['TARGET', 'TOOL_CHAIN_TAG', 'ARCH', 'FAMILY']
class ValueExpression(object):
# Logical operator mapping
LogicalOperators = {
@@ -144,14 +155,28 @@ class ValueExpression(object):
@staticmethod
def Eval(Operator, Oprand1, Oprand2 = None):
WrnExp = None
- if Operator not in ["==", "!=", ">=", "<=", ">", "<", "in", "not in"] and \
- (type(Oprand1) == type('') or type(Oprand2) == type('')):
- raise BadExpression(ERR_STRING_EXPR % Operator)
-
+ if Operator not in ["in", "not in"] and (type(Oprand1) == type('') or type(Oprand2) == type('')):
+ if type(Oprand1) == type(''):
+ if Oprand1[0] in ['"', "'"] or Oprand1.startswith('L"') or Oprand1.startswith("L'")or Oprand1.startswith('UINT'):
+ Oprand1, Size = ParseFieldValue(Oprand1)
+ else:
+ Oprand1,Size = ParseFieldValue('"' + Oprand1 + '"')
+ if type(Oprand2) == type(''):
+ if Oprand2[0] in ['"', "'", 'L'] or Oprand2.startswith('UINT'):
+ Oprand2, Size = ParseFieldValue(Oprand2)
+ else:
+ Oprand2, Size = ParseFieldValue('"' + Oprand2 + '"')
+ if type(Oprand1) == type('') or type(Oprand2) == type(''):
+ raise BadExpression(ERR_STRING_EXPR % Operator)
+ if Operator in ['in', 'not in']:
+ if type(Oprand1) != type(''):
+ Oprand1 = IntToStr(Oprand1)
+ if type(Oprand2) != type(''):
+ Oprand2 = IntToStr(Oprand2)
TypeDict = {
type(0) : 0,
type(0L) : 0,
type('') : 1,
type(True) : 2
@@ -224,10 +249,13 @@ class ValueExpression(object):
self._NoProcess = False
if type(Expression) != type(''):
self._Expr = Expression
self._NoProcess = True
return
+ if Expression.strip().startswith('{') and Expression.strip().endswith('}'):
+ self._Expr = Expression
+ self._NoProcess = True
self._Expr = ReplaceExprMacro(Expression.strip(),
SymbolTable,
SupportedInMacroList)
@@ -235,11 +263,11 @@ class ValueExpression(object):
raise BadExpression(ERR_EMPTY_EXPR)
#
# The symbol table including PCD and macro mapping
#
- self._Symb = SymbolTable
+ self._Symb = copy.deepcopy(SymbolTable)
self._Symb.update(self.LogicalOperators)
self._Idx = 0
self._Len = len(self._Expr)
self._Token = ''
self._WarnExcept = None
@@ -282,11 +310,11 @@ class ValueExpression(object):
if Val == 'L""':
Val = False
elif not Val:
Val = False
RealVal = '""'
- elif not Val.startswith('L"') and not Val.startswith('{'):
+ elif not Val.startswith('L"') and not Val.startswith('{') and not Val.startswith("L'"):
Val = True
RealVal = '"' + RealVal + '"'
# The expression has been parsed, but the end of expression is not reached
# It means the rest does not comply EBNF of <Expression>
@@ -424,10 +452,19 @@ class ValueExpression(object):
# Try to convert string to number
def __IsNumberToken(self):
Radix = 10
if self._Token.lower()[0:2] == '0x' and len(self._Token) > 2:
Radix = 16
+ if self._Token.startswith('"') or self._Token.startswith("'")\
+ or self._Token.startswith("L'") or self._Token.startswith('L"'):
+ Flag = 0
+ for Index in range(len(self._Token)):
+ if self._Token[Index] in ['"', "'"]:
+ Flag += 1
+ if Flag == 2:
+ self._Token = ParseFieldValue(self._Token)[0]
+ return True
try:
self._Token = int(self._Token, Radix)
return True
except ValueError:
return False
@@ -471,14 +508,16 @@ class ValueExpression(object):
# Replace escape \\\", \"
Expr = self._Expr[self._Idx:].replace('\\\\', '//').replace('\\\"', '\\\'')
for Ch in Expr:
self._Idx += 1
- if Ch == '"':
+ if Ch == '"' or Ch == "'":
break
self._Token = self._LiteralToken = self._Expr[Idx:self._Idx]
- if not self._Token.endswith('"'):
+ if self._Token.startswith('"') and not self._Token.endswith('"'):
+ raise BadExpression(ERR_STRING_TOKEN % self._Token)
+ if self._Token.startswith("'") and not self._Token.endswith("'"):
raise BadExpression(ERR_STRING_TOKEN % self._Token)
self._Token = self._Token[1:-1]
return self._Token
# Get token that is comprised by alphanumeric, underscore or dot(used by PCD)
@@ -576,11 +615,48 @@ class ValueExpression(object):
if Expr.startswith('L"'):
# Skip L
self._Idx += 1
UStr = self.__GetString()
self._Token = 'L"' + UStr + '"'
+ self._Token, Size = ParseFieldValue(self._Token)
+ return self._Token
+ elif Expr.startswith("L'"):
+ # Skip L
+ self._Idx += 1
+ UStr = self.__GetString()
+ self._Token = "L'" + UStr + "'"
+ self._Token, Size = ParseFieldValue(self._Token)
+ return self._Token
+ elif Expr.startswith('"'):
+ UStr = self.__GetString()
+ self._Token = '"' + UStr + '"'
+ self._Token, Size = ParseFieldValue(self._Token)
return self._Token
+ elif Expr.startswith("'"):
+ UStr = self.__GetString()
+ self._Token = "'" + UStr + "'"
+ self._Token, Size = ParseFieldValue(self._Token)
+ return self._Token
+ elif Expr.startswith('UINT'):
+ Re = re.compile('(?:UINT8|UINT16|UINT32|UINT64)\((.+)\)')
+ try:
+ RetValue = Re.search(Expr).group(1)
+ except:
+ raise BadExpression('Invalid Expression %s' % Expr)
+ Idx = self._Idx
+ for Ch in Expr:
+ self._Idx += 1
+ if Ch == '(':
+ Prefix = self._Expr[Idx:self._Idx - 1]
+ Idx = self._Idx
+ if Ch == ')':
+ TmpValue = self._Expr[Idx :self._Idx - 1]
+ TmpValue = ValueExpression(TmpValue)(True)
+ TmpValue = '0x%x' % int(TmpValue) if type(TmpValue) != type('') else TmpValue
+ break
+ self._Token, Size = ParseFieldValue(Prefix + '(' + TmpValue + ')')
+ return self._Token
self._Token = ''
if Expr:
Ch = Expr[0]
Match = self.RegGuidPattern.match(Expr)
@@ -646,10 +722,162 @@ class ValueExpression(object):
self._Token = self.LogicalOperators[self._Token]
return True
self._Idx = Idx
return False
+class ValueExpressionEx(ValueExpression):
+ def __init__(self, PcdValue, PcdType, SymbolTable={}):
+ ValueExpression.__init__(self, PcdValue, SymbolTable)
+ self.PcdValue = PcdValue
+ self.PcdType = PcdType
+
+ def __call__(self, RealValue=False, Depth=0):
+ PcdValue = self.PcdValue
+ try:
+ PcdValue = ValueExpression.__call__(self, RealValue, Depth)
+ except WrnExpression, Value:
+ PcdValue = Value.result
+
+ if PcdValue == 'True':
+ PcdValue = '1'
+ if PcdValue == 'False':
+ PcdValue = '0'
+ if self.PcdType in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
+ PcdValue = PcdValue.strip()
+ if type(PcdValue) == type('') and PcdValue.startswith('{') and PcdValue.endswith('}'):
+ PcdValue = PcdValue[1:-1].split(',')
+ if type(PcdValue) == type([]):
+ TmpValue = 0
+ Size = 0
+ for Item in PcdValue:
+ if Item.startswith('UINT16'):
+ ItemSize = 2
+ elif Item.startswith('UINT32'):
+ ItemSize = 4
+ elif Item.startswith('UINT64'):
+ ItemSize = 8
+ else:
+ ItemSize = 0
+ Item = ValueExpressionEx(Item, self.PcdType, self._Symb)(True)
+
+ if ItemSize == 0:
+ ItemValue, ItemSize = ParseFieldValue(Item)
+ else:
+ ItemValue = ParseFieldValue(Item)[0]
+
+ if type(ItemValue) == type(''):
+ ItemValue = int(ItemValue, 16) if ItemValue.startswith('0x') else int(ItemValue)
+
+ TmpValue = (ItemValue << (Size * 8)) | TmpValue
+ Size = Size + ItemSize
+ else:
+ TmpValue, Size = ParseFieldValue(PcdValue)
+ if type(TmpValue) == type(''):
+ TmpValue = int(TmpValue)
+ else:
+ PcdValue = '0x%0{}X'.format(Size) % (TmpValue)
+ if TmpValue < 0:
+ raise BadExpression('Type %s PCD Value is negative' % self.PcdType)
+ if self.PcdType == 'UINT8' and Size > 1:
+ raise BadExpression('Type %s PCD Value Size is Larger than 1 byte' % self.PcdType)
+ if self.PcdType == 'UINT16' and Size > 2:
+ raise BadExpression('Type %s PCD Value Size is Larger than 2 byte' % self.PcdType)
+ if self.PcdType == 'UINT32' and Size > 4:
+ raise BadExpression('Type %s PCD Value Size is Larger than 4 byte' % self.PcdType)
+ if self.PcdType == 'UINT64' and Size > 8:
+ raise BadExpression('Type %s PCD Value Size is Larger than 8 byte' % self.PcdType)
+ if self.PcdType in ['VOID*']:
+ try:
+ TmpValue = long(PcdValue)
+ TmpList = []
+ if TmpValue.bit_length() == 0:
+ PcdValue = '{0x00}'
+ else:
+ for I in range((TmpValue.bit_length() + 7) / 8):
+ TmpList.append('0x%02x' % ((TmpValue >> I * 8) & 0xff))
+ PcdValue = '{' + ', '.join(TmpList) + '}'
+ except:
+ if PcdValue.strip().startswith('{'):
+ PcdValue = PcdValue.strip()[1:-1].strip()
+ Size = 0
+ ValueStr = ''
+ TokenSpaceGuidName = ''
+ if PcdValue.startswith('GUID') and PcdValue.endswith(')'):
+ try:
+ TokenSpaceGuidName = re.search('GUID\((\w+)\)', PcdValue).group(1)
+ except:
+ pass
+ if TokenSpaceGuidName and TokenSpaceGuidName in self._Symb:
+ PcdValue = 'GUID(' + self._Symb[TokenSpaceGuidName] + ')'
+ elif TokenSpaceGuidName:
+ raise BadExpression('%s not found in DEC file' % TokenSpaceGuidName)
+
+ ListItem, Size = ParseFieldValue(PcdValue)
+ elif PcdValue.startswith('DEVICE_PATH') and PcdValue.endswith(')'):
+ ListItem, Size = ParseFieldValue(PcdValue)
+ else:
+ ListItem = PcdValue.split(',')
+
+ if type(ListItem) == type(0) or type(ListItem) == type(0L):
+ for Index in range(0, Size):
+ ValueStr += '0x%02X' % (int(ListItem) & 255)
+ ListItem >>= 8
+ ValueStr += ', '
+ PcdValue = '{' + ValueStr[:-2] + '}'
+ elif type(ListItem) == type(''):
+ if ListItem.startswith('{') and ListItem.endswith('}'):
+ PcdValue = ListItem
+ else:
+ LabelDict = {}
+ ReLabel = re.compile('LABEL\((\w+)\)')
+ ReOffset = re.compile('OFFSET_OF\((\w+)\)')
+ for Index, Item in enumerate(ListItem):
+ # for LABEL parse
+ Item = Item.strip()
+ try:
+ LabelList = ReLabel.findall(Item)
+ for Label in LabelList:
+ if Label not in LabelDict.keys():
+ LabelDict[Label] = str(Index)
+ Item = ReLabel.sub('', Item)
+ except:
+ pass
+ try:
+ OffsetList = ReOffset.findall(Item)
+ except:
+ pass
+ for Offset in OffsetList:
+ if Offset in LabelDict.keys():
+ Re = re.compile('OFFSET_OF\(%s\)'% Offset)
+ Item = Re.sub(LabelDict[Offset], Item)
+ else:
+ raise BadExpression('%s not defined before use' % Offset)
+ if Item.startswith('UINT16'):
+ ItemSize = 2
+ elif Item.startswith('UINT32'):
+ ItemSize = 4
+ elif Item.startswith('UINT64'):
+ ItemSize = 8
+ else:
+ ItemSize = 0
+ TmpValue = ValueExpressionEx(Item, self.PcdType, self._Symb)(True)
+ Item = '0x%x' % TmpValue if type(TmpValue) != type('') else TmpValue
+ if ItemSize == 0:
+ ItemValue, ItemSize = ParseFieldValue(Item)
+ else:
+ ItemValue = ParseFieldValue(Item)[0]
+ for I in range(0, ItemSize):
+ ValueStr += '0x%02X' % (int(ItemValue) & 255)
+ ItemValue >>= 8
+ ValueStr += ', '
+ Size += ItemSize
+
+ if Size > 0:
+ PcdValue = '{' + ValueStr[:-2] + '}'
+ if RealValue:
+ return PcdValue
+
if __name__ == '__main__':
pass
while True:
input = raw_input('Input expr: ')
if input in 'qQ':
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index 0374be0..c51b685 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -35,10 +35,11 @@ from BuildToolError import *
from CommonDataClass.DataClass import *
from Parsing import GetSplitValueList
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import uuid
+from CommonDataClass.Exceptions import BadExpression
## Regular expression used to find out place holders in string template
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
## Dictionary used to store file time stamp for quick re-access
@@ -1470,103 +1471,123 @@ def AnalyzePcdExpression(Setting):
FieldList.append(Setting[StartPos:Pos].strip())
StartPos = Pos + 1
return FieldList
+def ParseDevPathValue (Value):
+ pass
+
def ParseFieldValue (Value):
- if type(Value) == type(0):
- return Value, (Value.bit_length() + 7) / 8
- if type(Value) <> type(''):
- raise ValueError
- Value = Value.strip()
- if Value.startswith('UINT8') and Value.endswith(')'):
- Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
- if Size > 1:
- raise ValueError
+ if type(Value) == type(0):
+ return Value, (Value.bit_length() + 7) / 8
+ if type(Value) <> type(''):
+ raise BadExpression('Type %s is %s' %(Value, type(Value)))
+ Value = Value.strip()
+ if Value.startswith('UINT8') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 1:
+ raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
+ return Value, 1
+ if Value.startswith('UINT16') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 2:
+ raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
+ return Value, 2
+ if Value.startswith('UINT32') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 4:
+ raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
+ return Value, 4
+ if Value.startswith('UINT64') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 8:
+ raise BadExpression('Value (%s) Size larger than %d' % (Value, Size))
+ return Value, 8
+ if Value.startswith('GUID') and Value.endswith(')'):
+ Value = Value.split('(', 1)[1][:-1].strip()
+ if Value[0] == '{' and Value[-1] == '}':
+ Value = Value[1:-1].strip()
+ Value = Value.split('{', 1)
+ Value = ['%02x' % int(Item, 16) for Item in (Value[0] + Value[1][:-1]).split(',')]
+ if len(Value[0]) != 8:
+ Value[0] = '%08X' % int(Value[0], 16)
+ if len(Value[1]) != 4:
+ Value[1] = '%04X' % int(Value[1], 16)
+ if len(Value[2]) != 4:
+ Value[2] = '%04X' % int(Value[2], 16)
+ Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])
+ if Value[0] == '"' and Value[-1] == '"':
+ Value = Value[1:-1]
+ try:
+ Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
+ except ValueError, Message:
+ raise BadExpression('%s' % Message)
+ Value, Size = ParseFieldValue(Value)
+ return Value, 16
+ if Value.startswith('L"') and Value.endswith('"'):
+ # Unicode String
+ List = list(Value[2:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, (len(List) + 1) * 2
+ if Value.startswith('"') and Value.endswith('"'):
+ # ASCII String
+ List = list(Value[1:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List) + 1
+ if Value.startswith("L'") and Value.endswith("'"):
+ # Unicode Character Constant
+ List = list(Value[2:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, len(List) * 2
+ if Value.startswith("'") and Value.endswith("'"):
+ # Character constant
+ List = list(Value[1:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List)
+ if Value.startswith('{') and Value.endswith('}'):
+ # Byte array
+ Value = Value[1:-1]
+ List = [Item.strip() for Item in Value.split(',')]
+ List.reverse()
+ Value = 0
+ RetSize = 0
+ for Item in List:
+ ItemValue, Size = ParseFieldValue(Item)
+ RetSize += Size
+ for I in range(Size):
+ Value = (Value << 8) | ((ItemValue >> 8 * I) & 0xff)
+ return Value, RetSize
+ if Value.startswith('DEVICE_PATH(') and Value.endswith(')'):
+ Value = Value.split('"')[1]
+ return ParseDevPathValue(Value)
+ if Value.lower().startswith('0x'):
+ Value = int(Value, 16)
+ if Value == 0:
+ return 0, 1
+ return Value, (Value.bit_length() + 7) / 8
+ if Value[0].isdigit():
+ Value = int(Value, 10)
+ if Value == 0:
+ return 0, 1
+ return Value, (Value.bit_length() + 7) / 8
+ if Value.lower() == 'true':
+ return 1, 1
+ if Value.lower() == 'false':
+ return 0, 1
return Value, 1
- if Value.startswith('UINT16') and Value.endswith(')'):
- Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
- if Size > 2:
- raise ValueError
- return Value, 2
- if Value.startswith('UINT32') and Value.endswith(')'):
- Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
- if Size > 4:
- raise ValueError
- return Value, 4
- if Value.startswith('UINT64') and Value.endswith(')'):
- Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
- if Size > 8:
- raise ValueError
- return Value, 8
- if Value.startswith('GUID') and Value.endswith(')'):
- Value = Value.split('(', 1)[1][:-1].strip()
- if Value[0] == '{' and Value[-1] == '}':
- Value = Value[1:-1].strip()
- Value = Value.split('{', 1)
- Value = [Item.strip()[2:] for Item in (Value[0] + Value[1][:-1]).split(',')]
- Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])
- if Value[0] == '"' and Value[-1] == '"':
- Value = Value[1:-1]
- Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
- Value, Size = ParseFieldValue(Value)
- return Value, 16
- if Value.startswith('L"') and Value.endswith('"'):
- # Unicode String
- List = list(Value[2:-1])
- List.reverse()
- Value = 0
- for Char in List:
- Value = (Value << 16) | ord(Char)
- return Value, (len(List) + 1) * 2
- if Value.startswith('"') and Value.endswith('"'):
- # ASCII String
- List = list(Value[1:-1])
- List.reverse()
- Value = 0
- for Char in List:
- Value = (Value << 8) | ord(Char)
- return Value, len(List) + 1
- if Value.startswith("L'") and Value.endswith("'"):
- # Unicode Character Constant
- List = list(Value[2:-1])
- List.reverse()
- Value = 0
- for Char in List:
- Value = (Value << 16) | ord(Char)
- return Value, len(List) * 2
- if Value.startswith("'") and Value.endswith("'"):
- # Character constant
- List = list(Value[1:-1])
- List.reverse()
- Value = 0
- for Char in List:
- Value = (Value << 8) | ord(Char)
- return Value, len(List)
- if Value.startswith('{') and Value.endswith('}'):
- # Byte array
- Value = Value[1:-1]
- List = [Item.strip() for Item in Value.split(',')]
- List.reverse()
- Value = 0
- for Item in List:
- ItemValue, Size = ParseFieldValue(Item)
- if Size > 1:
- raise ValueError
- Value = (Value << 8) | ItemValue
- return Value, len(List)
- if Value.lower().startswith('0x'):
- Value = int(Value, 16)
- return Value, (Value.bit_length() + 7) / 8
- if Value[0].isdigit():
- Value = int(Value, 10)
- return Value, (Value.bit_length() + 7) / 8
- if Value.lower() == 'true':
- return 1, 1
- if Value.lower() == 'false':
- return 0, 1
- return Value, 1
## AnalyzeDscPcd
#
# Analyze DSC PCD value, since there is no data type info in DSC
# This fuction is used to match functions (AnalyzePcdData, AnalyzeHiiPcdData, AnalyzeVpdPcdData) used for retrieving PCD value from database
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index e422100..05b26a3 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -798,11 +798,11 @@ class DscBuildData(PlatformBuildClassObject):
if ModuleFile in self._Modules:
continue
ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
PkgSet.update(ModuleData.Packages)
- self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
+ self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
EdkLogger.error('build', PARSER_ERROR,
"Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
@@ -819,10 +819,12 @@ class DscBuildData(PlatformBuildClassObject):
if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
try:
ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)
except WrnExpression, Value:
ValueList[Index] = Value.result
+ except BadExpression, Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=self._LineIndex + 1)
except EvaluationException, Excpt:
if hasattr(Excpt, 'Pcd'):
if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
" it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
@@ -832,15 +834,17 @@ class DscBuildData(PlatformBuildClassObject):
EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
File=self.MetaFile, Line=LineNo)
else:
EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
File=self.MetaFile, Line=LineNo)
- if ValueList[Index] == 'True':
- ValueList[Index] = '1'
- elif ValueList[Index] == 'False':
- ValueList[Index] = '0'
if ValueList[Index]:
+ DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
+ try:
+ ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
+ except BadExpression, Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
+ ExtraData="PCD [%s.%s] Value \"%s\" " % (TokenSpaceGuid, PcdCName, ValueList[Index]))
Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
if not Valid:
EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):
diff --git a/BaseTools/Source/Python/Workspace/InfBuildData.py b/BaseTools/Source/Python/Workspace/InfBuildData.py
index fd94067..7ea9b56 100644
--- a/BaseTools/Source/Python/Workspace/InfBuildData.py
+++ b/BaseTools/Source/Python/Workspace/InfBuildData.py
@@ -14,10 +14,11 @@
from Common.String import *
from Common.DataType import *
from Common.Misc import *
from types import *
+from MetaFileParser import *
from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject
## Module build information from INF file
#
# This class is used to retrieve information stored in database and convert them
@@ -1142,10 +1143,16 @@ class InfBuildData(ModuleBuildClassObject):
Pcd.DatumType = PcdInPackage.DatumType
Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize
Pcd.InfDefaultValue = Pcd.DefaultValue
if Pcd.DefaultValue in [None, '']:
Pcd.DefaultValue = PcdInPackage.DefaultValue
+ else:
+ try:
+ Pcd.DefaultValue = ValueExpressionEx(Pcd.DefaultValue, Pcd.DatumType, self.Guids)(True)
+ except BadExpression, Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(TokenSpaceGuid, PcdRealName, Pcd.DefaultValue, Value),
+ File=self.MetaFile, Line=LineNo)
break
else:
EdkLogger.error(
'build',
FORMAT_INVALID,
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 3038447..b2b0e28 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -25,11 +25,11 @@ import Common.EdkLogger as EdkLogger
import Common.GlobalData as GlobalData
from CommonDataClass.DataClass import *
from Common.DataType import *
from Common.String import *
-from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression
+from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression, ParseFieldValue
from Common.Expression import *
from CommonDataClass.Exceptions import *
from Common.LongFilePathSupport import OpenLongFilePath as open
from MetaFileTable import MetaFileStorage
@@ -180,10 +180,11 @@ class MetaFileParser(object):
self._Enabled = 0
self._Finished = False
self._PostProcessed = False
# Different version of meta-file has different way to parse.
self._Version = 0
+ self._GuidDict = {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
## Store the parsed data in table
def _Store(self, *Args):
return self._Table.Insert(*Args)
@@ -1869,10 +1870,12 @@ class DecParser(MetaFileParser):
ExtraData=self._CurrentLine + \
" (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
File=self.MetaFile, Line=self._LineIndex + 1)
self._ValueList[0] = TokenList[0]
self._ValueList[1] = TokenList[1]
+ if self._ValueList[0] not in self._GuidDict:
+ self._GuidDict[self._ValueList[0]] = self._ValueList[1]
## PCD sections parser
#
# [PcdsFixedAtBuild]
# [PcdsPatchableInModule]
@@ -1985,16 +1988,18 @@ class DecParser(MetaFileParser):
if PcdValue:
try:
ValueList[0] = ValueExpression(PcdValue, self._AllPcdDict)(True)
except WrnExpression, Value:
ValueList[0] = Value.result
+ except BadExpression, Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=self._LineIndex + 1)
- if ValueList[0] == 'True':
- ValueList[0] = '1'
- if ValueList[0] == 'False':
- ValueList[0] = '0'
-
+ if ValueList[0]:
+ try:
+ ValueList[0] = ValueExpressionEx(ValueList[0], ValueList[1], self._GuidDict)(True)
+ except BadExpression, Value:
+ EdkLogger.error('Parser', FORMAT_INVALID, Value, ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
# check format of default value against the datum type
IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])
if not IsValid:
EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,
File=self.MetaFile, Line=self._LineIndex + 1)
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
index c289b9d..c760e57 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
@@ -1,9 +1,9 @@
## @file
# Common routines used by workspace
#
-# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
@@ -41,28 +41,32 @@ def GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain):
# @param BuildDatabase: The database saves all data for all metafiles
# @param Arch: Current arch
# @param Target: Current target
# @param Toolchain: Current toolchain
# @retval: A dictionary contains instances of PcdClassObject with key (PcdCName, TokenSpaceGuid)
+# @retval: A dictionary contains real GUIDs of TokenSpaceGuid
#
def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain,additionalPkgs):
PkgList = GetPackageList(Platform, BuildDatabase, Arch, Target, Toolchain)
PkgList = set(PkgList)
PkgList |= additionalPkgs
DecPcds = {}
+ GuidDict = {}
for Pkg in PkgList:
+ Guids = Pkg.Guids
+ GuidDict.update(Guids)
for Pcd in Pkg.Pcds:
PcdCName = Pcd[0]
PcdTokenName = Pcd[1]
if GlobalData.MixedPcd:
for PcdItem in GlobalData.MixedPcd.keys():
if (PcdCName, PcdTokenName) in GlobalData.MixedPcd[PcdItem]:
PcdCName = PcdItem[0]
break
if (PcdCName, PcdTokenName) not in DecPcds.keys():
DecPcds[PcdCName, PcdTokenName] = Pkg.Pcds[Pcd]
- return DecPcds
+ return DecPcds, GuidDict
## Get all dependent libraries for a module
#
# @param Module: InfBuildData instance
# @param Platform: DscBuildData instance
diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py
index 75e8ec9..5da9914 100644
--- a/BaseTools/Source/Python/build/BuildReport.py
+++ b/BaseTools/Source/Python/build/BuildReport.py
@@ -43,10 +43,11 @@ import Common.GlobalData as GlobalData
from AutoGen.AutoGen import ModuleAutoGen
from Common.Misc import PathClass
from Common.String import NormPath
from Common.DataType import *
import collections
+from Common.Expression import ValueExpressionEx
## Pattern to extract contents in EDK DXS files
gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL)
## Pattern to find total FV total size, occupied size in flash report intermediate file
@@ -847,12 +848,15 @@ class PcdReport(object):
#
# Collect PCD DEC default value.
#
self.DecPcdDefault = {}
+ self._GuidDict = {}
for Pa in Wa.AutoGenObjectList:
for Package in Pa.PackageList:
+ Guids = Package.Guids
+ self._GuidDict.update(Guids)
for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:
DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue
self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)
#
# Collect PCDs defined in DSC common section
@@ -941,10 +945,12 @@ class PcdReport(object):
#
DecDefaultValue = self.DecPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType))
DscDefaultValue = self.DscPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))
DscDefaultValBak= DscDefaultValue
DscDefaultValue = self.FdfPcdSet.get((Pcd.TokenCName, Key), DscDefaultValue)
+ if DscDefaultValue:
+ DscDefaultValue = ValueExpressionEx(DscDefaultValue, Pcd.DatumType, self._GuidDict)(True)
InfDefaultValue = None
PcdValue = DecDefaultValue
if DscDefaultValue:
PcdValue = DscDefaultValue
--
2.6.1.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Patch 2/2] BaseTools: Add DevicePath support for PCD values
2017-12-26 16:40 [Patch 0/2] BaseTools: Add Flexible PCD Value support Yonghong Zhu
2017-12-26 16:40 ` [Patch 1/2] BaseTools: Support PCD flexible values format Yonghong Zhu
@ 2017-12-26 16:40 ` Yonghong Zhu
2017-12-27 2:40 ` Gao, Liming
1 sibling, 1 reply; 4+ messages in thread
From: Yonghong Zhu @ 2017-12-26 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Yunhua Feng
Use C code parse device path to output hex string, and Python
run command when PCD Value need device path parse.
https://bugzilla.tianocore.org/show_bug.cgi?id=541
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/BinaryFiles.txt | 3 +-
BaseTools/Source/C/DevicePath/DevicePath.c | 188 ++
BaseTools/Source/C/DevicePath/DevicePath.h | 1404 ++++++++
BaseTools/Source/C/DevicePath/DevicePathFromText.c | 3503 ++++++++++++++++++++
BaseTools/Source/C/DevicePath/DevicePathFromText.h | 72 +
.../Source/C/DevicePath/DevicePathUtilities.c | 2352 +++++++++++++
.../Source/C/DevicePath/DevicePathUtilities.h | 555 ++++
BaseTools/Source/C/DevicePath/GNUmakefile | 30 +
BaseTools/Source/C/DevicePath/Makefile | 24 +
BaseTools/Source/C/DevicePath/UefiDevicePathLib.c | 298 ++
BaseTools/Source/C/DevicePath/UefiDevicePathLib.h | 473 +++
BaseTools/Source/C/GNUmakefile | 3 +-
BaseTools/Source/C/Makefile | 5 +-
BaseTools/Source/Python/Common/Misc.py | 35 +-
BaseTools/Source/Python/Workspace/DscBuildData.py | 2 +-
15 files changed, 8940 insertions(+), 7 deletions(-)
create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.h
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.h
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.c
create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.h
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
diff --git a/BaseTools/Source/BinaryFiles.txt b/BaseTools/Source/BinaryFiles.txt
index 7b014a7..a5273d4 100644
--- a/BaseTools/Source/BinaryFiles.txt
+++ b/BaseTools/Source/BinaryFiles.txt
@@ -9,11 +9,11 @@
# [ExtraFiles.Win32] section.
# The [CxFreeze.Win32] section is maintained by the owner of the Build Server who
# must ensure that files that are required by the cx_freeze frozen binaries are
# present in the Bin\Win32 directory.
#
-# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available under
# the terms and conditions of the BSD License which accompanies this distribution.
# The full text of the license may be found at:
# http://opensource.org/licenses/bsd-license.php
@@ -57,10 +57,11 @@ TianoCompress.exe
Trim.exe
UPT.exe
VfrCompile.exe
VolInfo.exe
Pkcs7Sign.exe
+DevicePath.exe
[ExtraFiles.Win32]
TestSigningPrivateKey.pem
config.ini
exception.xml
diff --git a/BaseTools/Source/C/DevicePath/DevicePath.c b/BaseTools/Source/C/DevicePath/DevicePath.c
new file mode 100644
index 0000000..6c32ad4
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePath.c
@@ -0,0 +1,188 @@
+/** @file
+ Definition for Device Path Tool.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UefiDevicePathLib.h"
+
+//
+// Utility Name
+//
+#define UTILITY_NAME "DevicePath"
+
+//
+// Utility version information
+//
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+EFI_GUID gEfiDebugPortDevicePathGuid = DEVICE_PATH_MESSAGING_DEBUGPORT;
+EFI_GUID gEfiPcAnsiGuid = EFI_PC_ANSI_GUID;
+EFI_GUID gEfiVT100Guid = EFI_VT_100_GUID;
+EFI_GUID gEfiVT100PlusGuid = EFI_VT_100_PLUS_GUID;
+EFI_GUID gEfiVTUTF8Guid = EFI_VT_UTF8_GUID;
+EFI_GUID gEfiUartDevicePathGuid = EFI_UART_DEVICE_PATH_GUID;
+EFI_GUID gEfiSasDevicePathGuid = EFI_SAS_DEVICE_PATH_GUID;
+EFI_GUID gEfiVirtualDiskGuid = { 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }};
+EFI_GUID gEfiVirtualCdGuid = { 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }};
+EFI_GUID gEfiPersistentVirtualDiskGuid = { 0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }};
+EFI_GUID gEfiPersistentVirtualCdGuid = { 0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }};
+
+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) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " DevicePathString DevicePathString like as:\n"
+ " \"PciRoot(0)/Pci(0,0)\"\n"
+ " start with \" and end with \"\n"
+ " not support blank in device path string.\n");
+
+ fprintf (stdout, " --version Show program's version number and exit.\n");
+ fprintf (stdout, " -h, --help Show this help message and exit.\n");
+}
+
+
+void print_mem(void const *vp, size_t n)
+{
+ unsigned char const *p = vp;
+ for (size_t i=0; i<n; i++) {
+ printf("0x%02x ", p[i]);
+ }
+}
+
+VOID
+Ascii2UnicodeString (
+ CHAR8 *String,
+ CHAR16 *UniString
+ )
+/*++
+
+Routine Description:
+
+ Write ascii string as unicode string format to FILE
+
+Arguments:
+
+ String - Pointer to string that is written to FILE.
+ UniString - Pointer to unicode string
+
+Returns:
+
+ NULL
+
+--*/
+{
+ while (*String != '\0') {
+ *(UniString++) = (CHAR16) *(String++);
+ }
+ //
+ // End the UniString with a NULL.
+ //
+ *UniString = '\0';
+}
+
+int main(int argc, CHAR8 *argv[])
+{
+ CHAR8 * Str;
+ CHAR16* Str16;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "No input options specified.");
+ Usage ();
+ return STATUS_ERROR;
+ }
+ if ((stricmp (argv[1], "-h") == 0) || (stricmp (argv[1], "--help") == 0)) {
+ Version ();
+ Usage ();
+ return STATUS_SUCCESS;
+ }
+
+ if (stricmp (argv[1], "--version") == 0) {
+ Version ();
+ return STATUS_SUCCESS;
+ }
+ Str = argv[1];
+ if (Str == NULL) {
+ fprintf(stderr, "Invalid option value, Device Path can't be NULL");
+ return STATUS_ERROR;
+ }
+ Str16 = (CHAR16 *)malloc(1024);
+ if (Str16 == NULL) {
+ fprintf(stderr, "Resource, memory cannot be allcoated");
+ return STATUS_ERROR;
+ }
+ Ascii2UnicodeString(Str, Str16);
+ DevicePath = UefiDevicePathLibConvertTextToDevicePath(Str16);
+ while (!((DevicePath->Type == END_DEVICE_PATH_TYPE) && (DevicePath->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)) )
+ {
+ print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1] << 8));
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)DevicePath + (DevicePath->Length[0] | DevicePath->Length[1] << 8));
+ }
+ print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1] << 8));
+ putchar('\n');
+ return STATUS_SUCCESS;
+}
diff --git a/BaseTools/Source/C/DevicePath/DevicePath.h b/BaseTools/Source/C/DevicePath/DevicePath.h
new file mode 100644
index 0000000..389c993
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePath.h
@@ -0,0 +1,1404 @@
+/** @file
+ The device path protocol as defined in UEFI 2.0.
+
+ The device path represents a programmatic path to a device,
+ from a software point of view. The path must persist from boot to boot, so
+ it can not contain things like PCI bus numbers that change from boot to boot.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_DEVICE_PATH_H__
+#define __EFI_DEVICE_PATH_H__
+
+#include <Guid/PcAnsi.h>
+#include <IndustryStandard/Acpi3_0.h>
+
+///
+/// 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_ADDRESS
+///
+typedef struct {
+ ///
+ /// 48bit Bluetooth device address.
+ ///
+ UINT8 Address[6];
+} BLUETOOTH_ADDRESS;
+
+///
+/// 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_ADDRESS
+///
+typedef struct {
+ ///
+ /// 48-bit Bluetooth device address
+ ///
+ UINT8 Address[6];
+ ///
+ /// 0x00 - Public Device Address
+ /// 0x01 - Random Device Address
+ ///
+ UINT8 Type;
+} BLUETOOTH_LE_ADDRESS;
+
+///
+/// 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 EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE
+
+extern EFI_GUID gEfiVirtualDiskGuid;
+
+///
+/// This GUID defines a RAM Disk supporting an ISO image in volatile memory.
+///
+#define EFI_VIRTUAL_CD_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE
+
+extern EFI_GUID gEfiVirtualCdGuid;
+
+///
+/// This GUID defines a RAM Disk supporting a raw disk format in persistent memory.
+///
+#define EFI_PERSISTENT_VIRTUAL_DISK_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT
+
+extern EFI_GUID gEfiPersistentVirtualDiskGuid;
+
+///
+/// This GUID defines a RAM Disk supporting an ISO image in persistent memory.
+///
+#define EFI_PERSISTENT_VIRTUAL_CD_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT
+
+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/DevicePath/DevicePathFromText.c b/BaseTools/Source/C/DevicePath/DevicePathFromText.c
new file mode 100644
index 0000000..fb5b09b
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.c
@@ -0,0 +1,3503 @@
+/** @file
+ DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UefiDevicePathLib.h"
+
+/**
+
+ Duplicates a string.
+
+ @param Src Source string.
+
+ @return The duplicated string.
+
+**/
+CHAR16 *
+UefiDevicePathLibStrDuplicate (
+ CONST CHAR16 *Src
+ )
+{
+ return AllocateCopyPool (StrSize (Src), Src);
+}
+
+/**
+
+ Get parameter in a pair of parentheses follow the given node name.
+ For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
+
+ @param Str Device Path Text.
+ @param NodeName Name of the node.
+
+ @return Parameter text for the node.
+
+**/
+CHAR16 *
+GetParamByNodeName (
+ CHAR16 *Str,
+ CHAR16 *NodeName
+ )
+{
+ CHAR16 *ParamStr;
+ CHAR16 *StrPointer;
+ UINTN NodeNameLength;
+ UINTN ParameterLength;
+
+ //
+ // Check whether the node name matchs
+ //
+ NodeNameLength = StrLen (NodeName);
+ if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {
+ return NULL;
+ }
+
+ ParamStr = Str + NodeNameLength;
+ if (!IS_LEFT_PARENTH (*ParamStr)) {
+ return NULL;
+ }
+
+ //
+ // Skip the found '(' and find first occurrence of ')'
+ //
+ ParamStr++;
+ ParameterLength = 0;
+ StrPointer = ParamStr;
+ while (!IS_NULL (*StrPointer)) {
+ if (IS_RIGHT_PARENTH (*StrPointer)) {
+ break;
+ }
+ StrPointer++;
+ ParameterLength++;
+ }
+ if (IS_NULL (*StrPointer)) {
+ //
+ // ')' not found
+ //
+ return NULL;
+ }
+
+ ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
+ if (ParamStr == NULL) {
+ return NULL;
+ }
+ //
+ // Terminate the parameter string
+ //
+ ParamStr[ParameterLength] = L'\0';
+
+ return ParamStr;
+}
+
+/**
+ Gets 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;
+}
+
+/**
+ 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;
+}
+
+
+/**
+ 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;
+}
+
+/**
+ 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/DevicePathFromText.h b/BaseTools/Source/C/DevicePath/DevicePathFromText.h
new file mode 100644
index 0000000..4c46921
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.h
@@ -0,0 +1,72 @@
+/** @file
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL as defined in UEFI 2.0.
+ This protocol provides service to convert text to device paths and device nodes.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__
+#define __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__
+
+///
+/// Device Path From Text protocol
+///
+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
+ { \
+ 0x5c99a21, 0xc70f, 0x4ad2, {0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \
+ }
+
+/**
+ 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.
+
+ @retval a_pointer Pointer to the EFI device node.
+ @retval NULL if TextDeviceNode is NULL or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_FROM_TEXT_NODE)(
+ CONST CHAR16 *TextDeviceNode
+ );
+
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device path character.
+
+ @retval a_pointer Pointer to the allocated device path.
+ @retval NULL if TextDeviceNode is NULL or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_FROM_TEXT_PATH)(
+ CONST CHAR16 *TextDevicePath
+ );
+
+///
+/// This protocol converts text to device paths and device nodes.
+///
+typedef struct {
+ EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode;
+ EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath;
+} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;
+
+extern EFI_GUID gEfiDevicePathFromTextProtocolGuid;
+
+#endif
diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.c b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
new file mode 100644
index 0000000..07a58ee
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
@@ -0,0 +1,2352 @@
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment varibles. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UefiDevicePathLib.h"
+#include "DevicePathUtilities.h"
+
+#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
+ do { \
+ ASSERT (Expression); \
+ if (!(Expression)) { \
+ return Status; \
+ } \
+ } while (FALSE)
+
+
+//
+// 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;
+}
+
+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;
+}
diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.h b/BaseTools/Source/C/DevicePath/DevicePathUtilities.h
new file mode 100644
index 0000000..418615f
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.h
@@ -0,0 +1,555 @@
+/** @file
+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0.
+ Use to create and manipulate device paths and device nodes.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DEVICE_PATH_UTILITIES_H__
+#define __DEVICE_PATH_UTILITIES_H__
+
+///
+/// Device Path Utilities protocol
+///
+#define EFI_DEVICE_PATH_UTILITIES_GUID \
+ { \
+ 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \
+ }
+
+/**
+ Returns the size of the device path, in bytes.
+
+ @param DevicePath Points to the start of the EFI device path.
+
+ @return Size Size of the specified device path, in bytes, including the end-of-path tag.
+ @retval 0 DevicePath is NULL
+
+**/
+typedef
+UINTN
+( *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+
+/**
+ Create a duplicate of the specified path.
+
+ @param DevicePath Points to the source EFI device path.
+
+ @retval Pointer A pointer to the duplicate device path.
+ @retval NULL insufficient memory or DevicePath is NULL
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Create a new path by appending the second device path to the first.
+ If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned.
+ If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned.
+ If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is returned.
+
+ @param Src1 Points to the first device path.
+ @param Src2 Points to the second device path.
+
+ @retval Pointer A pointer to the newly created device path.
+ @retval NULL Memory could not be allocated
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_PATH)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+ CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+ );
+
+/**
+ Creates a new path by appending the device node to the device path.
+ If DeviceNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DeviceNode, followed by an end-of-device path device node is returned.
+ If both DeviceNode and DevicePath are NULL then a copy of an end-of-device-path device node is returned.
+
+ @param DevicePath Points to the device path.
+ @param DeviceNode Points to the device node.
+
+ @retval Pointer A pointer to the allocated device node.
+ @retval NULL There was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_NODE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+ );
+
+/**
+ Creates a new path by appending the specified device path instance to the specified device path.
+
+ @param DevicePath Points to the device path. If NULL, then ignored.
+ @param DevicePathInstance Points to the device path instance.
+
+ @retval Pointer A pointer to the newly created device path
+ @retval NULL Memory could not be allocated or DevicePathInstance is NULL.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ @param DevicePathInstance On input, this holds the pointer to the current device path
+ instance. On output, this holds the pointer to the next
+ device path instance or NULL if there are no more device
+ path instances in the device path.
+ @param DevicePathInstanceSize On output, this holds the size of the device path instance,
+ in bytes or zero, if DevicePathInstance is NULL.
+ If NULL, then the instance size is not output.
+
+ @retval Pointer A pointer to the copy of the current device path instance.
+ @retval NULL DevicePathInstace was NULL on entry or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)(
+ EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
+ UINTN *DevicePathInstanceSize
+ );
+
+/**
+ Creates a device node
+
+ @param NodeType NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+ the new device node.
+ @param NodeSubType NodeSubType is the device node sub-type
+ EFI_DEVICE_PATH.SubType) for the new device node.
+ @param NodeLength NodeLength is the length of the device node
+ (EFI_DEVICE_PATH.Length) for the new device node.
+
+ @retval Pointer A pointer to the newly created device node.
+ @retval NULL NodeLength is less than
+ the size of the header or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_CREATE_NODE)(
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+);
+
+/**
+ Returns whether a device path is multi-instance.
+
+ @param DevicePath Points to the device path. If NULL, then ignored.
+
+ @retval TRUE The device path has more than one instance
+ @retval FALSE The device path is empty or contains only a single instance.
+
+**/
+typedef
+BOOLEAN
+( *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+///
+/// This protocol is used to creates and manipulates device paths and device nodes.
+///
+typedef struct {
+ EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;
+ EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath;
+ EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath;
+ EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode;
+ EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance;
+ EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance;
+ EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance;
+ EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode;
+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;
+
+extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid;
+
+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
+ );
+
+UINTN
+DevicePathNodeLength (
+ CONST VOID *Node
+ );
+
+UINT16
+SetDevicePathNodeLength (
+ VOID *Node,
+ UINTN Length
+ );
+
+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
+ );
+
+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
+ );
+
+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
+ );
+
+#endif
diff --git a/BaseTools/Source/C/DevicePath/GNUmakefile b/BaseTools/Source/C/DevicePath/GNUmakefile
new file mode 100644
index 0000000..27f6fa1
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/GNUmakefile
@@ -0,0 +1,30 @@
+## @file
+# GNU/Linux makefile for 'DevicePath' module build.
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+ARCH ?= IA32
+MAKEROOT ?= ..
+
+APPNAME = DevicePath
+
+OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o DevicePathUtilities.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+ifeq ($(CYGWIN), CYGWIN)
+ LIBS += -L/lib/e2fsprogs -luuid
+endif
+
+ifeq ($(LINUX), Linux)
+ LIBS += -luuid
+endif
+
diff --git a/BaseTools/Source/C/DevicePath/Makefile b/BaseTools/Source/C/DevicePath/Makefile
new file mode 100644
index 0000000..a069c22
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/Makefile
@@ -0,0 +1,24 @@
+## @file
+# Windows makefile for 'DevicePath' module build.
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = DevicePath
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = DevicePath.obj UefiDevicePathLib.obj DevicePathFromText.obj DevicePathUtilities.obj
+
+#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
new file mode 100644
index 0000000..a2e0322
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
@@ -0,0 +1,298 @@
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment varibles. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "UefiDevicePathLib.h"
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+GetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibGetDevicePathSize (DevicePath);
+}
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibDuplicateDevicePath (DevicePath);
+}
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);
+}
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);
+}
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);
+}
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ )
+{
+ return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);
+}
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ )
+{
+ return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength);
+}
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+IsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);
+}
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ )
+{
+ return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ )
+{
+ return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);
+}
diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
new file mode 100644
index 0000000..e03fbd0
--- /dev/null
+++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
@@ -0,0 +1,473 @@
+/** @file
+ Definition for Device Path library.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _UEFI_DEVICE_PATH_LIB_H_
+#define _UEFI_DEVICE_PATH_LIB_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#ifdef __GNUC__
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+#include <Common/UefiBaseTypes.h>
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+#include "DevicePath.h"
+#include "DevicePathUtilities.h"
+#include "DevicePathFromText.h"
+
+
+#define IS_COMMA(a) ((a) == L',')
+#define IS_HYPHEN(a) ((a) == L'-')
+#define IS_DOT(a) ((a) == L'.')
+#define IS_LEFT_PARENTH(a) ((a) == L'(')
+#define IS_RIGHT_PARENTH(a) ((a) == L')')
+#define IS_SLASH(a) ((a) == L'/')
+#define IS_NULL(a) ((a) == L'\0')
+
+#define MAX_UINTN MAX_ADDRESS
+#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL)
+#define MAX_UINT16 ((UINT16)0xFFFF)
+#define MAX_UINT8 ((UINT8)0xFF)
+
+#define END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL))
+#define MAX_DEVICE_PATH_NODE_COUNT 1024
+#define SIZE_64KB 0x00010000
+#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
+#define ASCII_RSIZE_MAX 1000000
+#ifndef RSIZE_MAX
+#define RSIZE_MAX 1000000
+#endif
+
+//
+// Private Data structure
+//
+typedef
+EFI_DEVICE_PATH_PROTOCOL *
+(*DEVICE_PATH_FROM_TEXT) (
+ IN CHAR16 *Str
+ );
+
+typedef struct {
+ CHAR16 *Str;
+ UINTN Count;
+ UINTN Capacity;
+} POOL_PRINT;
+
+
+typedef struct {
+ CHAR16 *DevicePathNodeText;
+ DEVICE_PATH_FROM_TEXT Function;
+} DEVICE_PATH_FROM_TEXT_TABLE;
+
+typedef struct {
+ BOOLEAN ClassExist;
+ UINT8 Class;
+ BOOLEAN SubClassExist;
+ UINT8 SubClass;
+} USB_CLASS_TEXT;
+
+#define USB_CLASS_AUDIO 1
+#define USB_CLASS_CDCCONTROL 2
+#define USB_CLASS_HID 3
+#define USB_CLASS_IMAGE 6
+#define USB_CLASS_PRINTER 7
+#define USB_CLASS_MASS_STORAGE 8
+#define USB_CLASS_HUB 9
+#define USB_CLASS_CDCDATA 10
+#define USB_CLASS_SMART_CARD 11
+#define USB_CLASS_VIDEO 14
+#define USB_CLASS_DIAGNOSTIC 220
+#define USB_CLASS_WIRELESS 224
+
+#define USB_CLASS_RESERVE 254
+#define USB_SUBCLASS_FW_UPDATE 1
+#define USB_SUBCLASS_IRDA_BRIDGE 2
+#define USB_SUBCLASS_TEST 3
+
+#define RFC_1700_UDP_PROTOCOL 17
+#define RFC_1700_TCP_PROTOCOL 6
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Hid;
+ UINT32 Uid;
+ UINT32 Cid;
+ CHAR8 HidUidCidStr[3];
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 NetworkProtocol;
+ UINT16 LoginOption;
+ UINT64 Lun;
+ UINT16 TargetPortalGroupTag;
+ CHAR8 TargetName[1];
+} ISCSI_DEVICE_PATH_WITH_NAME;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEVICE_PATH_WITH_DATA;
+
+#pragma pack()
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+UefiDevicePathLibGetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibDuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ );
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ );
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibGetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ );
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibCreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+UefiDevicePathLibIsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ );
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+ EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+BOOLEAN
+IsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ );
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+UINTN
+GetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+CHAR16 *
+ConvertDeviceNodeToText (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ BOOLEAN DisplayOnly,
+ BOOLEAN AllowShortcuts
+ );
+
+CHAR16 *
+ConvertDevicePathToText (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ BOOLEAN DisplayOnly,
+ BOOLEAN AllowShortcuts
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ );
+
+
+#endif
diff --git a/BaseTools/Source/C/GNUmakefile b/BaseTools/Source/C/GNUmakefile
index 0dc7482..37421ad 100644
--- a/BaseTools/Source/C/GNUmakefile
+++ b/BaseTools/Source/C/GNUmakefile
@@ -65,11 +65,12 @@ APPLICATIONS = \
GenCrc32 \
GenVtf \
LzmaCompress \
Split \
TianoCompress \
- VolInfo
+ VolInfo \
+ DevicePath
SUBDIRS := $(LIBRARIES) $(APPLICATIONS)
$(LIBRARIES): $(MAKEROOT)/libs
$(APPLICATIONS): $(LIBRARIES) $(MAKEROOT)/bin $(VFRAUTOGEN)
diff --git a/BaseTools/Source/C/Makefile b/BaseTools/Source/C/Makefile
index 50be773..5428180 100644
--- a/BaseTools/Source/C/Makefile
+++ b/BaseTools/Source/C/Makefile
@@ -1,9 +1,9 @@
## @file
# Windows makefile for C tools build.
#
-# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
@@ -30,11 +30,12 @@ APPLICATIONS = \
GenVtf \
LzmaCompress \
Split \
TianoCompress \
VolInfo \
- VfrCompile
+ VfrCompile \
+ DevicePath
all: libs apps install
libs: $(LIBRARIES)
@echo.
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index c51b685..104a370 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -36,11 +36,11 @@ from CommonDataClass.DataClass import *
from Parsing import GetSplitValueList
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import uuid
from CommonDataClass.Exceptions import BadExpression
-
+import subprocess
## Regular expression used to find out place holders in string template
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
## Dictionary used to store file time stamp for quick re-access
gFileTimeStampCache = {} # {file path : file time stamp}
@@ -1472,11 +1472,42 @@ def AnalyzePcdExpression(Setting):
StartPos = Pos + 1
return FieldList
def ParseDevPathValue (Value):
- pass
+ DevPathList = [ "Path","HardwarePath","Pci","PcCard","MemoryMapped","VenHw","Ctrl","BMC","AcpiPath","Acpi","PciRoot",
+ "PcieRoot","Floppy","Keyboard","Serial","ParallelPort","AcpiEx","AcpiExp","AcpiAdr","Msg","Ata","Scsi",
+ "Fibre","FibreEx","I1394","USB","I2O","Infiniband","VenMsg","VenPcAnsi","VenVt100","VenVt100Plus",
+ "VenUtf8","UartFlowCtrl","SAS","SasEx","NVMe","UFS","SD","eMMC","DebugPort","MAC","IPv4","IPv6","Uart",
+ "UsbClass","UsbAudio","UsbCDCControl","UsbHID","UsbImage","UsbPrinter","UsbMassStorage","UsbHub",
+ "UsbCDCData","UsbSmartCard","UsbVideo","UsbDiagnostic","UsbWireless","UsbDeviceFirmwareUpdate",
+ "UsbIrdaBridge","UsbTestAndMeasurement","UsbWwid","Unit","iSCSI","Vlan","Uri","Bluetooth","Wi-Fi",
+ "MediaPath","HD","CDROM","VenMedia","Media","Fv","FvFile","Offset","RamDisk","VirtualDisk","VirtualCD",
+ "PersistentVirtualDisk","PersistentVirtualCD","BbsPath","BBS","Sata" ]
+ if '\\' in Value:
+ Value.replace('\\', '/').replace(' ', '')
+ for Item in Value.split('/'):
+ Key = Item.strip().split('(')[0]
+ if Key not in DevPathList:
+ pass
+
+ Cmd = 'DevicePath ' + '"' + Value + '"'
+ try:
+ p = subprocess.Popen(Cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ out, err = p.communicate()
+ except Exception, X:
+ raise BadExpression("DevicePath: %s" % (str(X)) )
+ finally:
+ subprocess._cleanup()
+ p.stdout.close()
+ p.stderr.close()
+ if err:
+ raise BadExpression("DevicePath: %s" % str(err))
+ Size = len(out.split())
+ out = ','.join(out.split())
+ return '{' + out + '}', Size
+
def ParseFieldValue (Value):
if type(Value) == type(0):
return Value, (Value.bit_length() + 7) / 8
if type(Value) <> type(''):
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 05b26a3..f9cd429 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -2060,11 +2060,11 @@ class DscBuildData(PlatformBuildClassObject):
ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
if ModuleFile in self._Modules:
continue
ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
PkgSet.update(ModuleData.Packages)
- self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
+ self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
return self._DecPcds
_Macros = property(_GetMacros)
Arch = property(_GetArch, _SetArch)
Platform = property(_GetPlatformName)
PlatformName = property(_GetPlatformName)
--
2.6.1.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Patch 2/2] BaseTools: Add DevicePath support for PCD values
2017-12-26 16:40 ` [Patch 2/2] BaseTools: Add DevicePath support for PCD values Yonghong Zhu
@ 2017-12-27 2:40 ` Gao, Liming
0 siblings, 0 replies; 4+ messages in thread
From: Gao, Liming @ 2017-12-27 2:40 UTC (permalink / raw)
To: Zhu, Yonghong, edk2-devel@lists.01.org; +Cc: Feng, YunhuaX
Yonghong:
For DevicePath definition, please define them in BaseTools\Source\C\Include\Protocol directory to align MdePkg layout.
Thanks
Liming
>-----Original Message-----
>From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
>Yonghong Zhu
>Sent: Wednesday, December 27, 2017 12:40 AM
>To: edk2-devel@lists.01.org
>Cc: Feng, YunhuaX <yunhuax.feng@intel.com>
>Subject: [edk2] [Patch 2/2] 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 <yunhuax.feng@intel.com>
>Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
>---
> BaseTools/Source/BinaryFiles.txt | 3 +-
> BaseTools/Source/C/DevicePath/DevicePath.c | 188 ++
> BaseTools/Source/C/DevicePath/DevicePath.h | 1404 ++++++++
> BaseTools/Source/C/DevicePath/DevicePathFromText.c | 3503
>++++++++++++++++++++
> BaseTools/Source/C/DevicePath/DevicePathFromText.h | 72 +
> .../Source/C/DevicePath/DevicePathUtilities.c | 2352 +++++++++++++
> .../Source/C/DevicePath/DevicePathUtilities.h | 555 ++++
> BaseTools/Source/C/DevicePath/GNUmakefile | 30 +
> BaseTools/Source/C/DevicePath/Makefile | 24 +
> BaseTools/Source/C/DevicePath/UefiDevicePathLib.c | 298 ++
> BaseTools/Source/C/DevicePath/UefiDevicePathLib.h | 473 +++
> BaseTools/Source/C/GNUmakefile | 3 +-
> BaseTools/Source/C/Makefile | 5 +-
> BaseTools/Source/Python/Common/Misc.py | 35 +-
> BaseTools/Source/Python/Workspace/DscBuildData.py | 2 +-
> 15 files changed, 8940 insertions(+), 7 deletions(-)
> create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.c
> create mode 100644 BaseTools/Source/C/DevicePath/DevicePath.h
> create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.c
> create mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.h
> create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.c
> create mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.h
> 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
>
>diff --git a/BaseTools/Source/BinaryFiles.txt
>b/BaseTools/Source/BinaryFiles.txt
>index 7b014a7..a5273d4 100644
>--- a/BaseTools/Source/BinaryFiles.txt
>+++ b/BaseTools/Source/BinaryFiles.txt
>@@ -9,11 +9,11 @@
> # [ExtraFiles.Win32] section.
> # The [CxFreeze.Win32] section is maintained by the owner of the Build
>Server who
> # must ensure that files that are required by the cx_freeze frozen binaries
>are
> # present in the Bin\Win32 directory.
> #
>-# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
>+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
> #
> # This program and the accompanying materials are licensed and made
>available under
> # the terms and conditions of the BSD License which accompanies this
>distribution.
> # The full text of the license may be found at:
> # http://opensource.org/licenses/bsd-license.php
>@@ -57,10 +57,11 @@ TianoCompress.exe
> Trim.exe
> UPT.exe
> VfrCompile.exe
> VolInfo.exe
> Pkcs7Sign.exe
>+DevicePath.exe
>
> [ExtraFiles.Win32]
> TestSigningPrivateKey.pem
> config.ini
> exception.xml
>diff --git a/BaseTools/Source/C/DevicePath/DevicePath.c
>b/BaseTools/Source/C/DevicePath/DevicePath.c
>new file mode 100644
>index 0000000..6c32ad4
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/DevicePath.c
>@@ -0,0 +1,188 @@
>+/** @file
>+ Definition for Device Path Tool.
>+
>+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+This program and the accompanying materials
>+are licensed and made available under the terms and conditions of the BSD
>License
>+which accompanies this distribution. The full text of the license may be
>found at
>+http://opensource.org/licenses/bsd-license.php
>+
>+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+
>+**/
>+
>+#include "UefiDevicePathLib.h"
>+
>+//
>+// Utility Name
>+//
>+#define UTILITY_NAME "DevicePath"
>+
>+//
>+// Utility version information
>+//
>+#define UTILITY_MAJOR_VERSION 0
>+#define UTILITY_MINOR_VERSION 1
>+
>+EFI_GUID gEfiDebugPortDevicePathGuid =
>DEVICE_PATH_MESSAGING_DEBUGPORT;
>+EFI_GUID gEfiPcAnsiGuid = EFI_PC_ANSI_GUID;
>+EFI_GUID gEfiVT100Guid = EFI_VT_100_GUID;
>+EFI_GUID gEfiVT100PlusGuid = EFI_VT_100_PLUS_GUID;
>+EFI_GUID gEfiVTUTF8Guid = EFI_VT_UTF8_GUID;
>+EFI_GUID gEfiUartDevicePathGuid = EFI_UART_DEVICE_PATH_GUID;
>+EFI_GUID gEfiSasDevicePathGuid = EFI_SAS_DEVICE_PATH_GUID;
>+EFI_GUID gEfiVirtualDiskGuid = { 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60,
>0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }};
>+EFI_GUID gEfiVirtualCdGuid = { 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64,
>0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }};
>+EFI_GUID gEfiPersistentVirtualDiskGuid = { 0x5CEA02C9, 0x4D07, 0x69D3,
>{0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }};
>+EFI_GUID gEfiPersistentVirtualCdGuid = { 0x08018188, 0x42CD, 0xBB48, {0x10,
>0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }};
>+
>+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) 2007 - 2018, Intel Corporation. All rights
>reserved.\n\n");
>+ //
>+ // Details Option
>+ //
>+ fprintf (stdout, "Options:\n");
>+ fprintf (stdout, " DevicePathString DevicePathString like as:\n"
>+ " \"PciRoot(0)/Pci(0,0)\"\n"
>+ " start with \" and end with \"\n"
>+ " not support blank in device path string.\n");
>+
>+ fprintf (stdout, " --version Show program's version number and
>exit.\n");
>+ fprintf (stdout, " -h, --help Show this help message and exit.\n");
>+}
>+
>+
>+void print_mem(void const *vp, size_t n)
>+{
>+ unsigned char const *p = vp;
>+ for (size_t i=0; i<n; i++) {
>+ printf("0x%02x ", p[i]);
>+ }
>+}
>+
>+VOID
>+Ascii2UnicodeString (
>+ CHAR8 *String,
>+ CHAR16 *UniString
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Write ascii string as unicode string format to FILE
>+
>+Arguments:
>+
>+ String - Pointer to string that is written to FILE.
>+ UniString - Pointer to unicode string
>+
>+Returns:
>+
>+ NULL
>+
>+--*/
>+{
>+ while (*String != '\0') {
>+ *(UniString++) = (CHAR16) *(String++);
>+ }
>+ //
>+ // End the UniString with a NULL.
>+ //
>+ *UniString = '\0';
>+}
>+
>+int main(int argc, CHAR8 *argv[])
>+{
>+ CHAR8 * Str;
>+ CHAR16* Str16;
>+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
>+
>+ if (argc == 1) {
>+ Error (NULL, 0, 1001, "Missing options", "No input options specified.");
>+ Usage ();
>+ return STATUS_ERROR;
>+ }
>+ if ((stricmp (argv[1], "-h") == 0) || (stricmp (argv[1], "--help") == 0)) {
>+ Version ();
>+ Usage ();
>+ return STATUS_SUCCESS;
>+ }
>+
>+ if (stricmp (argv[1], "--version") == 0) {
>+ Version ();
>+ return STATUS_SUCCESS;
>+ }
>+ Str = argv[1];
>+ if (Str == NULL) {
>+ fprintf(stderr, "Invalid option value, Device Path can't be NULL");
>+ return STATUS_ERROR;
>+ }
>+ Str16 = (CHAR16 *)malloc(1024);
>+ if (Str16 == NULL) {
>+ fprintf(stderr, "Resource, memory cannot be allcoated");
>+ return STATUS_ERROR;
>+ }
>+ Ascii2UnicodeString(Str, Str16);
>+ DevicePath = UefiDevicePathLibConvertTextToDevicePath(Str16);
>+ while (!((DevicePath->Type == END_DEVICE_PATH_TYPE) && (DevicePath-
>>SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)) )
>+ {
>+ print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1]
><< 8));
>+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)DevicePath +
>(DevicePath->Length[0] | DevicePath->Length[1] << 8));
>+ }
>+ print_mem(DevicePath, (DevicePath->Length[0] | DevicePath->Length[1]
><< 8));
>+ putchar('\n');
>+ return STATUS_SUCCESS;
>+}
>diff --git a/BaseTools/Source/C/DevicePath/DevicePath.h
>b/BaseTools/Source/C/DevicePath/DevicePath.h
>new file mode 100644
>index 0000000..389c993
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/DevicePath.h
>@@ -0,0 +1,1404 @@
>+/** @file
>+ The device path protocol as defined in UEFI 2.0.
>+
>+ The device path represents a programmatic path to a device,
>+ from a software point of view. The path must persist from boot to boot, so
>+ it can not contain things like PCI bus numbers that change from boot to boot.
>+
>+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+This program and the accompanying materials are licensed and made
>available under
>+the terms and conditions of the BSD License that accompanies this
>distribution.
>+The full text of the license may be found at
>+http://opensource.org/licenses/bsd-license.php.
>+
>+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+
>+**/
>+
>+#ifndef __EFI_DEVICE_PATH_H__
>+#define __EFI_DEVICE_PATH_H__
>+
>+#include <Guid/PcAnsi.h>
>+#include <IndustryStandard/Acpi3_0.h>
>+
>+///
>+/// 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_ADDRESS
>+///
>+typedef struct {
>+ ///
>+ /// 48bit Bluetooth device address.
>+ ///
>+ UINT8 Address[6];
>+} BLUETOOTH_ADDRESS;
>+
>+///
>+/// 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_ADDRESS
>+///
>+typedef struct {
>+ ///
>+ /// 48-bit Bluetooth device address
>+ ///
>+ UINT8 Address[6];
>+ ///
>+ /// 0x00 - Public Device Address
>+ /// 0x01 - Random Device Address
>+ ///
>+ UINT8 Type;
>+} BLUETOOTH_LE_ADDRESS;
>+
>+///
>+/// 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
>EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGIO
>N_VOLATILE
>+
>+extern EFI_GUID gEfiVirtualDiskGuid;
>+
>+///
>+/// This GUID defines a RAM Disk supporting an ISO image in volatile memory.
>+///
>+#define EFI_VIRTUAL_CD_GUID
>EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION
>_VOLATILE
>+
>+extern EFI_GUID gEfiVirtualCdGuid;
>+
>+///
>+/// This GUID defines a RAM Disk supporting a raw disk format in persistent
>memory.
>+///
>+#define EFI_PERSISTENT_VIRTUAL_DISK_GUID
>EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGIO
>N_PERSISTENT
>+
>+extern EFI_GUID gEfiPersistentVirtualDiskGuid;
>+
>+///
>+/// This GUID defines a RAM Disk supporting an ISO image in persistent
>memory.
>+///
>+#define EFI_PERSISTENT_VIRTUAL_CD_GUID
>EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION
>_PERSISTENT
>+
>+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/DevicePath/DevicePathFromText.c
>b/BaseTools/Source/C/DevicePath/DevicePathFromText.c
>new file mode 100644
>index 0000000..fb5b09b
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.c
>@@ -0,0 +1,3503 @@
>+/** @file
>+ DevicePathFromText protocol as defined in the UEFI 2.0 specification.
>+
>+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+This program and the accompanying materials
>+are licensed and made available under the terms and conditions of the BSD
>License
>+which accompanies this distribution. The full text of the license may be
>found at
>+http://opensource.org/licenses/bsd-license.php
>+
>+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+
>+**/
>+
>+#include "UefiDevicePathLib.h"
>+
>+/**
>+
>+ Duplicates a string.
>+
>+ @param Src Source string.
>+
>+ @return The duplicated string.
>+
>+**/
>+CHAR16 *
>+UefiDevicePathLibStrDuplicate (
>+ CONST CHAR16 *Src
>+ )
>+{
>+ return AllocateCopyPool (StrSize (Src), Src);
>+}
>+
>+/**
>+
>+ Get parameter in a pair of parentheses follow the given node name.
>+ For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
>+
>+ @param Str Device Path Text.
>+ @param NodeName Name of the node.
>+
>+ @return Parameter text for the node.
>+
>+**/
>+CHAR16 *
>+GetParamByNodeName (
>+ CHAR16 *Str,
>+ CHAR16 *NodeName
>+ )
>+{
>+ CHAR16 *ParamStr;
>+ CHAR16 *StrPointer;
>+ UINTN NodeNameLength;
>+ UINTN ParameterLength;
>+
>+ //
>+ // Check whether the node name matchs
>+ //
>+ NodeNameLength = StrLen (NodeName);
>+ if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {
>+ return NULL;
>+ }
>+
>+ ParamStr = Str + NodeNameLength;
>+ if (!IS_LEFT_PARENTH (*ParamStr)) {
>+ return NULL;
>+ }
>+
>+ //
>+ // Skip the found '(' and find first occurrence of ')'
>+ //
>+ ParamStr++;
>+ ParameterLength = 0;
>+ StrPointer = ParamStr;
>+ while (!IS_NULL (*StrPointer)) {
>+ if (IS_RIGHT_PARENTH (*StrPointer)) {
>+ break;
>+ }
>+ StrPointer++;
>+ ParameterLength++;
>+ }
>+ if (IS_NULL (*StrPointer)) {
>+ //
>+ // ')' not found
>+ //
>+ return NULL;
>+ }
>+
>+ ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16),
>ParamStr);
>+ if (ParamStr == NULL) {
>+ return NULL;
>+ }
>+ //
>+ // Terminate the parameter string
>+ //
>+ ParamStr[ParameterLength] = L'\0';
>+
>+ return ParamStr;
>+}
>+
>+/**
>+ Gets 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;
>+}
>+
>+/**
>+ 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;
>+}
>+
>+
>+/**
>+ 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;
>+}
>+
>+/**
>+ 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/DevicePathFromText.h
>b/BaseTools/Source/C/DevicePath/DevicePathFromText.h
>new file mode 100644
>index 0000000..4c46921
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/DevicePathFromText.h
>@@ -0,0 +1,72 @@
>+/** @file
>+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL as defined in UEFI 2.0.
>+ This protocol provides service to convert text to device paths and device
>nodes.
>+
>+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+ This program and the accompanying materials
>+ are licensed and made available under the terms and conditions of the BSD
>License
>+ which accompanies this distribution. The full text of the license may be
>found at
>+ http://opensource.org/licenses/bsd-license.php
>+
>+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+
>+**/
>+
>+#ifndef __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__
>+#define __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__
>+
>+///
>+/// Device Path From Text protocol
>+///
>+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
>+ { \
>+ 0x5c99a21, 0xc70f, 0x4ad2, {0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e }
>\
>+ }
>+
>+/**
>+ 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.
>+
>+ @retval a_pointer Pointer to the EFI device node.
>+ @retval NULL if TextDeviceNode is NULL or there was insufficient
>memory.
>+
>+**/
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL*
>+( *EFI_DEVICE_PATH_FROM_TEXT_NODE)(
>+ CONST CHAR16 *TextDeviceNode
>+ );
>+
>+
>+/**
>+ Convert text to the binary representation of a device node.
>+
>+ @param TextDeviceNode TextDevicePath points to the text
>representation of a device
>+ path. Conversion starts with the first character and continues
>+ until the first non-device path character.
>+
>+ @retval a_pointer Pointer to the allocated device path.
>+ @retval NULL if TextDeviceNode is NULL or there was insufficient
>memory.
>+
>+**/
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL*
>+( *EFI_DEVICE_PATH_FROM_TEXT_PATH)(
>+ CONST CHAR16 *TextDevicePath
>+ );
>+
>+///
>+/// This protocol converts text to device paths and device nodes.
>+///
>+typedef struct {
>+ EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode;
>+ EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath;
>+} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;
>+
>+extern EFI_GUID gEfiDevicePathFromTextProtocolGuid;
>+
>+#endif
>diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
>b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
>new file mode 100644
>index 0000000..07a58ee
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
>@@ -0,0 +1,2352 @@
>+/** @file
>+ Device Path services. The thing to remember is device paths are built out of
>+ nodes. The device path is terminated by an end node that is length
>+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is
>sizeof(EFI_DEVICE_PATH_PROTOCOL)
>+ all over this file.
>+
>+ The only place where multi-instance device paths are supported is in
>+ environment varibles. Multi-instance device paths should never be placed
>+ on a Handle.
>+
>+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+ This program and the accompanying materials
>+ are licensed and made available under the terms and conditions of the BSD
>License
>+ which accompanies this distribution. The full text of the license may be
>found at
>+ http://opensource.org/licenses/bsd-license.php.
>+
>+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+
>+**/
>+
>+#include "UefiDevicePathLib.h"
>+#include "DevicePathUtilities.h"
>+
>+#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
>+ do { \
>+ ASSERT (Expression); \
>+ if (!(Expression)) { \
>+ return Status; \
>+ } \
>+ } while (FALSE)
>+
>+
>+//
>+// 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;
>+}
>+
>+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;
>+}
>diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.h
>b/BaseTools/Source/C/DevicePath/DevicePathUtilities.h
>new file mode 100644
>index 0000000..418615f
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/DevicePathUtilities.h
>@@ -0,0 +1,555 @@
>+/** @file
>+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0.
>+ Use to create and manipulate device paths and device nodes.
>+
>+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+ This program and the accompanying materials
>+ are licensed and made available under the terms and conditions of the BSD
>License
>+ which accompanies this distribution. The full text of the license may be
>found at
>+ http://opensource.org/licenses/bsd-license.php
>+
>+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+
>+**/
>+
>+#ifndef __DEVICE_PATH_UTILITIES_H__
>+#define __DEVICE_PATH_UTILITIES_H__
>+
>+///
>+/// Device Path Utilities protocol
>+///
>+#define EFI_DEVICE_PATH_UTILITIES_GUID \
>+ { \
>+ 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72,
>0xa4 } \
>+ }
>+
>+/**
>+ Returns the size of the device path, in bytes.
>+
>+ @param DevicePath Points to the start of the EFI device path.
>+
>+ @return Size Size of the specified device path, in bytes, including the end-
>of-path tag.
>+ @retval 0 DevicePath is NULL
>+
>+**/
>+typedef
>+UINTN
>+( *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)(
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+
>+/**
>+ Create a duplicate of the specified path.
>+
>+ @param DevicePath Points to the source EFI device path.
>+
>+ @retval Pointer A pointer to the duplicate device path.
>+ @retval NULL insufficient memory or DevicePath is NULL
>+
>+**/
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL*
>+( *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)(
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+/**
>+ Create a new path by appending the second device path to the first.
>+ If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned.
>+ If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned.
>+ If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is
>returned.
>+
>+ @param Src1 Points to the first device path.
>+ @param Src2 Points to the second device path.
>+
>+ @retval Pointer A pointer to the newly created device path.
>+ @retval NULL Memory could not be allocated
>+
>+**/
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL*
>+( *EFI_DEVICE_PATH_UTILS_APPEND_PATH)(
>+ CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
>+ CONST EFI_DEVICE_PATH_PROTOCOL *Src2
>+ );
>+
>+/**
>+ Creates a new path by appending the device node to the device path.
>+ If DeviceNode is NULL then a copy of DevicePath is returned.
>+ If DevicePath is NULL then a copy of DeviceNode, followed by an end-of-
>device path device node is returned.
>+ If both DeviceNode and DevicePath are NULL then a copy of an end-of-
>device-path device node is returned.
>+
>+ @param DevicePath Points to the device path.
>+ @param DeviceNode Points to the device node.
>+
>+ @retval Pointer A pointer to the allocated device node.
>+ @retval NULL There was insufficient memory.
>+
>+**/
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL*
>+( *EFI_DEVICE_PATH_UTILS_APPEND_NODE)(
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
>+ );
>+
>+/**
>+ Creates a new path by appending the specified device path instance to the
>specified device path.
>+
>+ @param DevicePath Points to the device path. If NULL, then ignored.
>+ @param DevicePathInstance Points to the device path instance.
>+
>+ @retval Pointer A pointer to the newly created device path
>+ @retval NULL Memory could not be allocated or DevicePathInstance
>is NULL.
>+
>+**/
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL*
>+( *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)(
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
>+ );
>+
>+/**
>+ Creates a copy of the current device path instance and returns a pointer to
>the next device path
>+ instance.
>+
>+ @param DevicePathInstance On input, this holds the pointer to the
>current device path
>+ instance. On output, this holds the pointer to the next
>+ device path instance or NULL if there are no more device
>+ path instances in the device path.
>+ @param DevicePathInstanceSize On output, this holds the size of the
>device path instance,
>+ in bytes or zero, if DevicePathInstance is NULL.
>+ If NULL, then the instance size is not output.
>+
>+ @retval Pointer A pointer to the copy of the current device path
>instance.
>+ @retval NULL DevicePathInstace was NULL on entry or there was
>insufficient memory.
>+
>+**/
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL*
>+( *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)(
>+ EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
>+ UINTN *DevicePathInstanceSize
>+ );
>+
>+/**
>+ Creates a device node
>+
>+ @param NodeType NodeType is the device node type
>(EFI_DEVICE_PATH.Type) for
>+ the new device node.
>+ @param NodeSubType NodeSubType is the device node sub-type
>+ EFI_DEVICE_PATH.SubType) for the new device node.
>+ @param NodeLength NodeLength is the length of the device node
>+ (EFI_DEVICE_PATH.Length) for the new device node.
>+
>+ @retval Pointer A pointer to the newly created device node.
>+ @retval NULL NodeLength is less than
>+ the size of the header or there was insufficient memory.
>+
>+**/
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL*
>+( *EFI_DEVICE_PATH_UTILS_CREATE_NODE)(
>+ UINT8 NodeType,
>+ UINT8 NodeSubType,
>+ UINT16 NodeLength
>+);
>+
>+/**
>+ Returns whether a device path is multi-instance.
>+
>+ @param DevicePath Points to the device path. If NULL, then ignored.
>+
>+ @retval TRUE The device path has more than one instance
>+ @retval FALSE The device path is empty or contains only a single instance.
>+
>+**/
>+typedef
>+BOOLEAN
>+( *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)(
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+///
>+/// This protocol is used to creates and manipulates device paths and device
>nodes.
>+///
>+typedef struct {
>+ EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;
>+ EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath;
>+ EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath;
>+ EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode;
>+ EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE
>AppendDevicePathInstance;
>+ EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE
>GetNextDevicePathInstance;
>+ EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE
>IsDevicePathMultiInstance;
>+ EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode;
>+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;
>+
>+extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid;
>+
>+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
>+ );
>+
>+UINTN
>+DevicePathNodeLength (
>+ CONST VOID *Node
>+ );
>+
>+UINT16
>+SetDevicePathNodeLength (
>+ VOID *Node,
>+ UINTN Length
>+ );
>+
>+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
>+ );
>+
>+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
>+ );
>+
>+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
>+ );
>+
>+#endif
>diff --git a/BaseTools/Source/C/DevicePath/GNUmakefile
>b/BaseTools/Source/C/DevicePath/GNUmakefile
>new file mode 100644
>index 0000000..27f6fa1
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/GNUmakefile
>@@ -0,0 +1,30 @@
>+## @file
>+# GNU/Linux makefile for 'DevicePath' module build.
>+#
>+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+# This program and the accompanying materials
>+# are licensed and made available under the terms and conditions of the BSD
>License
>+# which accompanies this distribution. The full text of the license may be
>found at
>+# http://opensource.org/licenses/bsd-license.php
>+#
>+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+#
>+ARCH ?= IA32
>+MAKEROOT ?= ..
>+
>+APPNAME = DevicePath
>+
>+OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o
>DevicePathUtilities.o
>+
>+include $(MAKEROOT)/Makefiles/app.makefile
>+
>+LIBS = -lCommon
>+ifeq ($(CYGWIN), CYGWIN)
>+ LIBS += -L/lib/e2fsprogs -luuid
>+endif
>+
>+ifeq ($(LINUX), Linux)
>+ LIBS += -luuid
>+endif
>+
>diff --git a/BaseTools/Source/C/DevicePath/Makefile
>b/BaseTools/Source/C/DevicePath/Makefile
>new file mode 100644
>index 0000000..a069c22
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/Makefile
>@@ -0,0 +1,24 @@
>+## @file
>+# Windows makefile for 'DevicePath' module build.
>+#
>+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+# This program and the accompanying materials
>+# are licensed and made available under the terms and conditions of the BSD
>License
>+# which accompanies this distribution. The full text of the license may be
>found at
>+# http://opensource.org/licenses/bsd-license.php
>+#
>+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+#
>+!INCLUDE ..\Makefiles\ms.common
>+
>+APPNAME = DevicePath
>+
>+LIBS = $(LIB_PATH)\Common.lib
>+
>+OBJECTS = DevicePath.obj UefiDevicePathLib.obj DevicePathFromText.obj
>DevicePathUtilities.obj
>+
>+#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib
>+
>+!INCLUDE ..\Makefiles\ms.app
>+
>diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
>b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
>new file mode 100644
>index 0000000..a2e0322
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
>@@ -0,0 +1,298 @@
>+/** @file
>+ Device Path services. The thing to remember is device paths are built out of
>+ nodes. The device path is terminated by an end node that is length
>+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is
>sizeof(EFI_DEVICE_PATH_PROTOCOL)
>+ all over this file.
>+
>+ The only place where multi-instance device paths are supported is in
>+ environment varibles. Multi-instance device paths should never be placed
>+ on a Handle.
>+
>+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+ This program and the accompanying materials
>+ are licensed and made available under the terms and conditions of the BSD
>License
>+ which accompanies this distribution. The full text of the license may be
>found at
>+ http://opensource.org/licenses/bsd-license.php.
>+
>+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+
>+**/
>+
>+
>+#include "UefiDevicePathLib.h"
>+
>+/**
>+ Returns the size of a device path in bytes.
>+
>+ This function returns the size, in bytes, of the device path data structure
>+ specified by DevicePath including the end of device path node.
>+ If DevicePath is NULL or invalid, then 0 is returned.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+
>+ @retval 0 If DevicePath is NULL or invalid.
>+ @retval Others The size of a device path in bytes.
>+
>+**/
>+UINTN
>+GetDevicePathSize (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ )
>+{
>+ return UefiDevicePathLibGetDevicePathSize (DevicePath);
>+}
>+
>+/**
>+ Creates a new copy of an existing device path.
>+
>+ This function allocates space for a new copy of the device path specified by
>DevicePath.
>+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
>+ allocated, then the contents of DevicePath are copied to the newly
>allocated
>+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is
>returned.
>+ The memory for the new device path is allocated from EFI boot services
>memory.
>+ It is the responsibility of the caller to free the memory allocated.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+
>+ @retval NULL DevicePath is NULL or invalid.
>+ @retval Others A pointer to the duplicated device path.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+DuplicateDevicePath (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ )
>+{
>+ return UefiDevicePathLibDuplicateDevicePath (DevicePath);
>+}
>+
>+/**
>+ Creates a new device path by appending a second device path to a first
>device path.
>+
>+ This function creates a new device path by appending a copy of
>SecondDevicePath
>+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-
>device-path
>+ device node from SecondDevicePath is retained. The newly created device
>path is
>+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
>+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is
>ignored,
>+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
>+ SecondDevicePath are NULL, then a copy of an end-of-device-path is
>returned.
>+
>+ If there is not enough memory for the newly allocated buffer, then NULL is
>returned.
>+ The memory for the new device path is allocated from EFI boot services
>memory.
>+ It is the responsibility of the caller to free the memory allocated.
>+
>+ @param FirstDevicePath A pointer to a device path data structure.
>+ @param SecondDevicePath A pointer to a device path data structure.
>+
>+ @retval NULL If there is not enough memory for the newly allocated
>buffer.
>+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
>+ @retval Others A pointer to the new device path if success.
>+ Or a copy an end-of-device-path if both FirstDevicePath and
>SecondDevicePath are NULL.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+AppendDevicePath (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
>+ )
>+{
>+ return UefiDevicePathLibAppendDevicePath (FirstDevicePath,
>SecondDevicePath);
>+}
>+
>+/**
>+ Creates a new path by appending the device node to the device path.
>+
>+ This function creates a new device path by appending a copy of the device
>node
>+ specified by DevicePathNode to a copy of the device path specified by
>DevicePath
>+ in an allocated buffer. The end-of-device-path device node is moved after
>the
>+ end of the appended device node.
>+ If DevicePathNode is NULL then a copy of DevicePath is returned.
>+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-
>of-device
>+ path device node is returned.
>+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-
>device-path
>+ device node is returned.
>+ If there is not enough memory to allocate space for the new device path,
>then
>+ NULL is returned.
>+ The memory is allocated from EFI boot services memory. It is the
>responsibility
>+ of the caller to free the memory allocated.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+ @param DevicePathNode A pointer to a single device path node.
>+
>+ @retval NULL If there is not enough memory for the new device path.
>+ @retval Others A pointer to the new device path if success.
>+ A copy of DevicePathNode followed by an end-of-device-path
>node
>+ if both FirstDevicePath and SecondDevicePath are NULL.
>+ A copy of an end-of-device-path node if both FirstDevicePath
>+ and SecondDevicePath are NULL.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+AppendDevicePathNode (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
>+ )
>+{
>+ return UefiDevicePathLibAppendDevicePathNode (DevicePath,
>DevicePathNode);
>+}
>+
>+/**
>+ Creates a new device path by appending the specified device path instance
>to the specified device
>+ path.
>+
>+ This function creates a new device path by appending a copy of the device
>path
>+ instance specified by DevicePathInstance to a copy of the device path
>specified
>+ by DevicePath in a allocated buffer.
>+ The end-of-device-path device node is moved after the end of the
>appended device
>+ path instance and a new end-of-device-path-instance node is inserted
>between.
>+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
>+ If DevicePathInstance is NULL, then NULL is returned.
>+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
>+ If there is not enough memory to allocate space for the new device path,
>then
>+ NULL is returned.
>+ The memory is allocated from EFI boot services memory. It is the
>responsibility
>+ of the caller to free the memory allocated.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+ @param DevicePathInstance A pointer to a device path instance.
>+
>+ @return A pointer to the new device path.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+AppendDevicePathInstance (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
>+ )
>+{
>+ return UefiDevicePathLibAppendDevicePathInstance (DevicePath,
>DevicePathInstance);
>+}
>+
>+/**
>+ Creates a copy of the current device path instance and returns a pointer to
>the next device path
>+ instance.
>+
>+ This function creates a copy of the current device path instance. It also
>updates
>+ DevicePath to point to the next device path instance in the device path (or
>NULL
>+ if no more) and updates Size to hold the size of the device path instance
>copy.
>+ If DevicePath is NULL, then NULL is returned.
>+ If DevicePath points to a invalid device path, then NULL is returned.
>+ If there is not enough memory to allocate space for the new device path,
>then
>+ NULL is returned.
>+ The memory is allocated from EFI boot services memory. It is the
>responsibility
>+ of the caller to free the memory allocated.
>+ If Size is NULL, then ASSERT().
>+
>+ @param DevicePath On input, this holds the pointer to the current
>+ device path instance. On output, this holds
>+ the pointer to the next device path instance
>+ or NULL if there are no more device path
>+ instances in the device path pointer to a
>+ device path data structure.
>+ @param Size On output, this holds the size of the device
>+ path instance, in bytes or zero, if DevicePath
>+ is NULL.
>+
>+ @return A pointer to the current device path instance.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+GetNextDevicePathInstance (
>+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
>+ UINTN *Size
>+ )
>+{
>+ return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);
>+}
>+
>+/**
>+ Creates a device node.
>+
>+ This function creates a new device node in a newly allocated buffer of size
>+ NodeLength and initializes the device path node header with NodeType
>and NodeSubType.
>+ The new device path node is returned.
>+ If NodeLength is smaller than a device path header, then NULL is returned.
>+ If there is not enough memory to allocate space for the new device path,
>then
>+ NULL is returned.
>+ The memory is allocated from EFI boot services memory. It is the
>responsibility
>+ of the caller to free the memory allocated.
>+
>+ @param NodeType The device node type for the new device
>node.
>+ @param NodeSubType The device node sub-type for the new
>device node.
>+ @param NodeLength The length of the new device node.
>+
>+ @return The new device path.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+CreateDeviceNode (
>+ UINT8 NodeType,
>+ UINT8 NodeSubType,
>+ UINT16 NodeLength
>+ )
>+{
>+ return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType,
>NodeLength);
>+}
>+
>+/**
>+ Determines if a device path is single or multi-instance.
>+
>+ This function returns TRUE if the device path specified by DevicePath is
>+ multi-instance.
>+ Otherwise, FALSE is returned.
>+ If DevicePath is NULL or invalid, then FALSE is returned.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+
>+ @retval TRUE DevicePath is multi-instance.
>+ @retval FALSE DevicePath is not multi-instance, or DevicePath
>+ is NULL or invalid.
>+
>+**/
>+BOOLEAN
>+IsDevicePathMultiInstance (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ )
>+{
>+ return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);
>+}
>+
>+/**
>+ Convert text to the binary representation of a device node.
>+
>+ @param TextDeviceNode TextDeviceNode points to the text
>representation of a device
>+ node. Conversion starts with the first character and continues
>+ until the first non-device node character.
>+
>+ @return A pointer to the EFI device node or NULL if TextDeviceNode is
>NULL or there was
>+ insufficient memory or text unsupported.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+ConvertTextToDeviceNode (
>+ CONST CHAR16 *TextDeviceNode
>+ )
>+{
>+ return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);
>+}
>+
>+/**
>+ Convert text to the binary representation of a device path.
>+
>+
>+ @param TextDevicePath TextDevicePath points to the text representation
>of a device
>+ path. Conversion starts with the first character and continues
>+ until the first non-device node character.
>+
>+ @return A pointer to the allocated device path or NULL if TextDeviceNode
>is NULL or
>+ there was insufficient memory.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+ConvertTextToDevicePath (
>+ CONST CHAR16 *TextDevicePath
>+ )
>+{
>+ return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);
>+}
>diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
>b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
>new file mode 100644
>index 0000000..e03fbd0
>--- /dev/null
>+++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
>@@ -0,0 +1,473 @@
>+/** @file
>+ Definition for Device Path library.
>+
>+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>+This program and the accompanying materials
>+are licensed and made available under the terms and conditions of the BSD
>License
>+which accompanies this distribution. The full text of the license may be
>found at
>+http://opensource.org/licenses/bsd-license.php
>+
>+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
>BASIS,
>+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>EXPRESS OR IMPLIED.
>+
>+**/
>+#ifndef _UEFI_DEVICE_PATH_LIB_H_
>+#define _UEFI_DEVICE_PATH_LIB_H_
>+
>+#include <stdio.h>
>+#include <stdlib.h>
>+#include <string.h>
>+#include <ctype.h>
>+#include <assert.h>
>+#ifdef __GNUC__
>+#include <unistd.h>
>+#else
>+#include <direct.h>
>+#endif
>+#include <Common/UefiBaseTypes.h>
>+#include "CommonLib.h"
>+#include "EfiUtilityMsgs.h"
>+#include "DevicePath.h"
>+#include "DevicePathUtilities.h"
>+#include "DevicePathFromText.h"
>+
>+
>+#define IS_COMMA(a) ((a) == L',')
>+#define IS_HYPHEN(a) ((a) == L'-')
>+#define IS_DOT(a) ((a) == L'.')
>+#define IS_LEFT_PARENTH(a) ((a) == L'(')
>+#define IS_RIGHT_PARENTH(a) ((a) == L')')
>+#define IS_SLASH(a) ((a) == L'/')
>+#define IS_NULL(a) ((a) == L'\0')
>+
>+#define MAX_UINTN MAX_ADDRESS
>+#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL)
>+#define MAX_UINT16 ((UINT16)0xFFFF)
>+#define MAX_UINT8 ((UINT8)0xFF)
>+
>+#define END_DEVICE_PATH_LENGTH (sizeof
>(EFI_DEVICE_PATH_PROTOCOL))
>+#define MAX_DEVICE_PATH_NODE_COUNT 1024
>+#define SIZE_64KB 0x00010000
>+#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
>+#define ASCII_RSIZE_MAX 1000000
>+#ifndef RSIZE_MAX
>+#define RSIZE_MAX 1000000
>+#endif
>+
>+//
>+// Private Data structure
>+//
>+typedef
>+EFI_DEVICE_PATH_PROTOCOL *
>+(*DEVICE_PATH_FROM_TEXT) (
>+ IN CHAR16 *Str
>+ );
>+
>+typedef struct {
>+ CHAR16 *Str;
>+ UINTN Count;
>+ UINTN Capacity;
>+} POOL_PRINT;
>+
>+
>+typedef struct {
>+ CHAR16 *DevicePathNodeText;
>+ DEVICE_PATH_FROM_TEXT Function;
>+} DEVICE_PATH_FROM_TEXT_TABLE;
>+
>+typedef struct {
>+ BOOLEAN ClassExist;
>+ UINT8 Class;
>+ BOOLEAN SubClassExist;
>+ UINT8 SubClass;
>+} USB_CLASS_TEXT;
>+
>+#define USB_CLASS_AUDIO 1
>+#define USB_CLASS_CDCCONTROL 2
>+#define USB_CLASS_HID 3
>+#define USB_CLASS_IMAGE 6
>+#define USB_CLASS_PRINTER 7
>+#define USB_CLASS_MASS_STORAGE 8
>+#define USB_CLASS_HUB 9
>+#define USB_CLASS_CDCDATA 10
>+#define USB_CLASS_SMART_CARD 11
>+#define USB_CLASS_VIDEO 14
>+#define USB_CLASS_DIAGNOSTIC 220
>+#define USB_CLASS_WIRELESS 224
>+
>+#define USB_CLASS_RESERVE 254
>+#define USB_SUBCLASS_FW_UPDATE 1
>+#define USB_SUBCLASS_IRDA_BRIDGE 2
>+#define USB_SUBCLASS_TEST 3
>+
>+#define RFC_1700_UDP_PROTOCOL 17
>+#define RFC_1700_TCP_PROTOCOL 6
>+
>+#pragma pack(1)
>+
>+typedef struct {
>+ EFI_DEVICE_PATH_PROTOCOL Header;
>+ EFI_GUID Guid;
>+ UINT8 VendorDefinedData[1];
>+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
>+
>+typedef struct {
>+ EFI_DEVICE_PATH_PROTOCOL Header;
>+ EFI_GUID Guid;
>+ UINT8 VendorDefinedData[1];
>+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
>+
>+typedef struct {
>+ EFI_DEVICE_PATH_PROTOCOL Header;
>+ EFI_GUID Guid;
>+ UINT8 VendorDefinedData[1];
>+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;
>+
>+typedef struct {
>+ EFI_DEVICE_PATH_PROTOCOL Header;
>+ UINT32 Hid;
>+ UINT32 Uid;
>+ UINT32 Cid;
>+ CHAR8 HidUidCidStr[3];
>+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
>+
>+typedef struct {
>+ EFI_DEVICE_PATH_PROTOCOL Header;
>+ UINT16 NetworkProtocol;
>+ UINT16 LoginOption;
>+ UINT64 Lun;
>+ UINT16 TargetPortalGroupTag;
>+ CHAR8 TargetName[1];
>+} ISCSI_DEVICE_PATH_WITH_NAME;
>+
>+typedef struct {
>+ EFI_DEVICE_PATH_PROTOCOL Header;
>+ EFI_GUID Guid;
>+ UINT8 VendorDefinedData[1];
>+} VENDOR_DEVICE_PATH_WITH_DATA;
>+
>+#pragma pack()
>+
>+/**
>+ Returns the size of a device path in bytes.
>+
>+ This function returns the size, in bytes, of the device path data structure
>+ specified by DevicePath including the end of device path node.
>+ If DevicePath is NULL or invalid, then 0 is returned.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+
>+ @retval 0 If DevicePath is NULL or invalid.
>+ @retval Others The size of a device path in bytes.
>+
>+**/
>+UINTN
>+UefiDevicePathLibGetDevicePathSize (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+/**
>+ Creates a new copy of an existing device path.
>+
>+ This function allocates space for a new copy of the device path specified by
>DevicePath.
>+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
>+ allocated, then the contents of DevicePath are copied to the newly
>allocated
>+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is
>returned.
>+ The memory for the new device path is allocated from EFI boot services
>memory.
>+ It is the responsibility of the caller to free the memory allocated.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+
>+ @retval NULL DevicePath is NULL or invalid.
>+ @retval Others A pointer to the duplicated device path.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+UefiDevicePathLibDuplicateDevicePath (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+/**
>+ Creates a new device path by appending a second device path to a first
>device path.
>+
>+ This function creates a new device path by appending a copy of
>SecondDevicePath
>+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-
>device-path
>+ device node from SecondDevicePath is retained. The newly created device
>path is
>+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
>+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is
>ignored,
>+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
>+ SecondDevicePath are NULL, then a copy of an end-of-device-path is
>returned.
>+
>+ If there is not enough memory for the newly allocated buffer, then NULL is
>returned.
>+ The memory for the new device path is allocated from EFI boot services
>memory.
>+ It is the responsibility of the caller to free the memory allocated.
>+
>+ @param FirstDevicePath A pointer to a device path data structure.
>+ @param SecondDevicePath A pointer to a device path data structure.
>+
>+ @retval NULL If there is not enough memory for the newly allocated
>buffer.
>+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
>+ @retval Others A pointer to the new device path if success.
>+ Or a copy an end-of-device-path if both FirstDevicePath and
>SecondDevicePath are NULL.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+UefiDevicePathLibAppendDevicePath (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
>+ );
>+
>+/**
>+ Creates a new path by appending the device node to the device path.
>+
>+ This function creates a new device path by appending a copy of the device
>node
>+ specified by DevicePathNode to a copy of the device path specified by
>DevicePath
>+ in an allocated buffer. The end-of-device-path device node is moved after
>the
>+ end of the appended device node.
>+ If DevicePathNode is NULL then a copy of DevicePath is returned.
>+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-
>of-device
>+ path device node is returned.
>+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-
>device-path
>+ device node is returned.
>+ If there is not enough memory to allocate space for the new device path,
>then
>+ NULL is returned.
>+ The memory is allocated from EFI boot services memory. It is the
>responsibility
>+ of the caller to free the memory allocated.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+ @param DevicePathNode A pointer to a single device path node.
>+
>+ @retval NULL If there is not enough memory for the new device path.
>+ @retval Others A pointer to the new device path if success.
>+ A copy of DevicePathNode followed by an end-of-device-path
>node
>+ if both FirstDevicePath and SecondDevicePath are NULL.
>+ A copy of an end-of-device-path node if both FirstDevicePath
>+ and SecondDevicePath are NULL.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+UefiDevicePathLibAppendDevicePathNode (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
>+ );
>+
>+/**
>+ Creates a new device path by appending the specified device path instance
>to the specified device
>+ path.
>+
>+ This function creates a new device path by appending a copy of the device
>path
>+ instance specified by DevicePathInstance to a copy of the device path
>specified
>+ by DevicePath in a allocated buffer.
>+ The end-of-device-path device node is moved after the end of the
>appended device
>+ path instance and a new end-of-device-path-instance node is inserted
>between.
>+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
>+ If DevicePathInstance is NULL, then NULL is returned.
>+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
>+ If there is not enough memory to allocate space for the new device path,
>then
>+ NULL is returned.
>+ The memory is allocated from EFI boot services memory. It is the
>responsibility
>+ of the caller to free the memory allocated.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+ @param DevicePathInstance A pointer to a device path instance.
>+
>+ @return A pointer to the new device path.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+UefiDevicePathLibAppendDevicePathInstance (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
>+ );
>+
>+/**
>+ Creates a copy of the current device path instance and returns a pointer to
>the next device path
>+ instance.
>+
>+ This function creates a copy of the current device path instance. It also
>updates
>+ DevicePath to point to the next device path instance in the device path (or
>NULL
>+ if no more) and updates Size to hold the size of the device path instance
>copy.
>+ If DevicePath is NULL, then NULL is returned.
>+ If DevicePath points to a invalid device path, then NULL is returned.
>+ If there is not enough memory to allocate space for the new device path,
>then
>+ NULL is returned.
>+ The memory is allocated from EFI boot services memory. It is the
>responsibility
>+ of the caller to free the memory allocated.
>+ If Size is NULL, then ASSERT().
>+
>+ @param DevicePath On input, this holds the pointer to the current
>+ device path instance. On output, this holds
>+ the pointer to the next device path instance
>+ or NULL if there are no more device path
>+ instances in the device path pointer to a
>+ device path data structure.
>+ @param Size On output, this holds the size of the device
>+ path instance, in bytes or zero, if DevicePath
>+ is NULL.
>+
>+ @return A pointer to the current device path instance.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+UefiDevicePathLibGetNextDevicePathInstance (
>+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
>+ UINTN *Size
>+ );
>+
>+/**
>+ Creates a device node.
>+
>+ This function creates a new device node in a newly allocated buffer of size
>+ NodeLength and initializes the device path node header with NodeType
>and NodeSubType.
>+ The new device path node is returned.
>+ If NodeLength is smaller than a device path header, then NULL is returned.
>+ If there is not enough memory to allocate space for the new device path,
>then
>+ NULL is returned.
>+ The memory is allocated from EFI boot services memory. It is the
>responsibility
>+ of the caller to free the memory allocated.
>+
>+ @param NodeType The device node type for the new device
>node.
>+ @param NodeSubType The device node sub-type for the new
>device node.
>+ @param NodeLength The length of the new device node.
>+
>+ @return The new device path.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+UefiDevicePathLibCreateDeviceNode (
>+ UINT8 NodeType,
>+ UINT8 NodeSubType,
>+ UINT16 NodeLength
>+ );
>+
>+/**
>+ Determines if a device path is single or multi-instance.
>+
>+ This function returns TRUE if the device path specified by DevicePath is
>+ multi-instance.
>+ Otherwise, FALSE is returned.
>+ If DevicePath is NULL or invalid, then FALSE is returned.
>+
>+ @param DevicePath A pointer to a device path data structure.
>+
>+ @retval TRUE DevicePath is multi-instance.
>+ @retval FALSE DevicePath is not multi-instance, or DevicePath
>+ is NULL or invalid.
>+
>+**/
>+BOOLEAN
>+UefiDevicePathLibIsDevicePathMultiInstance (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+/**
>+ Convert text to the binary representation of a device node.
>+
>+ @param TextDeviceNode TextDeviceNode points to the text
>representation of a device
>+ node. Conversion starts with the first character and continues
>+ until the first non-device node character.
>+
>+ @return A pointer to the EFI device node or NULL if TextDeviceNode is
>NULL or there was
>+ insufficient memory or text unsupported.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+UefiDevicePathLibConvertTextToDeviceNode (
>+ CONST CHAR16 *TextDeviceNode
>+ );
>+
>+/**
>+ Convert text to the binary representation of a device path.
>+
>+
>+ @param TextDevicePath TextDevicePath points to the text representation
>of a device
>+ path. Conversion starts with the first character and continues
>+ until the first non-device node character.
>+
>+ @return A pointer to the allocated device path or NULL if TextDeviceNode
>is NULL or
>+ there was insufficient memory.
>+
>+**/
>+EFI_DEVICE_PATH_PROTOCOL *
>+UefiDevicePathLibConvertTextToDevicePath (
>+ CONST CHAR16 *TextDevicePath
>+ );
>+
>+EFI_DEVICE_PATH_PROTOCOL *
>+CreateDeviceNode (
>+ UINT8 NodeType,
>+ UINT8 NodeSubType,
>+ UINT16 NodeLength
>+ );
>+
>+ EFI_DEVICE_PATH_PROTOCOL *
>+CreateDeviceNode (
>+ UINT8 NodeType,
>+ UINT8 NodeSubType,
>+ UINT16 NodeLength
>+ );
>+
>+BOOLEAN
>+IsDevicePathMultiInstance (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+EFI_DEVICE_PATH_PROTOCOL *
>+GetNextDevicePathInstance (
>+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
>+ UINTN *Size
>+ );
>+
>+EFI_DEVICE_PATH_PROTOCOL *
>+AppendDevicePathInstance (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
>+ );
>+
>+EFI_DEVICE_PATH_PROTOCOL *
>+AppendDevicePathNode (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
>+ );
>+EFI_DEVICE_PATH_PROTOCOL *
>+AppendDevicePath (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
>+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
>+ );
>+
>+EFI_DEVICE_PATH_PROTOCOL *
>+DuplicateDevicePath (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+UINTN
>+GetDevicePathSize (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
>+ );
>+
>+CHAR16 *
>+ConvertDeviceNodeToText (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
>+ BOOLEAN DisplayOnly,
>+ BOOLEAN AllowShortcuts
>+ );
>+
>+CHAR16 *
>+ConvertDevicePathToText (
>+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
>+ BOOLEAN DisplayOnly,
>+ BOOLEAN AllowShortcuts
>+ );
>+
>+EFI_DEVICE_PATH_PROTOCOL *
>+ConvertTextToDeviceNode (
>+ CONST CHAR16 *TextDeviceNode
>+ );
>+
>+EFI_DEVICE_PATH_PROTOCOL *
>+ConvertTextToDevicePath (
>+ CONST CHAR16 *TextDevicePath
>+ );
>+
>+
>+#endif
>diff --git a/BaseTools/Source/C/GNUmakefile
>b/BaseTools/Source/C/GNUmakefile
>index 0dc7482..37421ad 100644
>--- a/BaseTools/Source/C/GNUmakefile
>+++ b/BaseTools/Source/C/GNUmakefile
>@@ -65,11 +65,12 @@ APPLICATIONS = \
> GenCrc32 \
> GenVtf \
> LzmaCompress \
> Split \
> TianoCompress \
>- VolInfo
>+ VolInfo \
>+ DevicePath
>
> SUBDIRS := $(LIBRARIES) $(APPLICATIONS)
>
> $(LIBRARIES): $(MAKEROOT)/libs
> $(APPLICATIONS): $(LIBRARIES) $(MAKEROOT)/bin $(VFRAUTOGEN)
>diff --git a/BaseTools/Source/C/Makefile b/BaseTools/Source/C/Makefile
>index 50be773..5428180 100644
>--- a/BaseTools/Source/C/Makefile
>+++ b/BaseTools/Source/C/Makefile
>@@ -1,9 +1,9 @@
> ## @file
> # Windows makefile for C tools build.
> #
>-# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
>+# Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
> # This program and the accompanying materials
> # are licensed and made available under the terms and conditions of the BSD
>License
> # which accompanies this distribution. The full text of the license may be
>found at
> # http://opensource.org/licenses/bsd-license.php
> #
>@@ -30,11 +30,12 @@ APPLICATIONS = \
> GenVtf \
> LzmaCompress \
> Split \
> TianoCompress \
> VolInfo \
>- VfrCompile
>+ VfrCompile \
>+ DevicePath
>
> all: libs apps install
>
> libs: $(LIBRARIES)
> @echo.
>diff --git a/BaseTools/Source/Python/Common/Misc.py
>b/BaseTools/Source/Python/Common/Misc.py
>index c51b685..104a370 100644
>--- a/BaseTools/Source/Python/Common/Misc.py
>+++ b/BaseTools/Source/Python/Common/Misc.py
>@@ -36,11 +36,11 @@ from CommonDataClass.DataClass import *
> from Parsing import GetSplitValueList
> from Common.LongFilePathSupport import OpenLongFilePath as open
> from Common.MultipleWorkspace import MultipleWorkspace as mws
> import uuid
> from CommonDataClass.Exceptions import BadExpression
>-
>+import subprocess
> ## Regular expression used to find out place holders in string template
> gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE |
>re.UNICODE)
>
> ## Dictionary used to store file time stamp for quick re-access
> gFileTimeStampCache = {} # {file path : file time stamp}
>@@ -1472,11 +1472,42 @@ def AnalyzePcdExpression(Setting):
> StartPos = Pos + 1
>
> return FieldList
>
> def ParseDevPathValue (Value):
>- pass
>+ DevPathList =
>[ "Path","HardwarePath","Pci","PcCard","MemoryMapped","VenHw","Ctrl","
>BMC","AcpiPath","Acpi","PciRoot",
>+
>"PcieRoot","Floppy","Keyboard","Serial","ParallelPort","AcpiEx","AcpiExp","A
>cpiAdr","Msg","Ata","Scsi",
>+
>"Fibre","FibreEx","I1394","USB","I2O","Infiniband","VenMsg","VenPcAnsi","V
>enVt100","VenVt100Plus",
>+
>"VenUtf8","UartFlowCtrl","SAS","SasEx","NVMe","UFS","SD","eMMC","Debu
>gPort","MAC","IPv4","IPv6","Uart",
>+
>"UsbClass","UsbAudio","UsbCDCControl","UsbHID","UsbImage","UsbPrinter"
>,"UsbMassStorage","UsbHub",
>+
>"UsbCDCData","UsbSmartCard","UsbVideo","UsbDiagnostic","UsbWireless","
>UsbDeviceFirmwareUpdate",
>+
>"UsbIrdaBridge","UsbTestAndMeasurement","UsbWwid","Unit","iSCSI","Vla
>n","Uri","Bluetooth","Wi-Fi",
>+
>"MediaPath","HD","CDROM","VenMedia","Media","Fv","FvFile","Offset","Ra
>mDisk","VirtualDisk","VirtualCD",
>+
>"PersistentVirtualDisk","PersistentVirtualCD","BbsPath","BBS","Sata" ]
>+ if '\\' in Value:
>+ Value.replace('\\', '/').replace(' ', '')
>+ for Item in Value.split('/'):
>+ Key = Item.strip().split('(')[0]
>+ if Key not in DevPathList:
>+ pass
>+
>+ Cmd = 'DevicePath ' + '"' + Value + '"'
>+ try:
>+ p = subprocess.Popen(Cmd, stdout=subprocess.PIPE,
>stderr=subprocess.PIPE, shell=True)
>+ out, err = p.communicate()
>+ except Exception, X:
>+ raise BadExpression("DevicePath: %s" % (str(X)) )
>+ finally:
>+ subprocess._cleanup()
>+ p.stdout.close()
>+ p.stderr.close()
>+ if err:
>+ raise BadExpression("DevicePath: %s" % str(err))
>+ Size = len(out.split())
>+ out = ','.join(out.split())
>+ return '{' + out + '}', Size
>+
>
> def ParseFieldValue (Value):
> if type(Value) == type(0):
> return Value, (Value.bit_length() + 7) / 8
> if type(Value) <> type(''):
>diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py
>b/BaseTools/Source/Python/Workspace/DscBuildData.py
>index 05b26a3..f9cd429 100644
>--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
>+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
>@@ -2060,11 +2060,11 @@ class DscBuildData(PlatformBuildClassObject):
> ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace,
>Arch=self._Arch)
> if ModuleFile in self._Modules:
> continue
> ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target,
>self._Toolchain]
> PkgSet.update(ModuleData.Packages)
>- self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch,
>self._Target, self._Toolchain,PkgSet)
>+ self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb,
>self._Arch, self._Target, self._Toolchain,PkgSet)
> return self._DecPcds
> _Macros = property(_GetMacros)
> Arch = property(_GetArch, _SetArch)
> Platform = property(_GetPlatformName)
> PlatformName = property(_GetPlatformName)
>--
>2.6.1.windows.1
>
>_______________________________________________
>edk2-devel mailing list
>edk2-devel@lists.01.org
>https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-12-27 2:35 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-26 16:40 [Patch 0/2] BaseTools: Add Flexible PCD Value support Yonghong Zhu
2017-12-26 16:40 ` [Patch 1/2] BaseTools: Support PCD flexible values format Yonghong Zhu
2017-12-26 16:40 ` [Patch 2/2] BaseTools: Add DevicePath support for PCD values Yonghong Zhu
2017-12-27 2:40 ` Gao, Liming
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox