1## @file 2# Module that encodes and decodes a EFI_CAPSULE_HEADER with a payload 3# 4# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR> 5# SPDX-License-Identifier: BSD-2-Clause-Patent 6# 7 8''' 9UefiCapsuleHeader 10''' 11 12import struct 13import uuid 14 15class UefiCapsuleHeaderClass (object): 16 # typedef struct { 17 # /// 18 # /// A GUID that defines the contents of a capsule. 19 # /// 20 # EFI_GUID CapsuleGuid; 21 # /// 22 # /// The size of the capsule header. This may be larger than the size of 23 # /// the EFI_CAPSULE_HEADER since CapsuleGuid may imply 24 # /// extended header entries 25 # /// 26 # UINT32 HeaderSize; 27 # /// 28 # /// Bit-mapped list describing the capsule attributes. The Flag values 29 # /// of 0x0000 - 0xFFFF are defined by CapsuleGuid. Flag values 30 # /// of 0x10000 - 0xFFFFFFFF are defined by this specification 31 # /// 32 # UINT32 Flags; 33 # /// 34 # /// Size in bytes of the capsule. 35 # /// 36 # UINT32 CapsuleImageSize; 37 # } EFI_CAPSULE_HEADER; 38 # 39 # #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 40 # #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 41 # #define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 42 # 43 _StructFormat = '<16sIIII' 44 _StructSize = struct.calcsize (_StructFormat) 45 46 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID = uuid.UUID ('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A') 47 48 _CAPSULE_FLAGS_PERSIST_ACROSS_RESET = 0x00010000 49 _CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE = 0x00020000 50 _CAPSULE_FLAGS_INITIATE_RESET = 0x00040000 51 52 def __init__ (self): 53 self._Valid = False 54 self.CapsuleGuid = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID 55 self.HeaderSize = self._StructSize 56 self.OemFlags = 0x0000 57 self.PersistAcrossReset = False 58 self.PopulateSystemTable = False 59 self.InitiateReset = False 60 self.CapsuleImageSize = self.HeaderSize 61 self.Payload = b'' 62 63 def Encode (self): 64 Flags = self.OemFlags 65 if self.PersistAcrossReset: 66 Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET 67 if self.PopulateSystemTable: 68 Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 69 if self.InitiateReset: 70 Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET 71 72 self.CapsuleImageSize = self.HeaderSize + len (self.Payload) 73 74 UefiCapsuleHeader = struct.pack ( 75 self._StructFormat, 76 self.CapsuleGuid.bytes_le, 77 self.HeaderSize, 78 Flags, 79 self.CapsuleImageSize, 80 0 81 ) 82 self._Valid = True 83 return UefiCapsuleHeader + self.Payload 84 85 def Decode (self, Buffer): 86 if len (Buffer) < self._StructSize: 87 raise ValueError 88 (CapsuleGuid, HeaderSize, Flags, CapsuleImageSize, Reserved) = \ 89 struct.unpack ( 90 self._StructFormat, 91 Buffer[0:self._StructSize] 92 ) 93 if HeaderSize < self._StructSize: 94 raise ValueError 95 if CapsuleImageSize != len (Buffer): 96 raise ValueError 97 self.CapsuleGuid = uuid.UUID (bytes_le = CapsuleGuid) 98 self.HeaderSize = HeaderSize 99 self.OemFlags = Flags & 0xffff 100 self.PersistAcrossReset = (Flags & self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0 101 self.PopulateSystemTable = (Flags & self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 102 self.InitiateReset = (Flags & self._CAPSULE_FLAGS_INITIATE_RESET) != 0 103 self.CapsuleImageSize = CapsuleImageSize 104 self.Payload = Buffer[self.HeaderSize:] 105 106 self._Valid = True 107 return self.Payload 108 109 def DumpInfo (self): 110 if not self._Valid: 111 raise ValueError 112 Flags = self.OemFlags 113 if self.PersistAcrossReset: 114 Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET 115 if self.PopulateSystemTable: 116 Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 117 if self.InitiateReset: 118 Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET 119 print ('EFI_CAPSULE_HEADER.CapsuleGuid = {Guid}'.format (Guid = str(self.CapsuleGuid).upper())) 120 print ('EFI_CAPSULE_HEADER.HeaderSize = {Size:08X}'.format (Size = self.HeaderSize)) 121 print ('EFI_CAPSULE_HEADER.Flags = {Flags:08X}'.format (Flags = Flags)) 122 print (' OEM Flags = {Flags:04X}'.format (Flags = self.OemFlags)) 123 if self.PersistAcrossReset: 124 print (' CAPSULE_FLAGS_PERSIST_ACROSS_RESET') 125 if self.PopulateSystemTable: 126 print (' CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE') 127 if self.InitiateReset: 128 print (' CAPSULE_FLAGS_INITIATE_RESET') 129 print ('EFI_CAPSULE_HEADER.CapsuleImageSize = {Size:08X}'.format (Size = self.CapsuleImageSize)) 130 print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload))) 131