1*76af099aSliuyi /* 2*76af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 3*76af099aSliuyi * Seth Liu 2017.03.01 4*76af099aSliuyi * 5*76af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 6*76af099aSliuyi */ 7*76af099aSliuyi #include "RKImage.h" 8*76af099aSliuyi 9*76af099aSliuyi DWORD CRKImage::GetVersion() 10*76af099aSliuyi { 11*76af099aSliuyi return m_version; 12*76af099aSliuyi } 13*76af099aSliuyi DWORD CRKImage::GetMergeVersion() 14*76af099aSliuyi { 15*76af099aSliuyi return m_mergeVersion; 16*76af099aSliuyi } 17*76af099aSliuyi STRUCT_RKTIME CRKImage::GetReleaseTime() 18*76af099aSliuyi { 19*76af099aSliuyi return m_releaseTime; 20*76af099aSliuyi } 21*76af099aSliuyi ENUM_RKDEVICE_TYPE CRKImage::GetSupportDevice() 22*76af099aSliuyi { 23*76af099aSliuyi return m_supportDevice; 24*76af099aSliuyi } 25*76af099aSliuyi ENUM_OS_TYPE CRKImage::GetOsType() 26*76af099aSliuyi { 27*76af099aSliuyi UINT *pOsType; 28*76af099aSliuyi pOsType = (UINT *)&m_reserved[4]; 29*76af099aSliuyi return (ENUM_OS_TYPE)*pOsType; 30*76af099aSliuyi } 31*76af099aSliuyi 32*76af099aSliuyi USHORT CRKImage::GetBackupSize() 33*76af099aSliuyi { 34*76af099aSliuyi USHORT *pBackupSize; 35*76af099aSliuyi pBackupSize = (USHORT *)&m_reserved[12]; 36*76af099aSliuyi return *pBackupSize; 37*76af099aSliuyi } 38*76af099aSliuyi DWORD CRKImage::GetBootOffset() 39*76af099aSliuyi { 40*76af099aSliuyi return m_bootOffset; 41*76af099aSliuyi } 42*76af099aSliuyi DWORD CRKImage::GetBootSize() 43*76af099aSliuyi { 44*76af099aSliuyi return m_bootSize; 45*76af099aSliuyi } 46*76af099aSliuyi DWORD CRKImage::GetFWOffset() 47*76af099aSliuyi { 48*76af099aSliuyi return m_fwOffset; 49*76af099aSliuyi } 50*76af099aSliuyi long long CRKImage::GetFWSize() 51*76af099aSliuyi { 52*76af099aSliuyi return m_fwSize; 53*76af099aSliuyi } 54*76af099aSliuyi bool CRKImage::SaveBootFile(string filename) 55*76af099aSliuyi { 56*76af099aSliuyi FILE *file = NULL; 57*76af099aSliuyi int iRead; 58*76af099aSliuyi file = fopen(filename.c_str(), "wb+"); 59*76af099aSliuyi if (!file) { 60*76af099aSliuyi return false; 61*76af099aSliuyi } 62*76af099aSliuyi BYTE buffer[1024]; 63*76af099aSliuyi DWORD dwBufferSize = 1024; 64*76af099aSliuyi DWORD dwBootSize = m_bootSize; 65*76af099aSliuyi DWORD dwReadSize; 66*76af099aSliuyi fseek(m_pFile, m_bootOffset, SEEK_SET); 67*76af099aSliuyi do { 68*76af099aSliuyi dwReadSize = (dwBootSize >= 1024) ? dwBufferSize : dwBootSize; 69*76af099aSliuyi iRead = fread(buffer, 1, dwReadSize, m_pFile); 70*76af099aSliuyi if (iRead != (int)dwReadSize) { 71*76af099aSliuyi fclose(file); 72*76af099aSliuyi return false; 73*76af099aSliuyi } 74*76af099aSliuyi fwrite(buffer, 1, dwReadSize, file); 75*76af099aSliuyi dwBootSize -= dwReadSize; 76*76af099aSliuyi } while(dwBootSize > 0); 77*76af099aSliuyi fclose(file); 78*76af099aSliuyi return true; 79*76af099aSliuyi } 80*76af099aSliuyi bool CRKImage::SaveFWFile(string filename) 81*76af099aSliuyi { 82*76af099aSliuyi FILE *file = NULL; 83*76af099aSliuyi int iRead; 84*76af099aSliuyi file = fopen(filename.c_str(), "wb+"); 85*76af099aSliuyi if (!file) { 86*76af099aSliuyi return false; 87*76af099aSliuyi } 88*76af099aSliuyi BYTE buffer[1024]; 89*76af099aSliuyi DWORD dwBufferSize = 1024; 90*76af099aSliuyi long long dwFWSize = m_fwSize; 91*76af099aSliuyi DWORD dwReadSize; 92*76af099aSliuyi fseeko(m_pFile, m_fwOffset, SEEK_SET); 93*76af099aSliuyi do { 94*76af099aSliuyi dwReadSize = (dwFWSize >= 1024) ? dwBufferSize : dwFWSize; 95*76af099aSliuyi iRead = fread(buffer, 1, dwReadSize, m_pFile); 96*76af099aSliuyi if (iRead != (int)dwReadSize) { 97*76af099aSliuyi fclose(file); 98*76af099aSliuyi return false; 99*76af099aSliuyi } 100*76af099aSliuyi fwrite(buffer, 1, dwReadSize, file); 101*76af099aSliuyi dwFWSize -= dwReadSize; 102*76af099aSliuyi } while (dwFWSize > 0); 103*76af099aSliuyi fclose(file); 104*76af099aSliuyi return true; 105*76af099aSliuyi } 106*76af099aSliuyi bool CRKImage::GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer) 107*76af099aSliuyi { 108*76af099aSliuyi if ( (dwOffset < 0) || (dwSize == 0) ) { 109*76af099aSliuyi return false; 110*76af099aSliuyi } 111*76af099aSliuyi if ( dwOffset+dwSize > m_fileSize) { 112*76af099aSliuyi return false; 113*76af099aSliuyi } 114*76af099aSliuyi fseeko(m_pFile, dwOffset, SEEK_SET); 115*76af099aSliuyi UINT uiActualRead; 116*76af099aSliuyi uiActualRead = fread(lpBuffer,1, dwSize, m_pFile); 117*76af099aSliuyi if (dwSize != uiActualRead){ 118*76af099aSliuyi return false; 119*76af099aSliuyi } 120*76af099aSliuyi return true; 121*76af099aSliuyi } 122*76af099aSliuyi void CRKImage::GetReservedData(PBYTE &lpData, USHORT &usSize) 123*76af099aSliuyi { 124*76af099aSliuyi lpData = m_reserved; 125*76af099aSliuyi usSize = IMAGE_RESERVED_SIZE; 126*76af099aSliuyi } 127*76af099aSliuyi 128*76af099aSliuyi CRKImage::CRKImage(string filename, bool &bCheck) 129*76af099aSliuyi { 130*76af099aSliuyi Version.setContainer(this); 131*76af099aSliuyi Version.getter(&CRKImage::GetVersion); 132*76af099aSliuyi MergeVersion.setContainer(this); 133*76af099aSliuyi MergeVersion.getter(&CRKImage::GetMergeVersion); 134*76af099aSliuyi ReleaseTime.setContainer(this); 135*76af099aSliuyi ReleaseTime.getter(&CRKImage::GetReleaseTime); 136*76af099aSliuyi SupportDevice.setContainer(this); 137*76af099aSliuyi SupportDevice.getter(&CRKImage::GetSupportDevice); 138*76af099aSliuyi OsType.setContainer(this); 139*76af099aSliuyi OsType.getter(&CRKImage::GetOsType); 140*76af099aSliuyi BackupSize.setContainer(this); 141*76af099aSliuyi BackupSize.getter(&CRKImage::GetBackupSize); 142*76af099aSliuyi BootOffset.setContainer(this); 143*76af099aSliuyi BootOffset.getter(&CRKImage::GetBootOffset); 144*76af099aSliuyi BootSize.setContainer(this); 145*76af099aSliuyi BootSize.getter(&CRKImage::GetBootSize); 146*76af099aSliuyi FWOffset.setContainer(this); 147*76af099aSliuyi FWOffset.getter(&CRKImage::GetFWOffset); 148*76af099aSliuyi FWSize.setContainer(this); 149*76af099aSliuyi FWSize.getter(&CRKImage::GetFWSize); 150*76af099aSliuyi SignFlag.setContainer(this); 151*76af099aSliuyi SignFlag.getter(&CRKImage::GetSignFlag); 152*76af099aSliuyi struct stat statBuf; 153*76af099aSliuyi m_bootObject = NULL; 154*76af099aSliuyi m_pFile = NULL; 155*76af099aSliuyi m_bSignFlag = false; 156*76af099aSliuyi 157*76af099aSliuyi m_signMd5Size = 0; 158*76af099aSliuyi memset(m_md5, 0, 32); 159*76af099aSliuyi memset(m_signMd5, 0, 256); 160*76af099aSliuyi 161*76af099aSliuyi char szName[256]; 162*76af099aSliuyi strcpy(szName, filename.c_str()); 163*76af099aSliuyi if(stat(szName, &statBuf) < 0) { 164*76af099aSliuyi bCheck = false; 165*76af099aSliuyi return; 166*76af099aSliuyi } 167*76af099aSliuyi if (S_ISDIR(statBuf.st_mode)) { 168*76af099aSliuyi bCheck = false; 169*76af099aSliuyi return; 170*76af099aSliuyi } 171*76af099aSliuyi m_fileSize = statBuf.st_size; 172*76af099aSliuyi 173*76af099aSliuyi bool bOnlyBootFile=false; 174*76af099aSliuyi transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower); 175*76af099aSliuyi if (filename.find(".bin") != string::npos) { 176*76af099aSliuyi bOnlyBootFile = true; 177*76af099aSliuyi } 178*76af099aSliuyi 179*76af099aSliuyi m_pFile = fopen(szName, "rb"); 180*76af099aSliuyi if (!m_pFile) { 181*76af099aSliuyi bCheck = false; 182*76af099aSliuyi return; 183*76af099aSliuyi } 184*76af099aSliuyi 185*76af099aSliuyi int nMd5DataSize, iRead; 186*76af099aSliuyi long long ulFwSize; 187*76af099aSliuyi STRUCT_RKIMAGE_HEAD imageHead; 188*76af099aSliuyi if (!bOnlyBootFile) { 189*76af099aSliuyi fseeko(m_pFile, 0, SEEK_SET); 190*76af099aSliuyi iRead = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile); 191*76af099aSliuyi if (iRead != sizeof(STRUCT_RKIMAGE_HEAD)) { 192*76af099aSliuyi bCheck = false; 193*76af099aSliuyi return; 194*76af099aSliuyi } 195*76af099aSliuyi if ( imageHead.uiTag != 0x57464B52 ) { 196*76af099aSliuyi bCheck = false; 197*76af099aSliuyi return; 198*76af099aSliuyi } 199*76af099aSliuyi if ((imageHead.reserved[14] == 'H') && (imageHead.reserved[15] == 'I')) { 200*76af099aSliuyi ulFwSize = *((DWORD *)(&imageHead.reserved[16])); 201*76af099aSliuyi ulFwSize <<= 32; 202*76af099aSliuyi ulFwSize += imageHead.dwFWOffset; 203*76af099aSliuyi ulFwSize += imageHead.dwFWSize; 204*76af099aSliuyi } else 205*76af099aSliuyi ulFwSize = imageHead.dwFWOffset + imageHead.dwFWSize; 206*76af099aSliuyi nMd5DataSize = GetImageSize() - ulFwSize; 207*76af099aSliuyi if (nMd5DataSize >= 160) { 208*76af099aSliuyi m_bSignFlag = true; 209*76af099aSliuyi m_signMd5Size = nMd5DataSize - 32; 210*76af099aSliuyi fseeko(m_pFile, ulFwSize, SEEK_SET); 211*76af099aSliuyi iRead = fread(m_md5, 1, 32, m_pFile); 212*76af099aSliuyi if (iRead != 32) { 213*76af099aSliuyi bCheck = false; 214*76af099aSliuyi return; 215*76af099aSliuyi } 216*76af099aSliuyi iRead = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile); 217*76af099aSliuyi if (iRead != (nMd5DataSize - 32)) { 218*76af099aSliuyi bCheck = false; 219*76af099aSliuyi return; 220*76af099aSliuyi } 221*76af099aSliuyi } else { 222*76af099aSliuyi fseeko(m_pFile, -32, SEEK_END); 223*76af099aSliuyi iRead = fread(m_md5, 1, 32, m_pFile); 224*76af099aSliuyi if (iRead != 32) { 225*76af099aSliuyi bCheck = false; 226*76af099aSliuyi return; 227*76af099aSliuyi } 228*76af099aSliuyi } 229*76af099aSliuyi 230*76af099aSliuyi m_version = imageHead.dwVersion; 231*76af099aSliuyi m_mergeVersion = imageHead.dwMergeVersion; 232*76af099aSliuyi m_releaseTime.usYear = imageHead.stReleaseTime.usYear; 233*76af099aSliuyi m_releaseTime.ucMonth = imageHead.stReleaseTime.ucMonth; 234*76af099aSliuyi m_releaseTime.ucDay = imageHead.stReleaseTime.ucDay; 235*76af099aSliuyi m_releaseTime.ucHour = imageHead.stReleaseTime.ucHour; 236*76af099aSliuyi m_releaseTime.ucMinute = imageHead.stReleaseTime.ucMinute; 237*76af099aSliuyi m_releaseTime.ucSecond = imageHead.stReleaseTime.ucSecond; 238*76af099aSliuyi m_supportDevice = imageHead.emSupportChip; 239*76af099aSliuyi m_bootOffset = imageHead.dwBootOffset; 240*76af099aSliuyi m_bootSize = imageHead.dwBootSize; 241*76af099aSliuyi m_fwOffset = imageHead.dwFWOffset; 242*76af099aSliuyi m_fwSize = ulFwSize - m_fwOffset; 243*76af099aSliuyi memcpy(m_reserved, imageHead.reserved, IMAGE_RESERVED_SIZE); 244*76af099aSliuyi } else { 245*76af099aSliuyi m_bootOffset = 0; 246*76af099aSliuyi m_bootSize = m_fileSize; 247*76af099aSliuyi } 248*76af099aSliuyi 249*76af099aSliuyi PBYTE lpBoot; 250*76af099aSliuyi lpBoot = new BYTE[m_bootSize]; 251*76af099aSliuyi fseeko(m_pFile, m_bootOffset, SEEK_SET); 252*76af099aSliuyi iRead = fread(lpBoot, 1, m_bootSize, m_pFile); 253*76af099aSliuyi if (iRead != (int)m_bootSize) { 254*76af099aSliuyi bCheck = false; 255*76af099aSliuyi return; 256*76af099aSliuyi } 257*76af099aSliuyi bool bRet; 258*76af099aSliuyi m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet); 259*76af099aSliuyi if (!bRet) { 260*76af099aSliuyi bCheck = false; 261*76af099aSliuyi return; 262*76af099aSliuyi } 263*76af099aSliuyi if (bOnlyBootFile) { 264*76af099aSliuyi m_supportDevice = m_bootObject->SupportDevice; 265*76af099aSliuyi UINT *pOsType; 266*76af099aSliuyi pOsType = (UINT *)&m_reserved[4]; 267*76af099aSliuyi *pOsType = (UINT)RK_OS; 268*76af099aSliuyi fclose(m_pFile); 269*76af099aSliuyi m_pFile = NULL; 270*76af099aSliuyi } 271*76af099aSliuyi bCheck = true; 272*76af099aSliuyi } 273*76af099aSliuyi CRKImage::~CRKImage() 274*76af099aSliuyi { 275*76af099aSliuyi if (m_pFile) { 276*76af099aSliuyi fclose(m_pFile); 277*76af099aSliuyi m_pFile = NULL; 278*76af099aSliuyi } 279*76af099aSliuyi if (m_bootObject) { 280*76af099aSliuyi delete m_bootObject; 281*76af099aSliuyi m_bootObject = NULL; 282*76af099aSliuyi } 283*76af099aSliuyi } 284*76af099aSliuyi 285*76af099aSliuyi long long CRKImage::GetImageSize() 286*76af099aSliuyi { 287*76af099aSliuyi return m_fileSize; 288*76af099aSliuyi } 289*76af099aSliuyi int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5) 290*76af099aSliuyi { 291*76af099aSliuyi lpMd5 = m_md5; 292*76af099aSliuyi lpSignMd5 = m_signMd5; 293*76af099aSliuyi return m_signMd5Size; 294*76af099aSliuyi } 295*76af099aSliuyi bool CRKImage::GetSignFlag() 296*76af099aSliuyi { 297*76af099aSliuyi return m_bSignFlag; 298*76af099aSliuyi }