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