1 /*
2 * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
3 * Seth Liu 2017.03.01
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7 #include "RKImage.h"
8
GetVersion()9 UINT CRKImage::GetVersion()
10 {
11 return m_version;
12 }
GetMergeVersion()13 UINT CRKImage::GetMergeVersion()
14 {
15 return m_mergeVersion;
16 }
GetReleaseTime()17 STRUCT_RKTIME CRKImage::GetReleaseTime()
18 {
19 return m_releaseTime;
20 }
GetSupportDevice()21 ENUM_RKDEVICE_TYPE CRKImage::GetSupportDevice()
22 {
23 return m_supportDevice;
24 }
GetOsType()25 ENUM_OS_TYPE CRKImage::GetOsType()
26 {
27 UINT *pOsType;
28 pOsType = (UINT *)&m_reserved[4];
29 return (ENUM_OS_TYPE)*pOsType;
30 }
31
GetBackupSize()32 USHORT CRKImage::GetBackupSize()
33 {
34 USHORT *pBackupSize;
35 pBackupSize = (USHORT *)&m_reserved[12];
36 return *pBackupSize;
37 }
GetBootOffset()38 UINT CRKImage::GetBootOffset()
39 {
40 return m_bootOffset;
41 }
GetBootSize()42 UINT CRKImage::GetBootSize()
43 {
44 return m_bootSize;
45 }
GetFWOffset()46 UINT CRKImage::GetFWOffset()
47 {
48 return m_fwOffset;
49 }
GetFWSize()50 long long CRKImage::GetFWSize()
51 {
52 return m_fwSize;
53 }
SaveBootFile(string filename)54 bool CRKImage::SaveBootFile(string filename)
55 {
56 FILE *file = NULL;
57 int iRead;
58 file = fopen(filename.c_str(), "wb+");
59 if (!file) {
60 return false;
61 }
62 BYTE buffer[1024];
63 DWORD dwBufferSize = 1024;
64 DWORD dwBootSize = m_bootSize;
65 DWORD dwReadSize;
66 fseek(m_pFile, m_bootOffset, SEEK_SET);
67 do {
68 dwReadSize = (dwBootSize >= 1024) ? dwBufferSize : dwBootSize;
69 iRead = fread(buffer, 1, dwReadSize, m_pFile);
70 if (iRead != (int)dwReadSize) {
71 fclose(file);
72 return false;
73 }
74 fwrite(buffer, 1, dwReadSize, file);
75 dwBootSize -= dwReadSize;
76 } while(dwBootSize > 0);
77 fclose(file);
78 return true;
79 }
SaveFWFile(string filename)80 bool CRKImage::SaveFWFile(string filename)
81 {
82 FILE *file = NULL;
83 int iRead;
84 file = fopen(filename.c_str(), "wb+");
85 if (!file) {
86 return false;
87 }
88 BYTE buffer[1024];
89 DWORD dwBufferSize = 1024;
90 long long dwFWSize = m_fwSize;
91 DWORD dwReadSize;
92 fseeko(m_pFile, m_fwOffset, SEEK_SET);
93 do {
94 dwReadSize = (dwFWSize >= 1024) ? dwBufferSize : dwFWSize;
95 iRead = fread(buffer, 1, dwReadSize, m_pFile);
96 if (iRead != (int)dwReadSize) {
97 fclose(file);
98 return false;
99 }
100 fwrite(buffer, 1, dwReadSize, file);
101 dwFWSize -= dwReadSize;
102 } while (dwFWSize > 0);
103 fclose(file);
104 return true;
105 }
GetData(long long dwOffset,DWORD dwSize,PBYTE lpBuffer)106 bool CRKImage::GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer)
107 {
108 if ( (dwOffset < 0) || (dwSize == 0) ) {
109 return false;
110 }
111 if ( dwOffset+dwSize > m_fileSize) {
112 return false;
113 }
114 fseeko(m_pFile, dwOffset, SEEK_SET);
115 UINT uiActualRead;
116 uiActualRead = fread(lpBuffer,1, dwSize, m_pFile);
117 if (dwSize != uiActualRead){
118 return false;
119 }
120 return true;
121 }
GetReservedData(PBYTE & lpData,USHORT & usSize)122 void CRKImage::GetReservedData(PBYTE &lpData, USHORT &usSize)
123 {
124 lpData = m_reserved;
125 usSize = IMAGE_RESERVED_SIZE;
126 }
127
CRKImage(string filename,bool & bCheck)128 CRKImage::CRKImage(string filename, bool &bCheck)
129 {
130 Version.setContainer(this);
131 Version.getter(&CRKImage::GetVersion);
132 MergeVersion.setContainer(this);
133 MergeVersion.getter(&CRKImage::GetMergeVersion);
134 ReleaseTime.setContainer(this);
135 ReleaseTime.getter(&CRKImage::GetReleaseTime);
136 SupportDevice.setContainer(this);
137 SupportDevice.getter(&CRKImage::GetSupportDevice);
138 OsType.setContainer(this);
139 OsType.getter(&CRKImage::GetOsType);
140 BackupSize.setContainer(this);
141 BackupSize.getter(&CRKImage::GetBackupSize);
142 BootOffset.setContainer(this);
143 BootOffset.getter(&CRKImage::GetBootOffset);
144 BootSize.setContainer(this);
145 BootSize.getter(&CRKImage::GetBootSize);
146 FWOffset.setContainer(this);
147 FWOffset.getter(&CRKImage::GetFWOffset);
148 FWSize.setContainer(this);
149 FWSize.getter(&CRKImage::GetFWSize);
150 SignFlag.setContainer(this);
151 SignFlag.getter(&CRKImage::GetSignFlag);
152 struct stat statBuf;
153 m_bootObject = NULL;
154 m_pFile = NULL;
155 m_bSignFlag = false;
156
157 m_signMd5Size = 0;
158 memset(m_md5, 0, 32);
159 memset(m_signMd5, 0, 256);
160
161 char szName[256];
162 strcpy(szName, filename.c_str());
163 if(stat(szName, &statBuf) < 0) {
164 bCheck = false;
165 return;
166 }
167 if (S_ISDIR(statBuf.st_mode)) {
168 bCheck = false;
169 return;
170 }
171 m_fileSize = statBuf.st_size;
172
173 bool bOnlyBootFile=false;
174 transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower);
175 if (filename.find(".bin") != string::npos) {
176 bOnlyBootFile = true;
177 }
178
179 m_pFile = fopen(szName, "rb");
180 if (!m_pFile) {
181 bCheck = false;
182 return;
183 }
184
185 int nMd5DataSize, iRead;
186 long long ulFwSize;
187 STRUCT_RKIMAGE_HEAD imageHead;
188 if (!bOnlyBootFile) {
189 fseeko(m_pFile, 0, SEEK_SET);
190 iRead = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile);
191 if (iRead != sizeof(STRUCT_RKIMAGE_HEAD)) {
192 bCheck = false;
193 return;
194 }
195 if ( imageHead.uiTag != 0x57464B52 ) {
196 bCheck = false;
197 return;
198 }
199 if ((imageHead.reserved[14] == 'H') && (imageHead.reserved[15] == 'I')) {
200 ulFwSize = *((DWORD *)(&imageHead.reserved[16]));
201 ulFwSize <<= 32;
202 ulFwSize += imageHead.dwFWOffset;
203 ulFwSize += imageHead.dwFWSize;
204 } else
205 ulFwSize = imageHead.dwFWOffset + imageHead.dwFWSize;
206 nMd5DataSize = GetImageSize() - ulFwSize;
207 if (nMd5DataSize >= 160) {
208 m_bSignFlag = true;
209 m_signMd5Size = nMd5DataSize - 32;
210 fseeko(m_pFile, ulFwSize, SEEK_SET);
211 iRead = fread(m_md5, 1, 32, m_pFile);
212 if (iRead != 32) {
213 bCheck = false;
214 return;
215 }
216 iRead = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile);
217 if (iRead != (nMd5DataSize - 32)) {
218 bCheck = false;
219 return;
220 }
221 } else {
222 fseeko(m_pFile, -32, SEEK_END);
223 iRead = fread(m_md5, 1, 32, m_pFile);
224 if (iRead != 32) {
225 bCheck = false;
226 return;
227 }
228 }
229
230 m_version = imageHead.dwVersion;
231 m_mergeVersion = imageHead.dwMergeVersion;
232 m_releaseTime.usYear = imageHead.stReleaseTime.usYear;
233 m_releaseTime.ucMonth = imageHead.stReleaseTime.ucMonth;
234 m_releaseTime.ucDay = imageHead.stReleaseTime.ucDay;
235 m_releaseTime.ucHour = imageHead.stReleaseTime.ucHour;
236 m_releaseTime.ucMinute = imageHead.stReleaseTime.ucMinute;
237 m_releaseTime.ucSecond = imageHead.stReleaseTime.ucSecond;
238 m_supportDevice = imageHead.emSupportChip;
239 m_bootOffset = imageHead.dwBootOffset;
240 m_bootSize = imageHead.dwBootSize;
241 m_fwOffset = imageHead.dwFWOffset;
242 m_fwSize = ulFwSize - m_fwOffset;
243 memcpy(m_reserved, imageHead.reserved, IMAGE_RESERVED_SIZE);
244 } else {
245 m_bootOffset = 0;
246 m_bootSize = m_fileSize;
247 }
248
249 PBYTE lpBoot;
250 lpBoot = new BYTE[m_bootSize];
251 fseeko(m_pFile, m_bootOffset, SEEK_SET);
252 iRead = fread(lpBoot, 1, m_bootSize, m_pFile);
253 if (iRead != (int)m_bootSize) {
254 bCheck = false;
255 return;
256 }
257 bool bRet;
258 m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet);
259 if (!bRet) {
260 bCheck = false;
261 return;
262 }
263 if (bOnlyBootFile) {
264 m_supportDevice = m_bootObject->SupportDevice;
265 UINT *pOsType;
266 pOsType = (UINT *)&m_reserved[4];
267 *pOsType = (UINT)RK_OS;
268 fclose(m_pFile);
269 m_pFile = NULL;
270 }
271 bCheck = true;
272 }
~CRKImage()273 CRKImage::~CRKImage()
274 {
275 if (m_pFile) {
276 fclose(m_pFile);
277 m_pFile = NULL;
278 }
279 if (m_bootObject) {
280 delete m_bootObject;
281 m_bootObject = NULL;
282 }
283 }
284
GetImageSize()285 long long CRKImage::GetImageSize()
286 {
287 return m_fileSize;
288 }
GetMd5Data(PBYTE & lpMd5,PBYTE & lpSignMd5)289 int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5)
290 {
291 lpMd5 = m_md5;
292 lpSignMd5 = m_signMd5;
293 return m_signMd5Size;
294 }
GetSignFlag()295 bool CRKImage::GetSignFlag()
296 {
297 return m_bSignFlag;
298 }
299