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