rkdeveloptool/RKImage.cpp
liuyi 76af099afc rkDevelopTool: initial commit
Signed-off-by: liuyi <liuyi@rock-chips.com>
2017-03-07 16:12:52 +08:00

298 lines
6.8 KiB
C++

/*
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
* Seth Liu 2017.03.01
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "RKImage.h"
DWORD CRKImage::GetVersion()
{
return m_version;
}
DWORD CRKImage::GetMergeVersion()
{
return m_mergeVersion;
}
STRUCT_RKTIME CRKImage::GetReleaseTime()
{
return m_releaseTime;
}
ENUM_RKDEVICE_TYPE CRKImage::GetSupportDevice()
{
return m_supportDevice;
}
ENUM_OS_TYPE CRKImage::GetOsType()
{
UINT *pOsType;
pOsType = (UINT *)&m_reserved[4];
return (ENUM_OS_TYPE)*pOsType;
}
USHORT CRKImage::GetBackupSize()
{
USHORT *pBackupSize;
pBackupSize = (USHORT *)&m_reserved[12];
return *pBackupSize;
}
DWORD CRKImage::GetBootOffset()
{
return m_bootOffset;
}
DWORD CRKImage::GetBootSize()
{
return m_bootSize;
}
DWORD CRKImage::GetFWOffset()
{
return m_fwOffset;
}
long long CRKImage::GetFWSize()
{
return m_fwSize;
}
bool CRKImage::SaveBootFile(string filename)
{
FILE *file = NULL;
int iRead;
file = fopen(filename.c_str(), "wb+");
if (!file) {
return false;
}
BYTE buffer[1024];
DWORD dwBufferSize = 1024;
DWORD dwBootSize = m_bootSize;
DWORD dwReadSize;
fseek(m_pFile, m_bootOffset, SEEK_SET);
do {
dwReadSize = (dwBootSize >= 1024) ? dwBufferSize : dwBootSize;
iRead = fread(buffer, 1, dwReadSize, m_pFile);
if (iRead != (int)dwReadSize) {
fclose(file);
return false;
}
fwrite(buffer, 1, dwReadSize, file);
dwBootSize -= dwReadSize;
} while(dwBootSize > 0);
fclose(file);
return true;
}
bool CRKImage::SaveFWFile(string filename)
{
FILE *file = NULL;
int iRead;
file = fopen(filename.c_str(), "wb+");
if (!file) {
return false;
}
BYTE buffer[1024];
DWORD dwBufferSize = 1024;
long long dwFWSize = m_fwSize;
DWORD dwReadSize;
fseeko(m_pFile, m_fwOffset, SEEK_SET);
do {
dwReadSize = (dwFWSize >= 1024) ? dwBufferSize : dwFWSize;
iRead = fread(buffer, 1, dwReadSize, m_pFile);
if (iRead != (int)dwReadSize) {
fclose(file);
return false;
}
fwrite(buffer, 1, dwReadSize, file);
dwFWSize -= dwReadSize;
} while (dwFWSize > 0);
fclose(file);
return true;
}
bool CRKImage::GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer)
{
if ( (dwOffset < 0) || (dwSize == 0) ) {
return false;
}
if ( dwOffset+dwSize > m_fileSize) {
return false;
}
fseeko(m_pFile, dwOffset, SEEK_SET);
UINT uiActualRead;
uiActualRead = fread(lpBuffer,1, dwSize, m_pFile);
if (dwSize != uiActualRead){
return false;
}
return true;
}
void CRKImage::GetReservedData(PBYTE &lpData, USHORT &usSize)
{
lpData = m_reserved;
usSize = IMAGE_RESERVED_SIZE;
}
CRKImage::CRKImage(string filename, bool &bCheck)
{
Version.setContainer(this);
Version.getter(&CRKImage::GetVersion);
MergeVersion.setContainer(this);
MergeVersion.getter(&CRKImage::GetMergeVersion);
ReleaseTime.setContainer(this);
ReleaseTime.getter(&CRKImage::GetReleaseTime);
SupportDevice.setContainer(this);
SupportDevice.getter(&CRKImage::GetSupportDevice);
OsType.setContainer(this);
OsType.getter(&CRKImage::GetOsType);
BackupSize.setContainer(this);
BackupSize.getter(&CRKImage::GetBackupSize);
BootOffset.setContainer(this);
BootOffset.getter(&CRKImage::GetBootOffset);
BootSize.setContainer(this);
BootSize.getter(&CRKImage::GetBootSize);
FWOffset.setContainer(this);
FWOffset.getter(&CRKImage::GetFWOffset);
FWSize.setContainer(this);
FWSize.getter(&CRKImage::GetFWSize);
SignFlag.setContainer(this);
SignFlag.getter(&CRKImage::GetSignFlag);
struct stat statBuf;
m_bootObject = NULL;
m_pFile = NULL;
m_bSignFlag = false;
m_signMd5Size = 0;
memset(m_md5, 0, 32);
memset(m_signMd5, 0, 256);
char szName[256];
strcpy(szName, filename.c_str());
if(stat(szName, &statBuf) < 0) {
bCheck = false;
return;
}
if (S_ISDIR(statBuf.st_mode)) {
bCheck = false;
return;
}
m_fileSize = statBuf.st_size;
bool bOnlyBootFile=false;
transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower);
if (filename.find(".bin") != string::npos) {
bOnlyBootFile = true;
}
m_pFile = fopen(szName, "rb");
if (!m_pFile) {
bCheck = false;
return;
}
int nMd5DataSize, iRead;
long long ulFwSize;
STRUCT_RKIMAGE_HEAD imageHead;
if (!bOnlyBootFile) {
fseeko(m_pFile, 0, SEEK_SET);
iRead = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile);
if (iRead != sizeof(STRUCT_RKIMAGE_HEAD)) {
bCheck = false;
return;
}
if ( imageHead.uiTag != 0x57464B52 ) {
bCheck = false;
return;
}
if ((imageHead.reserved[14] == 'H') && (imageHead.reserved[15] == 'I')) {
ulFwSize = *((DWORD *)(&imageHead.reserved[16]));
ulFwSize <<= 32;
ulFwSize += imageHead.dwFWOffset;
ulFwSize += imageHead.dwFWSize;
} else
ulFwSize = imageHead.dwFWOffset + imageHead.dwFWSize;
nMd5DataSize = GetImageSize() - ulFwSize;
if (nMd5DataSize >= 160) {
m_bSignFlag = true;
m_signMd5Size = nMd5DataSize - 32;
fseeko(m_pFile, ulFwSize, SEEK_SET);
iRead = fread(m_md5, 1, 32, m_pFile);
if (iRead != 32) {
bCheck = false;
return;
}
iRead = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile);
if (iRead != (nMd5DataSize - 32)) {
bCheck = false;
return;
}
} else {
fseeko(m_pFile, -32, SEEK_END);
iRead = fread(m_md5, 1, 32, m_pFile);
if (iRead != 32) {
bCheck = false;
return;
}
}
m_version = imageHead.dwVersion;
m_mergeVersion = imageHead.dwMergeVersion;
m_releaseTime.usYear = imageHead.stReleaseTime.usYear;
m_releaseTime.ucMonth = imageHead.stReleaseTime.ucMonth;
m_releaseTime.ucDay = imageHead.stReleaseTime.ucDay;
m_releaseTime.ucHour = imageHead.stReleaseTime.ucHour;
m_releaseTime.ucMinute = imageHead.stReleaseTime.ucMinute;
m_releaseTime.ucSecond = imageHead.stReleaseTime.ucSecond;
m_supportDevice = imageHead.emSupportChip;
m_bootOffset = imageHead.dwBootOffset;
m_bootSize = imageHead.dwBootSize;
m_fwOffset = imageHead.dwFWOffset;
m_fwSize = ulFwSize - m_fwOffset;
memcpy(m_reserved, imageHead.reserved, IMAGE_RESERVED_SIZE);
} else {
m_bootOffset = 0;
m_bootSize = m_fileSize;
}
PBYTE lpBoot;
lpBoot = new BYTE[m_bootSize];
fseeko(m_pFile, m_bootOffset, SEEK_SET);
iRead = fread(lpBoot, 1, m_bootSize, m_pFile);
if (iRead != (int)m_bootSize) {
bCheck = false;
return;
}
bool bRet;
m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet);
if (!bRet) {
bCheck = false;
return;
}
if (bOnlyBootFile) {
m_supportDevice = m_bootObject->SupportDevice;
UINT *pOsType;
pOsType = (UINT *)&m_reserved[4];
*pOsType = (UINT)RK_OS;
fclose(m_pFile);
m_pFile = NULL;
}
bCheck = true;
}
CRKImage::~CRKImage()
{
if (m_pFile) {
fclose(m_pFile);
m_pFile = NULL;
}
if (m_bootObject) {
delete m_bootObject;
m_bootObject = NULL;
}
}
long long CRKImage::GetImageSize()
{
return m_fileSize;
}
int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5)
{
lpMd5 = m_md5;
lpSignMd5 = m_signMd5;
return m_signMd5Size;
}
bool CRKImage::GetSignFlag()
{
return m_bSignFlag;
}