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