/* * (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; }