2 # Module that encodes and decodes a EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER with
5 # Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 class FmpCapsuleImageHeaderClass (object):
27 # /// Used to identify device firmware targeted by this update. This guid is matched by
28 # /// system firmware against ImageTypeId field within a EFI_FIRMWARE_IMAGE_DESCRIPTOR
30 # EFI_GUID UpdateImageTypeId;
33 # /// Passed as ImageIndex in call to EFI_FIRMWARE_MANAGEMENT_PROTOCOL.SetImage ()
35 # UINT8 UpdateImageIndex;
36 # UINT8 reserved_bytes[3];
39 # /// Size of the binary update image which immediately follows this structure
41 # UINT32 UpdateImageSize;
44 # /// Size of the VendorCode bytes which optionally immediately follow binary update image in the capsule
46 # UINT32 UpdateVendorCodeSize;
49 # /// The HardwareInstance to target with this update. If value is zero it means match all
50 # /// HardwareInstances. This field allows update software to target only a single device in
51 # /// cases where there are more than one device with the same ImageTypeId GUID.
52 # /// This header is outside the signed data of the Authentication Info structure and
53 # /// therefore can be modified without changing the Auth data.
55 # UINT64 UpdateHardwareInstance;
56 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;
58 # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000002
60 _StructFormat
= '<I16sB3BIIQ'
61 _StructSize
= struct
.calcsize (_StructFormat
)
63 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
= 0x00000002
67 self
.Version
= self
.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
68 self
.UpdateImageTypeId
= uuid
.UUID ('00000000-0000-0000-0000-000000000000')
69 self
.UpdateImageIndex
= 0
70 self
.UpdateImageSize
= 0
71 self
.UpdateVendorCodeSize
= 0
72 self
.UpdateHardwareInstance
= 0x0000000000000000
74 self
.VendorCodeBytes
= b
''
77 self
.UpdateImageSize
= len (self
.Payload
)
78 self
.UpdateVendorCodeSize
= len (self
.VendorCodeBytes
)
79 FmpCapsuleImageHeader
= struct
.pack (
82 self
.UpdateImageTypeId
.bytes_le
,
83 self
.UpdateImageIndex
,
86 self
.UpdateVendorCodeSize
,
87 self
.UpdateHardwareInstance
90 return FmpCapsuleImageHeader
+ self
.Payload
+ self
.VendorCodeBytes
92 def Decode (self
, Buffer
):
93 if len (Buffer
) < self
._StructSize
:
95 (Version
, UpdateImageTypeId
, UpdateImageIndex
, r0
, r1
, r2
, UpdateImageSize
, UpdateVendorCodeSize
, UpdateHardwareInstance
) = \
98 Buffer
[0:self
._StructSize
]
101 if Version
< self
.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
:
103 if UpdateImageIndex
< 1:
105 if UpdateImageSize
+ UpdateVendorCodeSize
!= len (Buffer
[self
._StructSize
:]):
108 self
.Version
= Version
109 self
.UpdateImageTypeId
= uuid
.UUID (bytes_le
= UpdateImageTypeId
)
110 self
.UpdateImageIndex
= UpdateImageIndex
111 self
.UpdateImageSize
= UpdateImageSize
112 self
.UpdateVendorCodeSize
= UpdateVendorCodeSize
113 self
.UpdateHardwareInstance
= UpdateHardwareInstance
114 self
.Payload
= Buffer
[self
._StructSize
:self
._StructSize
+ UpdateImageSize
]
115 self
.VendorCodeBytes
= Buffer
[self
._StructSize
+ UpdateImageSize
:]
117 return Buffer
[self
._StructSize
:]
122 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format (Version
= self
.Version
))
123 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format (UpdateImageTypeId
= str(self
.UpdateImageTypeId
).upper()))
124 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format (UpdateImageIndex
= self
.UpdateImageIndex
))
125 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}'.format (UpdateImageSize
= self
.UpdateImageSize
))
126 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}'.format (UpdateVendorCodeSize
= self
.UpdateVendorCodeSize
))
127 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format (UpdateHardwareInstance
= self
.UpdateHardwareInstance
))
128 print ('sizeof (Payload) = {Size:08X}'.format (Size
= len (self
.Payload
)))
129 print ('sizeof (VendorCodeBytes) = {Size:08X}'.format (Size
= len (self
.VendorCodeBytes
)))
131 class FmpCapsuleHeaderClass (object):
136 # /// The number of drivers included in the capsule and the number of corresponding
137 # /// offsets stored in ItemOffsetList array.
139 # UINT16 EmbeddedDriverCount;
142 # /// The number of payload items included in the capsule and the number of
143 # /// corresponding offsets stored in the ItemOffsetList array.
145 # UINT16 PayloadItemCount;
148 # /// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount]
149 # /// containing offsets of each of the drivers and payload items contained within the capsule
151 # // UINT64 ItemOffsetList[];
152 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;
154 # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION 0x00000001
155 _StructFormat
= '<IHH'
156 _StructSize
= struct
.calcsize (_StructFormat
)
158 _ItemOffsetFormat
= '<Q'
159 _ItemOffsetSize
= struct
.calcsize (_ItemOffsetFormat
)
161 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION
= 0x00000001
165 self
.Version
= self
.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION
166 self
.EmbeddedDriverCount
= 0
167 self
.PayloadItemCount
= 0
168 self
._ItemOffsetList
= []
169 self
._EmbeddedDriverList
= []
170 self
._PayloadList
= []
171 self
._FmpCapsuleImageHeaderList
= []
173 def AddEmbeddedDriver (self
, EmbeddedDriver
):
174 self
._EmbeddedDriverList
.append (EmbeddedDriver
)
176 def GetEmbeddedDriver (self
, Index
):
177 if Index
> len (self
._EmbeddedDriverList
):
179 return self
._EmbeddedDriverList
[Index
]
181 def AddPayload (self
, UpdateImageTypeId
, Payload
= b
'', VendorCodeBytes
= b
'', HardwareInstance
= 0):
182 self
._PayloadList
.append ((UpdateImageTypeId
, Payload
, VendorCodeBytes
, HardwareInstance
))
184 def GetFmpCapsuleImageHeader (self
, Index
):
185 if Index
>= len (self
._FmpCapsuleImageHeaderList
):
187 return self
._FmpCapsuleImageHeaderList
[Index
]
190 self
.EmbeddedDriverCount
= len (self
._EmbeddedDriverList
)
191 self
.PayloadItemCount
= len (self
._PayloadList
)
193 FmpCapsuleHeader
= struct
.pack (
196 self
.EmbeddedDriverCount
,
197 self
.PayloadItemCount
201 Offset
= self
._StructSize
+ (self
.EmbeddedDriverCount
+ self
.PayloadItemCount
) * self
._ItemOffsetSize
202 for EmbeddedDriver
in self
._EmbeddedDriverList
:
203 FmpCapsuleData
= FmpCapsuleData
+ EmbeddedDriver
204 self
._ItemOffsetList
.append (Offset
)
205 Offset
= Offset
+ len (EmbeddedDriver
)
207 for (UpdateImageTypeId
, Payload
, VendorCodeBytes
, HardwareInstance
) in self
._PayloadList
:
208 FmpCapsuleImageHeader
= FmpCapsuleImageHeaderClass ()
209 FmpCapsuleImageHeader
.UpdateImageTypeId
= UpdateImageTypeId
210 FmpCapsuleImageHeader
.UpdateImageIndex
= Index
211 FmpCapsuleImageHeader
.Payload
= Payload
212 FmpCapsuleImageHeader
.VendorCodeBytes
= VendorCodeBytes
213 FmpCapsuleImageHeader
.UpdateHardwareInstance
= HardwareInstance
214 FmpCapsuleImage
= FmpCapsuleImageHeader
.Encode ()
215 FmpCapsuleData
= FmpCapsuleData
+ FmpCapsuleImage
217 self
._ItemOffsetList
.append (Offset
)
218 self
._FmpCapsuleImageHeaderList
.append (FmpCapsuleImageHeader
)
220 Offset
= Offset
+ len (FmpCapsuleImage
)
223 for Offset
in self
._ItemOffsetList
:
224 FmpCapsuleHeader
= FmpCapsuleHeader
+ struct
.pack (self
._ItemOffsetFormat
, Offset
)
227 return FmpCapsuleHeader
+ FmpCapsuleData
229 def Decode (self
, Buffer
):
230 if len (Buffer
) < self
._StructSize
:
232 (Version
, EmbeddedDriverCount
, PayloadItemCount
) = \
235 Buffer
[0:self
._StructSize
]
237 if Version
< self
.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION
:
240 self
.Version
= Version
241 self
.EmbeddedDriverCount
= EmbeddedDriverCount
242 self
.PayloadItemCount
= PayloadItemCount
243 self
._ItemOffsetList
= []
244 self
._EmbeddedDriverList
= []
245 self
._PayloadList
= []
246 self
._FmpCapsuleImageHeaderList
= []
249 # Parse the ItemOffsetList values
251 Offset
= self
._StructSize
252 for Index
in range (0, EmbeddedDriverCount
+ PayloadItemCount
):
253 ItemOffset
= struct
.unpack (self
._ItemOffsetFormat
, Buffer
[Offset
:Offset
+ self
._ItemOffsetSize
])[0]
254 if ItemOffset
>= len (Buffer
):
256 self
._ItemOffsetList
.append (ItemOffset
)
257 Offset
= Offset
+ self
._ItemOffsetSize
258 Result
= Buffer
[Offset
:]
261 # Parse the EmbeddedDrivers
263 for Index
in range (0, EmbeddedDriverCount
):
264 Offset
= self
._ItemOffsetList
[Index
]
265 if Index
< (len (self
._ItemOffsetList
) - 1):
266 Length
= self
._ItemOffsetList
[Index
+ 1] - Offset
268 Length
= len (Buffer
) - Offset
269 self
.AddEmbeddedDriver (Buffer
[Offset
:Offset
+ Length
])
272 # Parse the Payloads that are FMP Capsule Images
274 for Index
in range (EmbeddedDriverCount
, EmbeddedDriverCount
+ PayloadItemCount
):
275 Offset
= self
._ItemOffsetList
[Index
]
276 if Index
< (len (self
._ItemOffsetList
) - 1):
277 Length
= self
._ItemOffsetList
[Index
+ 1] - Offset
279 Length
= len (Buffer
) - Offset
280 FmpCapsuleImageHeader
= FmpCapsuleImageHeaderClass ()
281 FmpCapsuleImageHeader
.Decode (Buffer
[Offset
:Offset
+ Length
])
283 FmpCapsuleImageHeader
.UpdateImageTypeId
,
284 FmpCapsuleImageHeader
.Payload
,
285 FmpCapsuleImageHeader
.VendorCodeBytes
287 self
._FmpCapsuleImageHeaderList
.append (FmpCapsuleImageHeader
)
295 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format (Version
= self
.Version
))
296 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount
= self
.EmbeddedDriverCount
))
297 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}'.format (PayloadItemCount
= self
.PayloadItemCount
))
298 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ')
299 for Offset
in self
._ItemOffsetList
:
300 print (' {Offset:016X}'.format (Offset
= Offset
))
301 for FmpCapsuleImageHeader
in self
._FmpCapsuleImageHeaderList
:
302 FmpCapsuleImageHeader
.DumpInfo ()