--- /dev/null
+## @file\r
+# Module that encodes and decodes a EFI_CAPSULE_HEADER with a payload\r
+#\r
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+'''\r
+UefiCapsuleHeader\r
+'''\r
+\r
+import struct\r
+import uuid\r
+\r
+class UefiCapsuleHeaderClass (object):\r
+ # typedef struct {\r
+ # ///\r
+ # /// A GUID that defines the contents of a capsule.\r
+ # ///\r
+ # EFI_GUID CapsuleGuid;\r
+ # ///\r
+ # /// The size of the capsule header. This may be larger than the size of\r
+ # /// the EFI_CAPSULE_HEADER since CapsuleGuid may imply\r
+ # /// extended header entries\r
+ # ///\r
+ # UINT32 HeaderSize;\r
+ # ///\r
+ # /// Bit-mapped list describing the capsule attributes. The Flag values\r
+ # /// of 0x0000 - 0xFFFF are defined by CapsuleGuid. Flag values\r
+ # /// of 0x10000 - 0xFFFFFFFF are defined by this specification\r
+ # ///\r
+ # UINT32 Flags;\r
+ # ///\r
+ # /// Size in bytes of the capsule.\r
+ # ///\r
+ # UINT32 CapsuleImageSize;\r
+ # } EFI_CAPSULE_HEADER;\r
+ #\r
+ # #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000\r
+ # #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000\r
+ # #define CAPSULE_FLAGS_INITIATE_RESET 0x00040000\r
+ #\r
+ _StructFormat = '<16sIIII'\r
+ _StructSize = struct.calcsize (_StructFormat)\r
+\r
+ EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID = uuid.UUID ('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')\r
+\r
+ _CAPSULE_FLAGS_PERSIST_ACROSS_RESET = 0x00010000\r
+ _CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE = 0x00020000\r
+ _CAPSULE_FLAGS_INITIATE_RESET = 0x00040000\r
+\r
+ def __init__ (self):\r
+ self._Valid = False\r
+ self.CapsuleGuid = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID\r
+ self.HeaderSize = self._StructSize\r
+ self.OemFlags = 0x0000\r
+ self.PersistAcrossReset = False\r
+ self.PopulateSystemTable = False\r
+ self.InitiateReset = False\r
+ self.CapsuleImageSize = self.HeaderSize\r
+ self.Payload = b''\r
+\r
+ def Encode (self):\r
+ Flags = self.OemFlags\r
+ if self.PersistAcrossReset:\r
+ Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET\r
+ if self.PopulateSystemTable:\r
+ Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE\r
+ if self.InitiateReset:\r
+ Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET\r
+\r
+ self.CapsuleImageSize = self.HeaderSize + len (self.Payload)\r
+\r
+ UefiCapsuleHeader = struct.pack (\r
+ self._StructFormat,\r
+ self.CapsuleGuid.bytes_le,\r
+ self.HeaderSize,\r
+ Flags,\r
+ self.CapsuleImageSize,\r
+ 0\r
+ )\r
+ self._Valid = True\r
+ return UefiCapsuleHeader + self.Payload\r
+\r
+ def Decode (self, Buffer):\r
+ if len (Buffer) < self._StructSize:\r
+ raise ValueError\r
+ (CapsuleGuid, HeaderSize, Flags, CapsuleImageSize, Reserved) = \\r
+ struct.unpack (\r
+ self._StructFormat,\r
+ Buffer[0:self._StructSize]\r
+ )\r
+ if HeaderSize < self._StructSize:\r
+ raise ValueError\r
+ if CapsuleImageSize != len (Buffer):\r
+ raise ValueError\r
+ self.CapsuleGuid = uuid.UUID (bytes_le = CapsuleGuid)\r
+ self.HeaderSize = HeaderSize\r
+ self.OemFlags = Flags & 0xffff\r
+ self.PersistAcrossReset = (Flags & self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0\r
+ self.PopulateSystemTable = (Flags & self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0\r
+ self.InitiateReset = (Flags & self._CAPSULE_FLAGS_INITIATE_RESET) != 0\r
+ self.CapsuleImageSize = CapsuleImageSize\r
+ self.Payload = Buffer[self.HeaderSize:]\r
+\r
+ self._Valid = True\r
+ return self.Payload\r
+\r
+ def DumpInfo (self):\r
+ if not self._Valid:\r
+ raise ValueError\r
+ Flags = self.OemFlags\r
+ if self.PersistAcrossReset:\r
+ Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET\r
+ if self.PopulateSystemTable:\r
+ Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE\r
+ if self.InitiateReset:\r
+ Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET\r
+ print ('EFI_CAPSULE_HEADER.CapsuleGuid = {Guid}'.format (Guid = str(self.CapsuleGuid).upper()))\r
+ print ('EFI_CAPSULE_HEADER.HeaderSize = {Size:08X}'.format (Size = self.HeaderSize))\r
+ print ('EFI_CAPSULE_HEADER.Flags = {Flags:08X}'.format (Flags = Flags))\r
+ print (' OEM Flags = {Flags:04X}'.format (Flags = self.OemFlags))\r
+ if self.PersistAcrossReset:\r
+ print (' CAPSULE_FLAGS_PERSIST_ACROSS_RESET')\r
+ if self.PopulateSystemTable:\r
+ print (' CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE')\r
+ if self.InitiateReset:\r
+ print (' CAPSULE_FLAGS_INITIATE_RESET')\r
+ print ('EFI_CAPSULE_HEADER.CapsuleImageSize = {Size:08X}'.format (Size = self.CapsuleImageSize))\r
+ print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))\r