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
if CapsuleImageSize != len (Buffer):
raise ValueError
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)))
|