xref: /rkdeveloptool/RKImage.cpp (revision b06b487d7032fb122d83edf5dd70060822a7ce78)
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