BaseTools: Replace StringIO.StringIO with io.BytesIO
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / CapsuleData.py
1 ## @file
2 # generate capsule
3 #
4 # Copyright (c) 2007-2018, Intel Corporation. All rights reserved.<BR>
5 #
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
10 #
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.
13 #
14
15 ##
16 # Import Modules
17 #
18 import Ffs
19 from GenFdsGlobalVariable import GenFdsGlobalVariable
20 from io import BytesIO
21 from struct import pack
22 import os
23 from Common.Misc import SaveFileOnChange
24 import uuid
25
26 ## base class for capsule data
27 #
28 #
29 class CapsuleData:
30 ## The constructor
31 #
32 # @param self The object pointer
33 def __init__(self):
34 pass
35
36 ## generate capsule data
37 #
38 # @param self The object pointer
39 def GenCapsuleSubItem(self):
40 pass
41
42 ## FFS class for capsule data
43 #
44 #
45 class CapsuleFfs (CapsuleData):
46 ## The constructor
47 #
48 # @param self The object pointer
49 #
50 def __init__(self) :
51 self.Ffs = None
52 self.FvName = None
53
54 ## generate FFS capsule data
55 #
56 # @param self The object pointer
57 # @retval string Generated file name
58 #
59 def GenCapsuleSubItem(self):
60 FfsFile = self.Ffs.GenFfs()
61 return FfsFile
62
63 ## FV class for capsule data
64 #
65 #
66 class CapsuleFv (CapsuleData):
67 ## The constructor
68 #
69 # @param self The object pointer
70 #
71 def __init__(self) :
72 self.Ffs = None
73 self.FvName = None
74 self.CapsuleName = None
75
76 ## generate FV capsule data
77 #
78 # @param self The object pointer
79 # @retval string Generated file name
80 #
81 def GenCapsuleSubItem(self):
82 if self.FvName.find('.fv') == -1:
83 if self.FvName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
84 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[self.FvName.upper()]
85 FdBuffer = BytesIO('')
86 FvObj.CapsuleName = self.CapsuleName
87 FvFile = FvObj.AddToBuffer(FdBuffer)
88 FvObj.CapsuleName = None
89 FdBuffer.close()
90 return FvFile
91 else:
92 FvFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvName)
93 return FvFile
94
95 ## FD class for capsule data
96 #
97 #
98 class CapsuleFd (CapsuleData):
99 ## The constructor
100 #
101 # @param self The object pointer
102 #
103 def __init__(self) :
104 self.Ffs = None
105 self.FdName = None
106 self.CapsuleName = None
107
108 ## generate FD capsule data
109 #
110 # @param self The object pointer
111 # @retval string Generated file name
112 #
113 def GenCapsuleSubItem(self):
114 if self.FdName.find('.fd') == -1:
115 if self.FdName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
116 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[self.FdName.upper()]
117 FdFile = FdObj.GenFd()
118 return FdFile
119 else:
120 FdFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FdName)
121 return FdFile
122
123 ## AnyFile class for capsule data
124 #
125 #
126 class CapsuleAnyFile (CapsuleData):
127 ## The constructor
128 #
129 # @param self The object pointer
130 #
131 def __init__(self) :
132 self.Ffs = None
133 self.FileName = None
134
135 ## generate AnyFile capsule data
136 #
137 # @param self The object pointer
138 # @retval string Generated file name
139 #
140 def GenCapsuleSubItem(self):
141 return self.FileName
142
143 ## Afile class for capsule data
144 #
145 #
146 class CapsuleAfile (CapsuleData):
147 ## The constructor
148 #
149 # @param self The object pointer
150 #
151 def __init__(self) :
152 self.Ffs = None
153 self.FileName = None
154
155 ## generate Afile capsule data
156 #
157 # @param self The object pointer
158 # @retval string Generated file name
159 #
160 def GenCapsuleSubItem(self):
161 return self.FileName
162
163 class CapsulePayload(CapsuleData):
164 '''Generate payload file, the header is defined below:
165 #pragma pack(1)
166 typedef struct {
167 UINT32 Version;
168 EFI_GUID UpdateImageTypeId;
169 UINT8 UpdateImageIndex;
170 UINT8 reserved_bytes[3];
171 UINT32 UpdateImageSize;
172 UINT32 UpdateVendorCodeSize;
173 UINT64 UpdateHardwareInstance; //Introduced in v2
174 } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;
175 '''
176 def __init__(self):
177 self.UiName = None
178 self.Version = None
179 self.ImageTypeId = None
180 self.ImageIndex = None
181 self.HardwareInstance = None
182 self.ImageFile = []
183 self.VendorCodeFile = []
184 self.Certificate_Guid = None
185 self.MonotonicCount = None
186 self.Existed = False
187 self.Buffer = None
188
189 def GenCapsuleSubItem(self, AuthData=[]):
190 if not self.Version:
191 self.Version = '0x00000002'
192 if not self.ImageIndex:
193 self.ImageIndex = '0x1'
194 if not self.HardwareInstance:
195 self.HardwareInstance = '0x0'
196 ImageFileSize = os.path.getsize(self.ImageFile)
197 if AuthData:
198 # the ImageFileSize need include the full authenticated info size. From first bytes of MonotonicCount to last bytes of certificate.
199 # the 32 bit is the MonotonicCount, dwLength, wRevision, wCertificateType and CertType
200 ImageFileSize += 32
201 VendorFileSize = 0
202 if self.VendorCodeFile:
203 VendorFileSize = os.path.getsize(self.VendorCodeFile)
204
205 #
206 # Fill structure
207 #
208 Guid = self.ImageTypeId.split('-')
209 Buffer = pack('=ILHHBBBBBBBBBBBBIIQ',
210 int(self.Version, 16),
211 int(Guid[0], 16),
212 int(Guid[1], 16),
213 int(Guid[2], 16),
214 int(Guid[3][-4:-2], 16),
215 int(Guid[3][-2:], 16),
216 int(Guid[4][-12:-10], 16),
217 int(Guid[4][-10:-8], 16),
218 int(Guid[4][-8:-6], 16),
219 int(Guid[4][-6:-4], 16),
220 int(Guid[4][-4:-2], 16),
221 int(Guid[4][-2:], 16),
222 int(self.ImageIndex, 16),
223 0,
224 0,
225 0,
226 ImageFileSize,
227 VendorFileSize,
228 int(self.HardwareInstance, 16)
229 )
230 if AuthData:
231 Buffer += pack('QIHH', AuthData[0], AuthData[1], AuthData[2], AuthData[3])
232 Buffer += uuid.UUID(AuthData[4]).get_bytes_le()
233
234 #
235 # Append file content to the structure
236 #
237 ImageFile = open(self.ImageFile, 'rb')
238 Buffer += ImageFile.read()
239 ImageFile.close()
240 if self.VendorCodeFile:
241 VendorFile = open(self.VendorCodeFile, 'rb')
242 Buffer += VendorFile.read()
243 VendorFile.close()
244 self.Existed = True
245 return Buffer