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