from Common.Uefi.Capsule.UefiCapsuleHeader import UefiCapsuleHeaderClass\r
from Common.Uefi.Capsule.FmpCapsuleHeader import FmpCapsuleHeaderClass\r
from Common.Uefi.Capsule.FmpAuthHeader import FmpAuthHeaderClass\r
+from Common.Uefi.Capsule.CapsuleDependency import CapsuleDependencyClass\r
from Common.Edk2.Capsule.FmpPayloadHeader import FmpPayloadHeaderClass\r
\r
#\r
OpenSslOtherPublicCertFile = ConvertJsonValue (Config, 'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True)\r
OpenSslTrustedPublicCertFile = ConvertJsonValue (Config, 'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True)\r
SigningToolPath = ConvertJsonValue (Config, 'SigningToolPath', os.path.expandvars, Required = False, Default = None)\r
+ DepexExp = ConvertJsonValue (Config, 'Dependencies', str, Required = False, Default = None)\r
\r
#\r
# Read binary input file\r
OpenSslSignerPrivateCertFile,\r
OpenSslOtherPublicCertFile,\r
OpenSslTrustedPublicCertFile,\r
- SigningToolPath\r
+ SigningToolPath,\r
+ DepexExp\r
))\r
\r
def GenerateOutputJson (PayloadJsonDescriptorList):\r
"OpenSslSignerPrivateCertFile": str(PayloadDescriptor.OpenSslSignerPrivateCertFile),\r
"OpenSslOtherPublicCertFile": str(PayloadDescriptor.OpenSslOtherPublicCertFile),\r
"OpenSslTrustedPublicCertFile": str(PayloadDescriptor.OpenSslTrustedPublicCertFile),\r
- "SigningToolPath": str(PayloadDescriptor.SigningToolPath)\r
+ "SigningToolPath": str(PayloadDescriptor.SigningToolPath),\r
+ "Dependencies" : str(PayloadDescriptor.DepexExp)\r
}for PayloadDescriptor in PayloadJsonDescriptorList\r
]\r
}\r
OpenSslSignerPrivateCertFile = None,\r
OpenSslOtherPublicCertFile = None,\r
OpenSslTrustedPublicCertFile = None,\r
- SigningToolPath = None\r
+ SigningToolPath = None,\r
+ DepexExp = None\r
):\r
self.Payload = Payload\r
self.Guid = Guid\r
self.OpenSslOtherPublicCertFile = OpenSslOtherPublicCertFile\r
self.OpenSslTrustedPublicCertFile = OpenSslTrustedPublicCertFile\r
self.SigningToolPath = SigningToolPath\r
+ self.DepexExp = DepexExp\r
\r
self.UseSignTool = self.SignToolPfxFile is not None\r
self.UseOpenSsl = (self.OpenSslSignerPrivateCertFile is not None and\r
self.AnyOpenSsl = (self.OpenSslSignerPrivateCertFile is not None or\r
self.OpenSslOtherPublicCertFile is not None or\r
self.OpenSslTrustedPublicCertFile is not None)\r
+ self.UseDependency = self.DepexExp is not None\r
\r
def Validate(self, args):\r
if self.UseSignTool and self.AnyOpenSsl:\r
args.OpenSslSignerPrivateCertFile,\r
args.OpenSslOtherPublicCertFile,\r
args.OpenSslTrustedPublicCertFile,\r
- args.SigningToolPath\r
+ args.SigningToolPath,\r
+ None\r
))\r
for SinglePayloadDescriptor in PayloadDescriptorList:\r
try:\r
except:\r
print ('GenerateCapsule: error: can not encode FMP Payload Header')\r
sys.exit (1)\r
+ if SinglePayloadDescriptor.UseDependency:\r
+ CapsuleDependency.Payload = Result\r
+ CapsuleDependency.DepexExp = SinglePayloadDescriptor.DepexExp\r
+ Result = CapsuleDependency.Encode ()\r
+ if args.Verbose:\r
+ CapsuleDependency.DumpInfo ()\r
if SinglePayloadDescriptor.UseOpenSsl or SinglePayloadDescriptor.UseSignTool:\r
#\r
# Sign image with 64-bit MonotonicCount appended to end of image\r
args.OpenSslSignerPrivateCertFile,\r
args.OpenSslOtherPublicCertFile,\r
args.OpenSslTrustedPublicCertFile,\r
- args.SigningToolPath\r
+ args.SigningToolPath,\r
+ None\r
))\r
#\r
# Perform additional verification on payload descriptors\r
PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile,\r
PayloadDescriptorList[Index].OpenSslOtherPublicCertFile,\r
PayloadDescriptorList[Index].OpenSslTrustedPublicCertFile,\r
- PayloadDescriptorList[Index].SigningToolPath\r
+ PayloadDescriptorList[Index].SigningToolPath,\r
+ None\r
))\r
else:\r
PayloadDescriptorList[0].Payload = FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Payload\r
None,\r
None,\r
None,\r
+ None,\r
None\r
))\r
GUID = FmpCapsuleHeader.GetFmpCapsuleImageHeader (Index).UpdateImageTypeId\r
PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile,\r
PayloadDescriptorList[Index].OpenSslOtherPublicCertFile,\r
PayloadDescriptorList[Index].OpenSslTrustedPublicCertFile,\r
- PayloadDescriptorList[Index].SigningToolPath\r
+ PayloadDescriptorList[Index].SigningToolPath,\r
+ None\r
))\r
JsonIndex = 0\r
for SinglePayloadDescriptor in PayloadDescriptorList:\r
if args.Verbose:\r
print ('--------')\r
print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')\r
+\r
+ PayloadSignature = struct.unpack ('<I', SinglePayloadDescriptor.Payload[0:4])\r
+ if PayloadSignature != FmpPayloadHeader.Signature:\r
+ SinglePayloadDescriptor.UseDependency = True\r
+ try:\r
+ SinglePayloadDescriptor.Payload = CapsuleDependency.Decode (SinglePayloadDescriptor.Payload)\r
+ PayloadJsonDescriptorList[JsonIndex].DepexExp = CapsuleDependency.DepexExp\r
+ if args.Verbose:\r
+ print ('--------')\r
+ CapsuleDependency.DumpInfo ()\r
+ except Exception as Msg:\r
+ print ('GenerateCapsule: error: invalid dependency expression')\r
+ else:\r
+ if args.Verbose:\r
+ print ('--------')\r
+ print ('No EFI_FIRMWARE_IMAGE_DEP')\r
+\r
try:\r
SinglePayloadDescriptor.Payload = FmpPayloadHeader.Decode (SinglePayloadDescriptor.Payload)\r
PayloadJsonDescriptorList[JsonIndex].FwVersion = FmpPayloadHeader.FwVersion\r
except:\r
print ('--------')\r
print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')\r
+\r
+ PayloadSignature = struct.unpack ('<I', Result[0:4])\r
+ if PayloadSignature != FmpPayloadHeader.Signature:\r
+ try:\r
+ Result = CapsuleDependency.Decode (Result)\r
+ print ('--------')\r
+ CapsuleDependency.DumpInfo ()\r
+ except:\r
+ print ('GenerateCapsule: error: invalid dependency expression')\r
+ else:\r
+ print ('--------')\r
+ print ('No EFI_FIRMWARE_IMAGE_DEP')\r
try:\r
Result = FmpPayloadHeader.Decode (Result)\r
print ('--------')\r
FmpCapsuleHeader = FmpCapsuleHeaderClass ()\r
FmpAuthHeader = FmpAuthHeaderClass ()\r
FmpPayloadHeader = FmpPayloadHeaderClass ()\r
+ CapsuleDependency = CapsuleDependencyClass ()\r
\r
EmbeddedDriverDescriptorList = []\r
PayloadDescriptorList = []\r
--- /dev/null
+## @file\r
+# Module that encodes and decodes a capsule dependency.\r
+#\r
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+import struct\r
+import json\r
+import sys\r
+import uuid\r
+import re\r
+\r
+'''\r
+CapsuleDependency\r
+'''\r
+\r
+class OpConvert (object):\r
+ def __init__ (self):\r
+ # Opcode: (OperandSize, PackSize, PackFmt, EncodeConvert, DecodeConvert)\r
+ self._DepexOperations = {0x00: (16, 16, 's', self.Str2Guid, self.Guid2Str),\r
+ 0x01: (4, 1, 'I', self.Str2Uint, self.Uint2Str),\r
+ 0x02: (1, 0, 's', self.Str2Utf8, self.Byte2Str),\r
+ }\r
+\r
+ def Str2Uint (self, Data):\r
+ try:\r
+ Value = int (Data, 16)\r
+ except:\r
+ Message = '{Data} is not a valid integer value.'.format (Data = Data)\r
+ raise ValueError (Message)\r
+ if Value < 0 or Value > 0xFFFFFFFF:\r
+ Message = '{Data} is not an UINT32.'.format (Data = Data)\r
+ raise ValueError (Message)\r
+ return Value\r
+\r
+ def Uint2Str (self, Data):\r
+ if Data < 0 or Data > 0xFFFFFFFF:\r
+ Message = '{Data} is not an UINT32.'.format (Data = Data)\r
+ raise ValueError (Message)\r
+ return "0x{Data:08x}".format (Data = Data)\r
+\r
+ def Str2Guid (self, Data):\r
+ try:\r
+ Guid = uuid.UUID (Data)\r
+ except:\r
+ Message = '{Data} is not a valid registry format GUID value.'.format (Data = Data)\r
+ raise ValueError (Message)\r
+ return Guid.bytes_le\r
+\r
+ def Guid2Str (self, Data):\r
+ try:\r
+ Guid = uuid.UUID (bytes_le = Data)\r
+ except:\r
+ Message = '{Data} is not a valid binary format GUID value.'.format (Data = Data)\r
+ raise ValueError (Message)\r
+ return str (Guid).upper ()\r
+\r
+ def Str2Utf8 (self, Data):\r
+ if isinstance (Data, str):\r
+ return Data.encode ('utf-8')\r
+ else:\r
+ Message = '{Data} is not a valid string.'.format (Data = Data)\r
+ raise ValueError (Message)\r
+\r
+ def Byte2Str (self, Data):\r
+ if isinstance (Data, bytes):\r
+ if Data[-1:] == b'\x00':\r
+ return str (Data[:-1], 'utf-8')\r
+ else:\r
+ return str (Data, 'utf-8')\r
+ else:\r
+ Message = '{Data} is not a valid binary string.'.format (Data = Data)\r
+ raise ValueError (Message)\r
+\r
+ def OpEncode (self, Opcode, Operand = None):\r
+ BinTemp = struct.pack ('<b', Opcode)\r
+ if Opcode <= 0x02 and Operand != None:\r
+ OperandSize, PackSize, PackFmt, EncodeConvert, DecodeConvert = self._DepexOperations[Opcode]\r
+ Value = EncodeConvert (Operand)\r
+ if Opcode == 0x02:\r
+ PackSize = len (Value) + 1\r
+ BinTemp += struct.pack ('<{PackSize}{PackFmt}'.format (PackSize = PackSize, PackFmt = PackFmt), Value)\r
+ return BinTemp\r
+\r
+ def OpDecode (self, Buffer):\r
+ Opcode = struct.unpack ('<b', Buffer[0:1])[0]\r
+ if Opcode <= 0x02:\r
+ OperandSize, PackSize, PackFmt, EncodeConvert, DecodeConvert = self._DepexOperations[Opcode]\r
+ if Opcode == 0x02:\r
+ try:\r
+ PackSize = Buffer[1:].index (b'\x00') + 1\r
+ OperandSize = PackSize\r
+ except:\r
+ Message = 'CapsuleDependency: OpConvert: error: decode failed with wrong opcode/string.'\r
+ raise ValueError (Message)\r
+ try:\r
+ Operand = DecodeConvert (struct.unpack ('<{PackSize}{PackFmt}'.format (PackSize = PackSize, PackFmt = PackFmt), Buffer[1:1+OperandSize])[0])\r
+ except:\r
+ Message = 'CapsuleDependency: OpConvert: error: decode failed with unpack failure.'\r
+ raise ValueError (Message)\r
+ else:\r
+ Operand = None\r
+ OperandSize = 0\r
+ return (Opcode, Operand, OperandSize)\r
+\r
+class CapsuleDependencyClass (object):\r
+ # //**************************************************************\r
+ # // Image Attribute - Dependency\r
+ # //**************************************************************\r
+ # typedef struct {\r
+ # UINT8 Dependencies[];\r
+ # } EFI_FIRMWARE_IMAGE_DEP\r
+\r
+ # {expression operator : [precedence, opcode, type (1:unary/2:binocular)]}\r
+ _opReference = {'&&': [2, 0x03, 2],\r
+ '||': [1, 0x04, 2],\r
+ '~': [5, 0x05, 1],\r
+ '==': [3, 0x08, 2],\r
+ '>': [4, 0x09, 2],\r
+ '>=': [4, 0x0A, 2],\r
+ '<': [4, 0x0B, 2],\r
+ '<=': [4, 0x0C, 2],\r
+ }\r
+\r
+ def __init__ (self):\r
+ self.Payload = b''\r
+ self._DepexExp = None\r
+ self._DepexList = []\r
+ self._DepexDump = []\r
+ self.Depex = b''\r
+ self._Valid = False\r
+ self._DepexSize = 0\r
+ self._opReferenceReverse = {v[1] : k for k, v in self._opReference.items ()}\r
+ self.OpConverter = OpConvert ()\r
+\r
+ @property\r
+ def DepexExp (self):\r
+ return self._DepexExp\r
+\r
+ @DepexExp.setter\r
+ def DepexExp (self, DepexExp = ''):\r
+ if isinstance (DepexExp, str):\r
+ DepexExp = re.sub (r'\n',r' ',DepexExp)\r
+ DepexExp = re.sub (r'\(',r' ( ',DepexExp)\r
+ DepexExp = re.sub (r'\)',r' ) ',DepexExp)\r
+ DepexExp = re.sub (r'~',r' ~ ',DepexExp)\r
+ self._DepexList = re.findall(r"[^\s\"\']+|\"[^\"]*\"|\'[^\']*\'",DepexExp)\r
+ self._DepexExp = " ".join(self._DepexList)\r
+\r
+ else:\r
+ Msg = 'Input Depex Expression is not valid string.'\r
+ raise ValueError (Msg)\r
+\r
+ def IsValidOperator (self, op):\r
+ return op in self._opReference.keys ()\r
+\r
+ def IsValidUnaryOperator (self, op):\r
+ return op in self._opReference.keys () and self._opReference[op][2] == 1\r
+\r
+ def IsValidBinocularOperator (self, op):\r
+ return op in self._opReference.keys () and self._opReference[op][2] == 2\r
+\r
+ def IsValidGuid (self, operand):\r
+ try:\r
+ uuid.UUID (operand)\r
+ except:\r
+ return False\r
+ return True\r
+\r
+ def IsValidVersion (self, operand):\r
+ try:\r
+ Value = int (operand, 16)\r
+ if Value < 0 or Value > 0xFFFFFFFF:\r
+ return False\r
+ except:\r
+ return False\r
+ return True\r
+\r
+ def IsValidBoolean (self, operand):\r
+ try:\r
+ return operand.upper () in ['TRUE', 'FALSE']\r
+ except:\r
+ return False\r
+\r
+ def IsValidOperand (self, operand):\r
+ return self.IsValidVersion (operand) or self.IsValidGuid (operand) or self.IsValidBoolean (operand)\r
+\r
+ def IsValidString (self, operand):\r
+ return operand[0] == "\"" and operand[-1] == "\"" and len(operand) >= 2\r
+\r
+ # Check if priority of current operater is greater than pervious op\r
+ def PriorityNotGreater (self, prevOp, currOp):\r
+ return self._opReference[currOp][0] <= self._opReference[prevOp][0]\r
+\r
+ def ValidateDepex (self):\r
+ OpList = self._DepexList\r
+\r
+ i = 0\r
+ while i < len (OpList):\r
+ Op = OpList[i]\r
+\r
+ if Op == 'DECLARE':\r
+ i += 1\r
+ if i >= len (OpList):\r
+ Msg = 'No more Operand after {Op}.'.format (Op = OpList[i-1])\r
+ raise IndexError (Msg)\r
+ # Check valid string\r
+ if not self.IsValidString(OpList[i]):\r
+ Msg = '{Operand} after {Op} is not a valid expression input.'.format (Operand = OpList[i], Op = OpList[i-1])\r
+ raise ValueError (Msg)\r
+\r
+ elif Op == '(':\r
+ # Expression cannot end with (\r
+ if i == len (OpList) - 1:\r
+ Msg = 'Expression cannot end with \'(\''\r
+ raise ValueError (Msg)\r
+ # The previous op after '(' cannot be a binocular operator\r
+ if self.IsValidBinocularOperator (OpList[i+1]) :\r
+ Msg = '{Op} after \'(\' is not a valid expression input.'.format (Op = OpList[i+1])\r
+ raise ValueError (Msg)\r
+\r
+ elif Op == ')':\r
+ # Expression cannot start with )\r
+ if i == 0:\r
+ Msg = 'Expression cannot start with \')\''\r
+ raise ValueError (Msg)\r
+ # The previous op before ')' cannot be an operator\r
+ if self.IsValidOperator (OpList[i-1]):\r
+ Msg = '{Op} before \')\' is not a valid expression input.'.format (Op = OpList[i-1])\r
+ raise ValueError (Msg)\r
+ # The next op after ')' cannot be operand or unary operator\r
+ if (i + 1) < len (OpList) and (self.IsValidOperand (OpList[i+1]) or self.IsValidUnaryOperator (OpList[i+1])):\r
+ Msg = '{Op} after \')\' is not a valid expression input.'.format (Op = OpList[i+1])\r
+ raise ValueError (Msg)\r
+\r
+ elif self.IsValidOperand (Op):\r
+ # The next expression of operand cannot be operand or unary operator\r
+ if (i + 1) < len (OpList) and (self.IsValidOperand (OpList[i+1]) or self.IsValidUnaryOperator (OpList[i+1])):\r
+ Msg = '{Op} after {PrevOp} is not a valid expression input.'.format (Op = OpList[i+1], PrevOp = Op)\r
+ raise ValueError (Msg)\r
+\r
+ elif self.IsValidOperator (Op):\r
+ # The next op of operator cannot binocular operator\r
+ if (i + 1) < len (OpList) and self.IsValidBinocularOperator (OpList[i+1]):\r
+ Msg = '{Op} after {PrevOp} is not a valid expression input.'.format (Op = OpList[i+1], PrevOp = Op)\r
+ raise ValueError (Msg)\r
+ # The first op can not be binocular operator\r
+ if i == 0 and self.IsValidBinocularOperator (Op):\r
+ Msg = 'Expression cannot start with an operator {Op}.'.format (Op = Op)\r
+ raise ValueError (Msg)\r
+ # The last op can not be operator\r
+ if i == len (OpList) - 1:\r
+ Msg = 'Expression cannot ended with an operator {Op}.'.format (Op = Op)\r
+ raise ValueError (Msg)\r
+ # The next op of unary operator cannot be guid / version\r
+ if self.IsValidUnaryOperator (Op) and (self.IsValidGuid (OpList[i+1]) or self.IsValidVersion (OpList[i+1])):\r
+ Msg = '{Op} after {PrevOp} is not a valid expression input.'.format (Op = OpList[i+1], PrevOp = Op)\r
+ raise ValueError (Msg)\r
+\r
+ else:\r
+ Msg = '{Op} is not a valid expression input.'.format (Op = Op)\r
+ raise ValueError (Msg)\r
+ i += 1\r
+\r
+ def Encode (self):\r
+ # initialize\r
+ self.Depex = b''\r
+ self._DepexDump = []\r
+ OperandStack = []\r
+ OpeartorStack = []\r
+ OpList = self._DepexList\r
+\r
+ self.ValidateDepex ()\r
+\r
+ # convert\r
+ i = 0\r
+ while i < len (OpList):\r
+ Op = OpList[i]\r
+ if Op == 'DECLARE':\r
+ # This declare next expression value is a VERSION_STRING\r
+ i += 1\r
+ self.Depex += self.OpConverter.OpEncode (0x02, OpList[i][1:-1])\r
+\r
+ elif Op == '(':\r
+ OpeartorStack.append (Op)\r
+\r
+ elif Op == ')':\r
+ while (OpeartorStack and OpeartorStack[-1] != '('):\r
+ Operator = OpeartorStack.pop ()\r
+ self.Depex += self.OpConverter.OpEncode (self._opReference[Operator][1])\r
+ try:\r
+ OpeartorStack.pop () # pop out '('\r
+ except:\r
+ Msg = 'Pop out \'(\' failed, too many \')\''\r
+ raise ValueError (Msg)\r
+\r
+ elif self.IsValidGuid (Op):\r
+ if not OperandStack:\r
+ OperandStack.append (self.OpConverter.OpEncode (0x00, Op))\r
+ else:\r
+ # accroding to uefi spec 2.8, the guid/version operands is a reversed order in firmware comparison.\r
+ self.Depex += self.OpConverter.OpEncode (0x00, Op)\r
+ self.Depex += OperandStack.pop ()\r
+\r
+ elif self.IsValidVersion (Op):\r
+ if not OperandStack:\r
+ OperandStack.append (self.OpConverter.OpEncode (0x01, Op))\r
+ else:\r
+ # accroding to uefi spec 2.8, the guid/version operands is a reversed order in firmware comparison.\r
+ self.Depex += self.OpConverter.OpEncode (0x01, Op)\r
+ self.Depex += OperandStack.pop ()\r
+\r
+ elif self.IsValidBoolean (Op):\r
+ if Op.upper () == 'FALSE':\r
+ self.Depex += self.OpConverter.OpEncode (0x07)\r
+ elif Op.upper () == 'TRUE':\r
+ self.Depex += self.OpConverter.OpEncode (0x06)\r
+\r
+ elif self.IsValidOperator (Op):\r
+ while (OpeartorStack and OpeartorStack[-1] != '(' and self.PriorityNotGreater (OpeartorStack[-1], Op)):\r
+ Operator = OpeartorStack.pop ()\r
+ self.Depex += self.OpConverter.OpEncode (self._opReference[Operator][1])\r
+ OpeartorStack.append (Op)\r
+\r
+ i += 1\r
+\r
+ while OpeartorStack:\r
+ Operator = OpeartorStack.pop ()\r
+ if Operator == '(':\r
+ Msg = 'Too many \'(\'.'\r
+ raise ValueError (Msg)\r
+ self.Depex += self.OpConverter.OpEncode (self._opReference[Operator][1])\r
+ self.Depex += self.OpConverter.OpEncode (0x0D)\r
+\r
+ self._Valid = True\r
+ self._DepexSize = len (self.Depex)\r
+ return self.Depex + self.Payload\r
+\r
+ def Decode (self, Buffer):\r
+ # initialize\r
+ self.Depex = Buffer\r
+ OperandStack = []\r
+ DepexLen = 0\r
+\r
+ while True:\r
+ Opcode, Operand, OperandSize = self.OpConverter.OpDecode (Buffer[DepexLen:])\r
+ DepexLen += OperandSize + 1\r
+\r
+ if Opcode == 0x0D:\r
+ break\r
+\r
+ elif Opcode == 0x02:\r
+ if not OperandStack:\r
+ OperandStack.append ('DECLARE \"{String}\"'.format (String = Operand))\r
+ else:\r
+ PrevOperand = OperandStack.pop ()\r
+ OperandStack.append ('{Operand} DECLARE \"{String}\"'.format (Operand = PrevOperand, String = Operand))\r
+\r
+ elif Opcode in [0x00, 0x01]:\r
+ OperandStack.append (Operand)\r
+\r
+ elif Opcode == 0x06:\r
+ OperandStack.append ('TRUE')\r
+\r
+ elif Opcode == 0x07:\r
+ OperandStack.append ('FALSE')\r
+\r
+ elif self.IsValidOperator (self._opReferenceReverse[Opcode]):\r
+ Operator = self._opReferenceReverse[Opcode]\r
+ if self.IsValidUnaryOperator (self._opReferenceReverse[Opcode]) and len (OperandStack) >= 1:\r
+ Oprand = OperandStack.pop ()\r
+ OperandStack.append (' ( {Operator} {Oprand} )'.format (Operator = Operator, Oprand = Oprand))\r
+ elif self.IsValidBinocularOperator (self._opReferenceReverse[Opcode]) and len (OperandStack) >= 2:\r
+ Oprand1 = OperandStack.pop ()\r
+ Oprand2 = OperandStack.pop ()\r
+ OperandStack.append (' ( {Oprand1} {Operator} {Oprand2} )'.format (Operator = Operator, Oprand1 = Oprand1, Oprand2 = Oprand2))\r
+ else:\r
+ Msg = 'No enough Operands for {Opcode:02X}.'.format (Opcode = Opcode)\r
+ raise ValueError (Msg)\r
+\r
+ else:\r
+ Msg = '{Opcode:02X} is not a valid OpCode.'.format (Opcode = Opcode)\r
+ raise ValueError (Msg)\r
+\r
+ self.DepexExp = OperandStack[0].strip (' ')\r
+ self.Payload = Buffer[DepexLen:]\r
+ self._Valid = True\r
+ self._DepexSize = DepexLen\r
+ return self.Payload\r
+\r
+\r
+ def DumpInfo (self):\r
+ DepexLen = 0\r
+ Opcode = None\r
+ Buffer = self.Depex\r
+\r
+ if self._Valid == True:\r
+ print ('EFI_FIRMWARE_IMAGE_DEP.Dependencies = {')\r
+ while Opcode != 0x0D:\r
+ Opcode, Operand, OperandSize = self.OpConverter.OpDecode (Buffer[DepexLen:])\r
+ DepexLen += OperandSize + 1\r
+ if Operand:\r
+ print (' {Opcode:02X}, {Operand},'.format (Opcode = Opcode, Operand = Operand))\r
+ else:\r
+ print (' {Opcode:02X},'.format (Opcode = Opcode))\r
+ print ('}')\r
+\r
+ print ('sizeof (EFI_FIRMWARE_IMAGE_DEP.Dependencies) = {Size:08X}'.format (Size = self._DepexSize))\r
+ print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))\r