#include "RKImage.h" #include "MD5Checksum.h" extern int IsRK3308_Platform(); extern int Compatible_rk3308bs_loader(); 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; } FILE *CRKImage::GetFWFileHandle() { return m_pFile; } char *CRKImage::GetFwPath() { return m_imgPath; } bool CRKImage::Md5Check(long long nCheckSize) { printf("In Md5Check\n"); tstring strNewMd5 = _T(""); strNewMd5 = CMD5Checksum::GetMD5(m_pFile, nCheckSize); if (strNewMd5.size() == 32) { BYTE newMd5[32]; memcpy(newMd5, strNewMd5.c_str(), 32); int i, j; printf("New Md5:\n"); for (i = 0; i < 2; i++) { for (j = 0; j < 16; j++) { printf("%02X ", newMd5[i * 16 + j]); } printf("\r\n"); } printf("Old Md5:\n"); for (i = 0; i < 2; i++) { for (j = 0; j < 16; j++) { printf("%02X ", m_md5[i * 16 + j]); } printf("\r\n"); } if (memcmp(newMd5, m_md5, 32) != 0) { return false; } else { return true; } } else { return false; } } bool CRKImage::SaveBootFile(tstring filename) { FILE *file = NULL; file = fopen(filename.c_str(), _T("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; size_t ret = fread(buffer, 1, dwReadSize, m_pFile); if (ret != dwReadSize) { printf("fread error: read:%d, req read:%d", ret, dwReadSize); } fwrite(buffer, 1, dwReadSize, file); dwBootSize -= dwReadSize; } while (dwBootSize > 0); fclose(file); return true; } bool CRKImage::SaveFWFile(tstring filename) { FILE *file = NULL; file = fopen(filename.c_str(), _T("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; size_t ret = fread(buffer, 1, dwReadSize, m_pFile); if (ret != dwReadSize) { printf("fread error: read:%d, req read:%d", ret, dwReadSize); } 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; } fseeko64(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; } int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5) { lpMd5 = m_md5; lpSignMd5 = m_signMd5; return m_signMd5Size; } CRKImage::CRKImage(tstring 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); FwPath.setContainer(this); FwPath.getter(&CRKImage::GetFwPath); bool bDoMdb5Check = bCheck; struct stat64 statBuf; m_bootObject = NULL; m_pFile = NULL; m_signMd5Size = 0; memset(m_md5, 0, 32); memset(m_signMd5, 0, 256); tchar szName[256]; _tcscpy(szName, filename.c_str()); if (stat64(szName, &statBuf) < 0) { bCheck = false; printf("CRKImage : stat <%s> happen error.error_reason = %s\n", szName, strerror(errno)); return; } if (S_ISDIR(statBuf.st_mode)) { bCheck = false; printf("CRKImage : Error! stat mode is DIR\n"); return; } m_fileSize = statBuf.st_size; memcpy(m_imgPath, szName, sizeof(szName)); bool bOnlyBootFile = false; transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower); if (filename.find(_T(".bin")) != tstring::npos) { bOnlyBootFile = true; } m_pFile = fopen(szName, "rb"); if (!m_pFile) { bCheck = false; printf("CRKImage : fopen <%s> fail,will try use fopen64 \n", szName); m_pFile = fopen64(szName, "rb"); if (!m_pFile) { bCheck = false; printf("CRKImage : fopen64 <%s> fail\n", szName); return; } } //code will be error if firmware is signed.md5 is not last 32 byte. // fseeko(m_pFile,-32,SEEK_END); // fread(m_md5,1,32,m_pFile); // fseeko(m_pFile,0,SEEK_SET); // if (!Md5Check()) // { // bCheck = false; // return; // } int nMd5DataSize; long long ulFwSize; STRUCT_RKIMAGE_HEAD imageHead; if (!bOnlyBootFile) { fseeko64(m_pFile, 0, SEEK_SET); size_t ret = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile); if (ret != sizeof(STRUCT_RKIMAGE_HEAD)) { return; } if (imageHead.uiTag != 0x57464B52) { bCheck = false; printf("CRKImage :Error! imageHead.uiTag != 0x57464B52\n"); 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) { //sign image m_bSignFlag = true; m_signMd5Size = nMd5DataSize - 32; fseeko64(m_pFile, ulFwSize, SEEK_SET); size_t ret = fread(m_md5, 1, 32, m_pFile); if (ret != 32) { printf("%s:read error\n", __func__); } ret = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile); if (ret != nMd5DataSize - 32) { printf("%s :ret = %d\n", __func__, ret); } } else { fseeko64(m_pFile, -32, SEEK_END); size_t read = fread(m_md5, 1, 32, m_pFile); if (read != 32) { printf("%s: read error\n", __func__); } } if (bDoMdb5Check) { if (!Md5Check(ulFwSize)) { printf("Md5Check update.img ulFwSize:%ld", ulFwSize); //bCheck = false; //return; bCheck = true; } } 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]; fseeko64(m_pFile, m_bootOffset, SEEK_SET); size_t ret = fread(lpBoot, 1, m_bootSize, m_pFile); if (ret != m_bootSize) { printf("%s : read error\n", __func__); } bool bRet; m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet); if (!bRet) { bCheck = false; printf("CRKImage :Error! new CRKBoot fail!\n"); 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; }