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 8*76af099aSliuyi #include "RKBoot.h" 9*76af099aSliuyi extern UINT CRC_32(PBYTE pData, UINT ulSize); 10*76af099aSliuyi bool CRKBoot::GetRc4DisableFlag() 11*76af099aSliuyi { 12*76af099aSliuyi return m_bRc4Disable; 13*76af099aSliuyi } 14*76af099aSliuyi bool CRKBoot::GetSignFlag() 15*76af099aSliuyi { 16*76af099aSliuyi return m_bSignFlag; 17*76af099aSliuyi } 18*76af099aSliuyi DWORD CRKBoot::GetVersion() 19*76af099aSliuyi { 20*76af099aSliuyi return m_version; 21*76af099aSliuyi } 22*76af099aSliuyi DWORD CRKBoot::GetMergeVersion() 23*76af099aSliuyi { 24*76af099aSliuyi return m_mergeVersion; 25*76af099aSliuyi } 26*76af099aSliuyi STRUCT_RKTIME CRKBoot::GetReleaseTime() 27*76af099aSliuyi { 28*76af099aSliuyi return m_releaseTime; 29*76af099aSliuyi } 30*76af099aSliuyi ENUM_RKDEVICE_TYPE CRKBoot::GetSupportDevice() 31*76af099aSliuyi { 32*76af099aSliuyi return m_supportDevice; 33*76af099aSliuyi } 34*76af099aSliuyi UCHAR CRKBoot::GetEntry471Count() 35*76af099aSliuyi { 36*76af099aSliuyi return m_471Count; 37*76af099aSliuyi } 38*76af099aSliuyi UCHAR CRKBoot::GetEntry472Count() 39*76af099aSliuyi { 40*76af099aSliuyi return m_472Count; 41*76af099aSliuyi } 42*76af099aSliuyi UCHAR CRKBoot::GetEntryLoaderCount() 43*76af099aSliuyi { 44*76af099aSliuyi return m_loaderCount; 45*76af099aSliuyi } 46*76af099aSliuyi bool CRKBoot::CrcCheck() 47*76af099aSliuyi { 48*76af099aSliuyi UINT*pOldCrc,ulNewCrc; 49*76af099aSliuyi pOldCrc = (UINT*)(m_BootData+(m_BootSize-4)); 50*76af099aSliuyi ulNewCrc = CRC_32(m_BootData,m_BootSize-4); 51*76af099aSliuyi return (*pOldCrc==ulNewCrc)?true:false; 52*76af099aSliuyi } 53*76af099aSliuyi bool CRKBoot::SaveEntryFile(ENUM_RKBOOTENTRY type,UCHAR ucIndex,string fileName) 54*76af099aSliuyi { 55*76af099aSliuyi DWORD dwOffset; 56*76af099aSliuyi UCHAR ucCount,ucSize; 57*76af099aSliuyi switch ( type ) 58*76af099aSliuyi { 59*76af099aSliuyi case ENTRY471: 60*76af099aSliuyi dwOffset = m_471Offset; 61*76af099aSliuyi ucCount = m_471Count; 62*76af099aSliuyi ucSize = m_471Size; 63*76af099aSliuyi break; 64*76af099aSliuyi case ENTRY472: 65*76af099aSliuyi dwOffset = m_472Offset; 66*76af099aSliuyi ucCount = m_472Count; 67*76af099aSliuyi ucSize = m_472Size; 68*76af099aSliuyi break; 69*76af099aSliuyi case ENTRYLOADER: 70*76af099aSliuyi dwOffset = m_loaderOffset; 71*76af099aSliuyi ucCount = m_loaderCount; 72*76af099aSliuyi ucSize = m_loaderSize; 73*76af099aSliuyi break; 74*76af099aSliuyi default: 75*76af099aSliuyi return false; 76*76af099aSliuyi } 77*76af099aSliuyi if (ucIndex >= ucCount) 78*76af099aSliuyi { 79*76af099aSliuyi return false; 80*76af099aSliuyi } 81*76af099aSliuyi PSTRUCT_RKBOOT_ENTRY pEntry; 82*76af099aSliuyi pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); 83*76af099aSliuyi FILE *file=NULL; 84*76af099aSliuyi file = fopen(fileName.c_str(),"wb+"); 85*76af099aSliuyi if ( !file ) 86*76af099aSliuyi { 87*76af099aSliuyi return false; 88*76af099aSliuyi } 89*76af099aSliuyi fwrite(m_BootData+pEntry->dwDataOffset,1,pEntry->dwDataSize,file); 90*76af099aSliuyi fclose(file); 91*76af099aSliuyi return true; 92*76af099aSliuyi } 93*76af099aSliuyi bool CRKBoot::GetEntryProperty(ENUM_RKBOOTENTRY type,UCHAR ucIndex,DWORD &dwSize,DWORD &dwDelay,char *pName) 94*76af099aSliuyi { 95*76af099aSliuyi DWORD dwOffset; 96*76af099aSliuyi UCHAR ucCount,ucSize; 97*76af099aSliuyi switch ( type ) 98*76af099aSliuyi { 99*76af099aSliuyi case ENTRY471: 100*76af099aSliuyi dwOffset = m_471Offset; 101*76af099aSliuyi ucCount = m_471Count; 102*76af099aSliuyi ucSize = m_471Size; 103*76af099aSliuyi break; 104*76af099aSliuyi case ENTRY472: 105*76af099aSliuyi dwOffset = m_472Offset; 106*76af099aSliuyi ucCount = m_472Count; 107*76af099aSliuyi ucSize = m_472Size; 108*76af099aSliuyi break; 109*76af099aSliuyi case ENTRYLOADER: 110*76af099aSliuyi dwOffset = m_loaderOffset; 111*76af099aSliuyi ucCount = m_loaderCount; 112*76af099aSliuyi ucSize = m_loaderSize;//Loader��������ʱ�Ѿ�512���� 113*76af099aSliuyi break; 114*76af099aSliuyi default: 115*76af099aSliuyi return false; 116*76af099aSliuyi } 117*76af099aSliuyi if (ucIndex >= ucCount) 118*76af099aSliuyi { 119*76af099aSliuyi return false; 120*76af099aSliuyi } 121*76af099aSliuyi PSTRUCT_RKBOOT_ENTRY pEntry; 122*76af099aSliuyi pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); 123*76af099aSliuyi dwDelay = pEntry->dwDataDelay; 124*76af099aSliuyi dwSize = pEntry->dwDataSize; 125*76af099aSliuyi if (pName) 126*76af099aSliuyi { 127*76af099aSliuyi WCHAR_To_char(pEntry->szName,pName,20); 128*76af099aSliuyi } 129*76af099aSliuyi return true; 130*76af099aSliuyi } 131*76af099aSliuyi bool CRKBoot::GetEntryData(ENUM_RKBOOTENTRY type,UCHAR ucIndex,PBYTE lpData) 132*76af099aSliuyi { 133*76af099aSliuyi DWORD dwOffset; 134*76af099aSliuyi UCHAR ucCount,ucSize; 135*76af099aSliuyi switch ( type ) 136*76af099aSliuyi { 137*76af099aSliuyi case ENTRY471: 138*76af099aSliuyi dwOffset = m_471Offset; 139*76af099aSliuyi ucCount = m_471Count; 140*76af099aSliuyi ucSize = m_471Size; 141*76af099aSliuyi break; 142*76af099aSliuyi case ENTRY472: 143*76af099aSliuyi dwOffset = m_472Offset; 144*76af099aSliuyi ucCount = m_472Count; 145*76af099aSliuyi ucSize = m_472Size; 146*76af099aSliuyi break; 147*76af099aSliuyi case ENTRYLOADER: 148*76af099aSliuyi dwOffset = m_loaderOffset; 149*76af099aSliuyi ucCount = m_loaderCount; 150*76af099aSliuyi ucSize = m_loaderSize; 151*76af099aSliuyi break; 152*76af099aSliuyi default: 153*76af099aSliuyi return false; 154*76af099aSliuyi } 155*76af099aSliuyi if (ucIndex >= ucCount) 156*76af099aSliuyi { 157*76af099aSliuyi return false; 158*76af099aSliuyi } 159*76af099aSliuyi PSTRUCT_RKBOOT_ENTRY pEntry; 160*76af099aSliuyi pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); 161*76af099aSliuyi memcpy(lpData,m_BootData+pEntry->dwDataOffset,pEntry->dwDataSize); 162*76af099aSliuyi return true; 163*76af099aSliuyi } 164*76af099aSliuyi char CRKBoot::GetIndexByName(ENUM_RKBOOTENTRY type,char *pName) 165*76af099aSliuyi { 166*76af099aSliuyi DWORD dwOffset; 167*76af099aSliuyi UCHAR ucCount,ucSize; 168*76af099aSliuyi switch ( type ) 169*76af099aSliuyi { 170*76af099aSliuyi case ENTRY471: 171*76af099aSliuyi dwOffset = m_471Offset; 172*76af099aSliuyi ucCount = m_471Count; 173*76af099aSliuyi ucSize = m_471Size; 174*76af099aSliuyi break; 175*76af099aSliuyi case ENTRY472: 176*76af099aSliuyi dwOffset = m_472Offset; 177*76af099aSliuyi ucCount = m_472Count; 178*76af099aSliuyi ucSize = m_472Size; 179*76af099aSliuyi break; 180*76af099aSliuyi case ENTRYLOADER: 181*76af099aSliuyi dwOffset = m_loaderOffset; 182*76af099aSliuyi ucCount = m_loaderCount; 183*76af099aSliuyi ucSize = m_loaderSize; 184*76af099aSliuyi break; 185*76af099aSliuyi default: 186*76af099aSliuyi return -1; 187*76af099aSliuyi } 188*76af099aSliuyi 189*76af099aSliuyi for (UCHAR i=0;i<ucCount;i++) 190*76af099aSliuyi { 191*76af099aSliuyi PSTRUCT_RKBOOT_ENTRY pEntry; 192*76af099aSliuyi pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*i)); 193*76af099aSliuyi 194*76af099aSliuyi char szName[20]; 195*76af099aSliuyi WCHAR_To_char(pEntry->szName,szName,20); 196*76af099aSliuyi 197*76af099aSliuyi if (strcasecmp(pName,szName)==0) 198*76af099aSliuyi { 199*76af099aSliuyi return i; 200*76af099aSliuyi } 201*76af099aSliuyi } 202*76af099aSliuyi return -1; 203*76af099aSliuyi } 204*76af099aSliuyi CRKBoot::~CRKBoot() 205*76af099aSliuyi { 206*76af099aSliuyi if (m_BootData!=NULL) 207*76af099aSliuyi { 208*76af099aSliuyi delete []m_BootData; 209*76af099aSliuyi } 210*76af099aSliuyi } 211*76af099aSliuyi 212*76af099aSliuyi CRKBoot::CRKBoot(PBYTE lpBootData,DWORD dwBootSize,bool &bCheck) 213*76af099aSliuyi { 214*76af099aSliuyi Rc4DisableFlag.setContainer(this); 215*76af099aSliuyi Rc4DisableFlag.getter(&CRKBoot::GetRc4DisableFlag); 216*76af099aSliuyi SignFlag.setContainer(this); 217*76af099aSliuyi SignFlag.getter(&CRKBoot::GetSignFlag); 218*76af099aSliuyi Version.setContainer(this); 219*76af099aSliuyi Version.getter(&CRKBoot::GetVersion); 220*76af099aSliuyi MergeVersion.setContainer(this); 221*76af099aSliuyi MergeVersion.getter(&CRKBoot::GetMergeVersion); 222*76af099aSliuyi ReleaseTime.setContainer(this); 223*76af099aSliuyi ReleaseTime.getter(&CRKBoot::GetReleaseTime); 224*76af099aSliuyi SupportDevice.setContainer(this); 225*76af099aSliuyi SupportDevice.getter(&CRKBoot::GetSupportDevice); 226*76af099aSliuyi Entry471Count.setContainer(this); 227*76af099aSliuyi Entry471Count.getter(&CRKBoot::GetEntry471Count); 228*76af099aSliuyi Entry472Count.setContainer(this); 229*76af099aSliuyi Entry472Count.getter(&CRKBoot::GetEntry472Count); 230*76af099aSliuyi EntryLoaderCount.setContainer(this); 231*76af099aSliuyi EntryLoaderCount.getter(&CRKBoot::GetEntryLoaderCount); 232*76af099aSliuyi bCheck = true; 233*76af099aSliuyi if (lpBootData!=NULL) 234*76af099aSliuyi { 235*76af099aSliuyi m_BootData=lpBootData; 236*76af099aSliuyi m_BootSize=dwBootSize; 237*76af099aSliuyi bCheck=CrcCheck(); 238*76af099aSliuyi if (!bCheck) 239*76af099aSliuyi { 240*76af099aSliuyi return; 241*76af099aSliuyi } 242*76af099aSliuyi PSTRUCT_RKBOOT_HEAD pBootHead; 243*76af099aSliuyi pBootHead = (PSTRUCT_RKBOOT_HEAD)(m_BootData); 244*76af099aSliuyi if ( pBootHead->uiTag!=0x544F4F42) 245*76af099aSliuyi { 246*76af099aSliuyi bCheck=false; 247*76af099aSliuyi return; 248*76af099aSliuyi } 249*76af099aSliuyi if (pBootHead->ucRc4Flag) 250*76af099aSliuyi { 251*76af099aSliuyi m_bRc4Disable = true; 252*76af099aSliuyi } 253*76af099aSliuyi else 254*76af099aSliuyi m_bRc4Disable = false; 255*76af099aSliuyi if (pBootHead->ucSignFlag=='S') 256*76af099aSliuyi { 257*76af099aSliuyi m_bSignFlag = true; 258*76af099aSliuyi } 259*76af099aSliuyi else 260*76af099aSliuyi m_bSignFlag = false; 261*76af099aSliuyi m_version = pBootHead->dwVersion; 262*76af099aSliuyi m_mergeVersion = pBootHead->dwMergeVersion; 263*76af099aSliuyi m_BootHeadSize = pBootHead->usSize; 264*76af099aSliuyi m_releaseTime.usYear = pBootHead->stReleaseTime.usYear; 265*76af099aSliuyi m_releaseTime.ucMonth = pBootHead->stReleaseTime.ucMonth; 266*76af099aSliuyi m_releaseTime.ucDay = pBootHead->stReleaseTime.ucDay; 267*76af099aSliuyi m_releaseTime.ucHour = pBootHead->stReleaseTime.ucHour; 268*76af099aSliuyi m_releaseTime.ucMinute = pBootHead->stReleaseTime.ucMinute; 269*76af099aSliuyi m_releaseTime.ucSecond = pBootHead->stReleaseTime.ucSecond; 270*76af099aSliuyi m_supportDevice = pBootHead->emSupportChip; 271*76af099aSliuyi 272*76af099aSliuyi m_471Offset = pBootHead->dw471EntryOffset; 273*76af099aSliuyi m_471Count = pBootHead->uc471EntryCount; 274*76af099aSliuyi m_471Size = pBootHead->uc471EntrySize; 275*76af099aSliuyi 276*76af099aSliuyi m_472Offset = pBootHead->dw472EntryOffset; 277*76af099aSliuyi m_472Count = pBootHead->uc472EntryCount; 278*76af099aSliuyi m_472Size = pBootHead->uc472EntrySize; 279*76af099aSliuyi 280*76af099aSliuyi m_loaderOffset = pBootHead->dwLoaderEntryOffset; 281*76af099aSliuyi m_loaderCount = pBootHead->ucLoaderEntryCount; 282*76af099aSliuyi m_loaderSize = pBootHead->ucLoaderEntrySize; 283*76af099aSliuyi 284*76af099aSliuyi memcpy(m_crc,m_BootData+(m_BootSize-4),4); 285*76af099aSliuyi } 286*76af099aSliuyi else 287*76af099aSliuyi { 288*76af099aSliuyi bCheck = false; 289*76af099aSliuyi m_BootData=NULL; 290*76af099aSliuyi } 291*76af099aSliuyi } 292*76af099aSliuyi void CRKBoot::WCHAR_To_wchar(WCHAR *src,wchar_t *dst,int len) 293*76af099aSliuyi { 294*76af099aSliuyi int i; 295*76af099aSliuyi memset(dst,0,len*sizeof(wchar_t)); 296*76af099aSliuyi for (i=0;i<len;i++) 297*76af099aSliuyi { 298*76af099aSliuyi memcpy(dst,src,2); 299*76af099aSliuyi src++; 300*76af099aSliuyi dst++; 301*76af099aSliuyi } 302*76af099aSliuyi } 303*76af099aSliuyi void CRKBoot::WCHAR_To_char(WCHAR *src,char *dst,int len) 304*76af099aSliuyi { 305*76af099aSliuyi int i; 306*76af099aSliuyi memset(dst,0,len*sizeof(char)); 307*76af099aSliuyi for (i=0;i<len;i++) 308*76af099aSliuyi { 309*76af099aSliuyi memcpy(dst,src,1); 310*76af099aSliuyi src++; 311*76af099aSliuyi dst++; 312*76af099aSliuyi } 313*76af099aSliuyi } 314*76af099aSliuyi 315