xref: /rkdeveloptool/RKImage.cpp (revision b06b487d7032fb122d83edf5dd70060822a7ce78)
176af099aSliuyi /*
276af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi  * Seth Liu 2017.03.01
476af099aSliuyi  *
576af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
676af099aSliuyi  */
776af099aSliuyi #include "RKImage.h"
876af099aSliuyi 
GetVersion()9*21b25fd4SDave Murphy UINT CRKImage::GetVersion()
1076af099aSliuyi {
1176af099aSliuyi 	return m_version;
1276af099aSliuyi }
GetMergeVersion()13*21b25fd4SDave Murphy UINT CRKImage::GetMergeVersion()
1476af099aSliuyi {
1576af099aSliuyi 	return m_mergeVersion;
1676af099aSliuyi }
GetReleaseTime()1776af099aSliuyi STRUCT_RKTIME CRKImage::GetReleaseTime()
1876af099aSliuyi {
1976af099aSliuyi 	return m_releaseTime;
2076af099aSliuyi }
GetSupportDevice()2176af099aSliuyi ENUM_RKDEVICE_TYPE CRKImage::GetSupportDevice()
2276af099aSliuyi {
2376af099aSliuyi 	return m_supportDevice;
2476af099aSliuyi }
GetOsType()2576af099aSliuyi ENUM_OS_TYPE CRKImage::GetOsType()
2676af099aSliuyi {
2776af099aSliuyi 	UINT *pOsType;
2876af099aSliuyi 	pOsType = (UINT *)&m_reserved[4];
2976af099aSliuyi 	return (ENUM_OS_TYPE)*pOsType;
3076af099aSliuyi }
3176af099aSliuyi 
GetBackupSize()3276af099aSliuyi USHORT CRKImage::GetBackupSize()
3376af099aSliuyi {
3476af099aSliuyi 	USHORT *pBackupSize;
3576af099aSliuyi 	pBackupSize = (USHORT *)&m_reserved[12];
3676af099aSliuyi 	return *pBackupSize;
3776af099aSliuyi }
GetBootOffset()38*21b25fd4SDave Murphy UINT CRKImage::GetBootOffset()
3976af099aSliuyi {
4076af099aSliuyi 	return m_bootOffset;
4176af099aSliuyi }
GetBootSize()42*21b25fd4SDave Murphy UINT CRKImage::GetBootSize()
4376af099aSliuyi {
4476af099aSliuyi 	return m_bootSize;
4576af099aSliuyi }
GetFWOffset()46*21b25fd4SDave Murphy UINT CRKImage::GetFWOffset()
4776af099aSliuyi {
4876af099aSliuyi 	return m_fwOffset;
4976af099aSliuyi }
GetFWSize()5076af099aSliuyi long long CRKImage::GetFWSize()
5176af099aSliuyi {
5276af099aSliuyi 	return m_fwSize;
5376af099aSliuyi }
SaveBootFile(string filename)5476af099aSliuyi bool CRKImage::SaveBootFile(string filename)
5576af099aSliuyi {
5676af099aSliuyi 	FILE *file = NULL;
5776af099aSliuyi 	int iRead;
5876af099aSliuyi 	file = fopen(filename.c_str(), "wb+");
5976af099aSliuyi 	if (!file) {
6076af099aSliuyi 		return false;
6176af099aSliuyi 	}
6276af099aSliuyi 	BYTE buffer[1024];
6376af099aSliuyi 	DWORD dwBufferSize = 1024;
6476af099aSliuyi 	DWORD dwBootSize = m_bootSize;
6576af099aSliuyi 	DWORD dwReadSize;
6676af099aSliuyi 	fseek(m_pFile, m_bootOffset, SEEK_SET);
6776af099aSliuyi 	do {
6876af099aSliuyi 		dwReadSize = (dwBootSize >= 1024) ? dwBufferSize : dwBootSize;
6976af099aSliuyi 		iRead = fread(buffer, 1, dwReadSize, m_pFile);
7076af099aSliuyi 		if (iRead != (int)dwReadSize) {
7176af099aSliuyi 			fclose(file);
7276af099aSliuyi 			return false;
7376af099aSliuyi 		}
7476af099aSliuyi 		fwrite(buffer, 1, dwReadSize, file);
7576af099aSliuyi 		dwBootSize -= dwReadSize;
7676af099aSliuyi 	} while(dwBootSize > 0);
7776af099aSliuyi 	fclose(file);
7876af099aSliuyi 	return true;
7976af099aSliuyi }
SaveFWFile(string filename)8076af099aSliuyi bool CRKImage::SaveFWFile(string filename)
8176af099aSliuyi {
8276af099aSliuyi 	FILE *file = NULL;
8376af099aSliuyi 	int iRead;
8476af099aSliuyi 	file = fopen(filename.c_str(), "wb+");
8576af099aSliuyi 	if (!file) {
8676af099aSliuyi 		return false;
8776af099aSliuyi 	}
8876af099aSliuyi 	BYTE buffer[1024];
8976af099aSliuyi 	DWORD dwBufferSize = 1024;
9076af099aSliuyi 	long long dwFWSize = m_fwSize;
9176af099aSliuyi 	DWORD dwReadSize;
9276af099aSliuyi 	fseeko(m_pFile, m_fwOffset, SEEK_SET);
9376af099aSliuyi 	do {
9476af099aSliuyi 		dwReadSize = (dwFWSize >= 1024) ? dwBufferSize : dwFWSize;
9576af099aSliuyi 		iRead = fread(buffer, 1, dwReadSize, m_pFile);
9676af099aSliuyi 		if (iRead != (int)dwReadSize) {
9776af099aSliuyi 			fclose(file);
9876af099aSliuyi 			return false;
9976af099aSliuyi 		}
10076af099aSliuyi 		fwrite(buffer, 1, dwReadSize, file);
10176af099aSliuyi 		dwFWSize -= dwReadSize;
10276af099aSliuyi 	} while (dwFWSize > 0);
10376af099aSliuyi 	fclose(file);
10476af099aSliuyi 	return true;
10576af099aSliuyi }
GetData(long long dwOffset,DWORD dwSize,PBYTE lpBuffer)10676af099aSliuyi bool CRKImage::GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer)
10776af099aSliuyi {
10876af099aSliuyi 	if ( (dwOffset < 0) || (dwSize == 0) ) {
10976af099aSliuyi 		return false;
11076af099aSliuyi 	}
11176af099aSliuyi 	if ( dwOffset+dwSize > m_fileSize) {
11276af099aSliuyi 		return false;
11376af099aSliuyi 	}
11476af099aSliuyi 	fseeko(m_pFile, dwOffset, SEEK_SET);
11576af099aSliuyi 	UINT uiActualRead;
11676af099aSliuyi 	uiActualRead = fread(lpBuffer,1, dwSize, m_pFile);
11776af099aSliuyi 	if (dwSize != uiActualRead){
11876af099aSliuyi 		return false;
11976af099aSliuyi 	}
12076af099aSliuyi 	return true;
12176af099aSliuyi }
GetReservedData(PBYTE & lpData,USHORT & usSize)12276af099aSliuyi void CRKImage::GetReservedData(PBYTE &lpData, USHORT &usSize)
12376af099aSliuyi {
12476af099aSliuyi 	lpData = m_reserved;
12576af099aSliuyi 	usSize = IMAGE_RESERVED_SIZE;
12676af099aSliuyi }
12776af099aSliuyi 
CRKImage(string filename,bool & bCheck)12876af099aSliuyi CRKImage::CRKImage(string filename, bool &bCheck)
12976af099aSliuyi {
13076af099aSliuyi 	Version.setContainer(this);
13176af099aSliuyi 	Version.getter(&CRKImage::GetVersion);
13276af099aSliuyi 	MergeVersion.setContainer(this);
13376af099aSliuyi 	MergeVersion.getter(&CRKImage::GetMergeVersion);
13476af099aSliuyi 	ReleaseTime.setContainer(this);
13576af099aSliuyi 	ReleaseTime.getter(&CRKImage::GetReleaseTime);
13676af099aSliuyi 	SupportDevice.setContainer(this);
13776af099aSliuyi 	SupportDevice.getter(&CRKImage::GetSupportDevice);
13876af099aSliuyi 	OsType.setContainer(this);
13976af099aSliuyi 	OsType.getter(&CRKImage::GetOsType);
14076af099aSliuyi 	BackupSize.setContainer(this);
14176af099aSliuyi 	BackupSize.getter(&CRKImage::GetBackupSize);
14276af099aSliuyi 	BootOffset.setContainer(this);
14376af099aSliuyi 	BootOffset.getter(&CRKImage::GetBootOffset);
14476af099aSliuyi 	BootSize.setContainer(this);
14576af099aSliuyi 	BootSize.getter(&CRKImage::GetBootSize);
14676af099aSliuyi 	FWOffset.setContainer(this);
14776af099aSliuyi 	FWOffset.getter(&CRKImage::GetFWOffset);
14876af099aSliuyi 	FWSize.setContainer(this);
14976af099aSliuyi 	FWSize.getter(&CRKImage::GetFWSize);
15076af099aSliuyi 	SignFlag.setContainer(this);
15176af099aSliuyi 	SignFlag.getter(&CRKImage::GetSignFlag);
15276af099aSliuyi 	struct stat statBuf;
15376af099aSliuyi 	m_bootObject = NULL;
15476af099aSliuyi 	m_pFile = NULL;
15576af099aSliuyi 	m_bSignFlag = false;
15676af099aSliuyi 
15776af099aSliuyi 	m_signMd5Size = 0;
15876af099aSliuyi 	memset(m_md5, 0, 32);
15976af099aSliuyi 	memset(m_signMd5, 0, 256);
16076af099aSliuyi 
16176af099aSliuyi 	char szName[256];
16276af099aSliuyi 	strcpy(szName, filename.c_str());
16376af099aSliuyi 	if(stat(szName, &statBuf) < 0) {
16476af099aSliuyi 		bCheck = false;
16576af099aSliuyi 		return;
16676af099aSliuyi 	}
16776af099aSliuyi 	if (S_ISDIR(statBuf.st_mode)) {
16876af099aSliuyi 		bCheck = false;
16976af099aSliuyi 		return;
17076af099aSliuyi 	}
17176af099aSliuyi 	m_fileSize = statBuf.st_size;
17276af099aSliuyi 
17376af099aSliuyi 	bool bOnlyBootFile=false;
17476af099aSliuyi 	transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower);
17576af099aSliuyi 	if (filename.find(".bin") != string::npos) {
17676af099aSliuyi 		bOnlyBootFile = true;
17776af099aSliuyi 	}
17876af099aSliuyi 
17976af099aSliuyi 	m_pFile = fopen(szName, "rb");
18076af099aSliuyi 	if (!m_pFile) {
18176af099aSliuyi 		bCheck = false;
18276af099aSliuyi 		return;
18376af099aSliuyi 	}
18476af099aSliuyi 
18576af099aSliuyi 	int nMd5DataSize, iRead;
18676af099aSliuyi 	long long ulFwSize;
18776af099aSliuyi 	STRUCT_RKIMAGE_HEAD imageHead;
18876af099aSliuyi 	if (!bOnlyBootFile) {
18976af099aSliuyi 		fseeko(m_pFile, 0, SEEK_SET);
19076af099aSliuyi 		iRead = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile);
19176af099aSliuyi 		if (iRead != sizeof(STRUCT_RKIMAGE_HEAD)) {
19276af099aSliuyi 			bCheck = false;
19376af099aSliuyi 			return;
19476af099aSliuyi 		}
19576af099aSliuyi 		if ( imageHead.uiTag != 0x57464B52 ) {
19676af099aSliuyi 			bCheck = false;
19776af099aSliuyi 			return;
19876af099aSliuyi 		}
19976af099aSliuyi 		if ((imageHead.reserved[14] == 'H') && (imageHead.reserved[15] == 'I')) {
20076af099aSliuyi 			ulFwSize = *((DWORD *)(&imageHead.reserved[16]));
20176af099aSliuyi 			ulFwSize <<= 32;
20276af099aSliuyi 			ulFwSize += imageHead.dwFWOffset;
20376af099aSliuyi 			ulFwSize += imageHead.dwFWSize;
20476af099aSliuyi 		} else
20576af099aSliuyi 			ulFwSize = imageHead.dwFWOffset + imageHead.dwFWSize;
20676af099aSliuyi 		nMd5DataSize = GetImageSize() - ulFwSize;
20776af099aSliuyi 		if (nMd5DataSize >= 160) {
20876af099aSliuyi 			m_bSignFlag = true;
20976af099aSliuyi 			m_signMd5Size = nMd5DataSize - 32;
21076af099aSliuyi 			fseeko(m_pFile, ulFwSize, SEEK_SET);
21176af099aSliuyi 			iRead = fread(m_md5, 1, 32, m_pFile);
21276af099aSliuyi 			if (iRead != 32) {
21376af099aSliuyi 				bCheck = false;
21476af099aSliuyi 				return;
21576af099aSliuyi 			}
21676af099aSliuyi 			iRead = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile);
21776af099aSliuyi 			if (iRead != (nMd5DataSize - 32)) {
21876af099aSliuyi 				bCheck = false;
21976af099aSliuyi 				return;
22076af099aSliuyi 			}
22176af099aSliuyi 		} else {
22276af099aSliuyi 			fseeko(m_pFile, -32, SEEK_END);
22376af099aSliuyi 			iRead = fread(m_md5, 1, 32, m_pFile);
22476af099aSliuyi 			if (iRead != 32) {
22576af099aSliuyi 				bCheck = false;
22676af099aSliuyi 				return;
22776af099aSliuyi 			}
22876af099aSliuyi 		}
22976af099aSliuyi 
23076af099aSliuyi 		m_version = imageHead.dwVersion;
23176af099aSliuyi 		m_mergeVersion = imageHead.dwMergeVersion;
23276af099aSliuyi 		m_releaseTime.usYear = imageHead.stReleaseTime.usYear;
23376af099aSliuyi 		m_releaseTime.ucMonth = imageHead.stReleaseTime.ucMonth;
23476af099aSliuyi 		m_releaseTime.ucDay = imageHead.stReleaseTime.ucDay;
23576af099aSliuyi 		m_releaseTime.ucHour = imageHead.stReleaseTime.ucHour;
23676af099aSliuyi 		m_releaseTime.ucMinute = imageHead.stReleaseTime.ucMinute;
23776af099aSliuyi 		m_releaseTime.ucSecond = imageHead.stReleaseTime.ucSecond;
23876af099aSliuyi 		m_supportDevice = imageHead.emSupportChip;
23976af099aSliuyi 		m_bootOffset = imageHead.dwBootOffset;
24076af099aSliuyi 		m_bootSize = imageHead.dwBootSize;
24176af099aSliuyi 		m_fwOffset = imageHead.dwFWOffset;
24276af099aSliuyi 		m_fwSize = ulFwSize - m_fwOffset;
24376af099aSliuyi 		memcpy(m_reserved, imageHead.reserved, IMAGE_RESERVED_SIZE);
24476af099aSliuyi 	} else {
24576af099aSliuyi 		m_bootOffset = 0;
24676af099aSliuyi 		m_bootSize = m_fileSize;
24776af099aSliuyi 	}
24876af099aSliuyi 
24976af099aSliuyi 	PBYTE lpBoot;
25076af099aSliuyi 	lpBoot = new BYTE[m_bootSize];
25176af099aSliuyi 	fseeko(m_pFile, m_bootOffset, SEEK_SET);
25276af099aSliuyi 	iRead = fread(lpBoot, 1, m_bootSize, m_pFile);
25376af099aSliuyi 	if (iRead != (int)m_bootSize) {
25476af099aSliuyi 		bCheck = false;
25576af099aSliuyi 		return;
25676af099aSliuyi 	}
25776af099aSliuyi 	bool bRet;
25876af099aSliuyi 	m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet);
25976af099aSliuyi 	if (!bRet) {
26076af099aSliuyi 		bCheck = false;
26176af099aSliuyi 		return;
26276af099aSliuyi 	}
26376af099aSliuyi 	if (bOnlyBootFile) {
26476af099aSliuyi 		m_supportDevice = m_bootObject->SupportDevice;
26576af099aSliuyi 		UINT *pOsType;
26676af099aSliuyi 		pOsType = (UINT *)&m_reserved[4];
26776af099aSliuyi 		*pOsType = (UINT)RK_OS;
26876af099aSliuyi 		fclose(m_pFile);
26976af099aSliuyi 		m_pFile = NULL;
27076af099aSliuyi 	}
27176af099aSliuyi 	bCheck = true;
27276af099aSliuyi }
~CRKImage()27376af099aSliuyi CRKImage::~CRKImage()
27476af099aSliuyi {
27576af099aSliuyi 	if (m_pFile) {
27676af099aSliuyi 		fclose(m_pFile);
27776af099aSliuyi 		m_pFile = NULL;
27876af099aSliuyi 	}
27976af099aSliuyi 	if (m_bootObject) {
28076af099aSliuyi 		delete m_bootObject;
28176af099aSliuyi 		m_bootObject = NULL;
28276af099aSliuyi 	}
28376af099aSliuyi }
28476af099aSliuyi 
GetImageSize()28576af099aSliuyi long long CRKImage::GetImageSize()
28676af099aSliuyi {
28776af099aSliuyi 	return m_fileSize;
28876af099aSliuyi }
GetMd5Data(PBYTE & lpMd5,PBYTE & lpSignMd5)28976af099aSliuyi int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5)
29076af099aSliuyi {
29176af099aSliuyi 	lpMd5 = m_md5;
29276af099aSliuyi 	lpSignMd5 = m_signMd5;
29376af099aSliuyi 	return m_signMd5Size;
29476af099aSliuyi }
GetSignFlag()29576af099aSliuyi bool CRKImage::GetSignFlag()
29676af099aSliuyi {
29776af099aSliuyi 	return m_bSignFlag;
29876af099aSliuyi }
299