176af099aSliuyi /* 276af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 376af099aSliuyi * Seth Liu 2017.03.01 476af099aSliuyi * 576af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 676af099aSliuyi */ 776af099aSliuyi 876af099aSliuyi #include "RKBoot.h" 976af099aSliuyi extern UINT CRC_32(PBYTE pData, UINT ulSize); 1076af099aSliuyi bool CRKBoot::GetRc4DisableFlag() 1176af099aSliuyi { 1276af099aSliuyi return m_bRc4Disable; 1376af099aSliuyi } 1476af099aSliuyi bool CRKBoot::GetSignFlag() 1576af099aSliuyi { 1676af099aSliuyi return m_bSignFlag; 1776af099aSliuyi } 1876af099aSliuyi DWORD CRKBoot::GetVersion() 1976af099aSliuyi { 2076af099aSliuyi return m_version; 2176af099aSliuyi } 2276af099aSliuyi DWORD CRKBoot::GetMergeVersion() 2376af099aSliuyi { 2476af099aSliuyi return m_mergeVersion; 2576af099aSliuyi } 2676af099aSliuyi STRUCT_RKTIME CRKBoot::GetReleaseTime() 2776af099aSliuyi { 2876af099aSliuyi return m_releaseTime; 2976af099aSliuyi } 3076af099aSliuyi ENUM_RKDEVICE_TYPE CRKBoot::GetSupportDevice() 3176af099aSliuyi { 3276af099aSliuyi return m_supportDevice; 3376af099aSliuyi } 3476af099aSliuyi UCHAR CRKBoot::GetEntry471Count() 3576af099aSliuyi { 3676af099aSliuyi return m_471Count; 3776af099aSliuyi } 3876af099aSliuyi UCHAR CRKBoot::GetEntry472Count() 3976af099aSliuyi { 4076af099aSliuyi return m_472Count; 4176af099aSliuyi } 4276af099aSliuyi UCHAR CRKBoot::GetEntryLoaderCount() 4376af099aSliuyi { 4476af099aSliuyi return m_loaderCount; 4576af099aSliuyi } 4676af099aSliuyi bool CRKBoot::CrcCheck() 4776af099aSliuyi { 4876af099aSliuyi UINT*pOldCrc,ulNewCrc; 4976af099aSliuyi pOldCrc = (UINT*)(m_BootData+(m_BootSize-4)); 5076af099aSliuyi ulNewCrc = CRC_32(m_BootData,m_BootSize-4); 5176af099aSliuyi return (*pOldCrc==ulNewCrc)?true:false; 5276af099aSliuyi } 5376af099aSliuyi bool CRKBoot::SaveEntryFile(ENUM_RKBOOTENTRY type,UCHAR ucIndex,string fileName) 5476af099aSliuyi { 5576af099aSliuyi DWORD dwOffset; 5676af099aSliuyi UCHAR ucCount,ucSize; 5776af099aSliuyi switch ( type ) 5876af099aSliuyi { 5976af099aSliuyi case ENTRY471: 6076af099aSliuyi dwOffset = m_471Offset; 6176af099aSliuyi ucCount = m_471Count; 6276af099aSliuyi ucSize = m_471Size; 6376af099aSliuyi break; 6476af099aSliuyi case ENTRY472: 6576af099aSliuyi dwOffset = m_472Offset; 6676af099aSliuyi ucCount = m_472Count; 6776af099aSliuyi ucSize = m_472Size; 6876af099aSliuyi break; 6976af099aSliuyi case ENTRYLOADER: 7076af099aSliuyi dwOffset = m_loaderOffset; 7176af099aSliuyi ucCount = m_loaderCount; 7276af099aSliuyi ucSize = m_loaderSize; 7376af099aSliuyi break; 7476af099aSliuyi default: 7576af099aSliuyi return false; 7676af099aSliuyi } 7776af099aSliuyi if (ucIndex >= ucCount) 7876af099aSliuyi { 7976af099aSliuyi return false; 8076af099aSliuyi } 8176af099aSliuyi PSTRUCT_RKBOOT_ENTRY pEntry; 8276af099aSliuyi pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); 8376af099aSliuyi FILE *file=NULL; 8476af099aSliuyi file = fopen(fileName.c_str(),"wb+"); 8576af099aSliuyi if ( !file ) 8676af099aSliuyi { 8776af099aSliuyi return false; 8876af099aSliuyi } 8976af099aSliuyi fwrite(m_BootData+pEntry->dwDataOffset,1,pEntry->dwDataSize,file); 9076af099aSliuyi fclose(file); 9176af099aSliuyi return true; 9276af099aSliuyi } 9376af099aSliuyi bool CRKBoot::GetEntryProperty(ENUM_RKBOOTENTRY type,UCHAR ucIndex,DWORD &dwSize,DWORD &dwDelay,char *pName) 9476af099aSliuyi { 9576af099aSliuyi DWORD dwOffset; 9676af099aSliuyi UCHAR ucCount,ucSize; 9776af099aSliuyi switch ( type ) 9876af099aSliuyi { 9976af099aSliuyi case ENTRY471: 10076af099aSliuyi dwOffset = m_471Offset; 10176af099aSliuyi ucCount = m_471Count; 10276af099aSliuyi ucSize = m_471Size; 10376af099aSliuyi break; 10476af099aSliuyi case ENTRY472: 10576af099aSliuyi dwOffset = m_472Offset; 10676af099aSliuyi ucCount = m_472Count; 10776af099aSliuyi ucSize = m_472Size; 10876af099aSliuyi break; 10976af099aSliuyi case ENTRYLOADER: 11076af099aSliuyi dwOffset = m_loaderOffset; 11176af099aSliuyi ucCount = m_loaderCount; 11276af099aSliuyi ucSize = m_loaderSize;//Loader��������ʱ�Ѿ�512���� 11376af099aSliuyi break; 11476af099aSliuyi default: 11576af099aSliuyi return false; 11676af099aSliuyi } 11776af099aSliuyi if (ucIndex >= ucCount) 11876af099aSliuyi { 11976af099aSliuyi return false; 12076af099aSliuyi } 12176af099aSliuyi PSTRUCT_RKBOOT_ENTRY pEntry; 12276af099aSliuyi pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); 12376af099aSliuyi dwDelay = pEntry->dwDataDelay; 12476af099aSliuyi dwSize = pEntry->dwDataSize; 12576af099aSliuyi if (pName) 12676af099aSliuyi { 12776af099aSliuyi WCHAR_To_char(pEntry->szName,pName,20); 12876af099aSliuyi } 12976af099aSliuyi return true; 13076af099aSliuyi } 13176af099aSliuyi bool CRKBoot::GetEntryData(ENUM_RKBOOTENTRY type,UCHAR ucIndex,PBYTE lpData) 13276af099aSliuyi { 13376af099aSliuyi DWORD dwOffset; 13476af099aSliuyi UCHAR ucCount,ucSize; 13576af099aSliuyi switch ( type ) 13676af099aSliuyi { 13776af099aSliuyi case ENTRY471: 13876af099aSliuyi dwOffset = m_471Offset; 13976af099aSliuyi ucCount = m_471Count; 14076af099aSliuyi ucSize = m_471Size; 14176af099aSliuyi break; 14276af099aSliuyi case ENTRY472: 14376af099aSliuyi dwOffset = m_472Offset; 14476af099aSliuyi ucCount = m_472Count; 14576af099aSliuyi ucSize = m_472Size; 14676af099aSliuyi break; 14776af099aSliuyi case ENTRYLOADER: 14876af099aSliuyi dwOffset = m_loaderOffset; 14976af099aSliuyi ucCount = m_loaderCount; 15076af099aSliuyi ucSize = m_loaderSize; 15176af099aSliuyi break; 15276af099aSliuyi default: 15376af099aSliuyi return false; 15476af099aSliuyi } 15576af099aSliuyi if (ucIndex >= ucCount) 15676af099aSliuyi { 15776af099aSliuyi return false; 15876af099aSliuyi } 15976af099aSliuyi PSTRUCT_RKBOOT_ENTRY pEntry; 16076af099aSliuyi pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); 16176af099aSliuyi memcpy(lpData,m_BootData+pEntry->dwDataOffset,pEntry->dwDataSize); 16276af099aSliuyi return true; 16376af099aSliuyi } 16476af099aSliuyi char CRKBoot::GetIndexByName(ENUM_RKBOOTENTRY type,char *pName) 16576af099aSliuyi { 16676af099aSliuyi DWORD dwOffset; 16776af099aSliuyi UCHAR ucCount,ucSize; 16876af099aSliuyi switch ( type ) 16976af099aSliuyi { 17076af099aSliuyi case ENTRY471: 17176af099aSliuyi dwOffset = m_471Offset; 17276af099aSliuyi ucCount = m_471Count; 17376af099aSliuyi ucSize = m_471Size; 17476af099aSliuyi break; 17576af099aSliuyi case ENTRY472: 17676af099aSliuyi dwOffset = m_472Offset; 17776af099aSliuyi ucCount = m_472Count; 17876af099aSliuyi ucSize = m_472Size; 17976af099aSliuyi break; 18076af099aSliuyi case ENTRYLOADER: 18176af099aSliuyi dwOffset = m_loaderOffset; 18276af099aSliuyi ucCount = m_loaderCount; 18376af099aSliuyi ucSize = m_loaderSize; 18476af099aSliuyi break; 18576af099aSliuyi default: 18676af099aSliuyi return -1; 18776af099aSliuyi } 18876af099aSliuyi 18976af099aSliuyi for (UCHAR i=0;i<ucCount;i++) 19076af099aSliuyi { 19176af099aSliuyi PSTRUCT_RKBOOT_ENTRY pEntry; 19276af099aSliuyi pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*i)); 19376af099aSliuyi 19476af099aSliuyi char szName[20]; 19576af099aSliuyi WCHAR_To_char(pEntry->szName,szName,20); 19676af099aSliuyi 19776af099aSliuyi if (strcasecmp(pName,szName)==0) 19876af099aSliuyi { 19976af099aSliuyi return i; 20076af099aSliuyi } 20176af099aSliuyi } 20276af099aSliuyi return -1; 20376af099aSliuyi } 20476af099aSliuyi CRKBoot::~CRKBoot() 20576af099aSliuyi { 20676af099aSliuyi if (m_BootData!=NULL) 20776af099aSliuyi { 20876af099aSliuyi delete []m_BootData; 20976af099aSliuyi } 21076af099aSliuyi } 21176af099aSliuyi 21276af099aSliuyi CRKBoot::CRKBoot(PBYTE lpBootData,DWORD dwBootSize,bool &bCheck) 21376af099aSliuyi { 21476af099aSliuyi Rc4DisableFlag.setContainer(this); 21576af099aSliuyi Rc4DisableFlag.getter(&CRKBoot::GetRc4DisableFlag); 21676af099aSliuyi SignFlag.setContainer(this); 21776af099aSliuyi SignFlag.getter(&CRKBoot::GetSignFlag); 21876af099aSliuyi Version.setContainer(this); 21976af099aSliuyi Version.getter(&CRKBoot::GetVersion); 22076af099aSliuyi MergeVersion.setContainer(this); 22176af099aSliuyi MergeVersion.getter(&CRKBoot::GetMergeVersion); 22276af099aSliuyi ReleaseTime.setContainer(this); 22376af099aSliuyi ReleaseTime.getter(&CRKBoot::GetReleaseTime); 22476af099aSliuyi SupportDevice.setContainer(this); 22576af099aSliuyi SupportDevice.getter(&CRKBoot::GetSupportDevice); 22676af099aSliuyi Entry471Count.setContainer(this); 22776af099aSliuyi Entry471Count.getter(&CRKBoot::GetEntry471Count); 22876af099aSliuyi Entry472Count.setContainer(this); 22976af099aSliuyi Entry472Count.getter(&CRKBoot::GetEntry472Count); 23076af099aSliuyi EntryLoaderCount.setContainer(this); 23176af099aSliuyi EntryLoaderCount.getter(&CRKBoot::GetEntryLoaderCount); 23276af099aSliuyi bCheck = true; 23376af099aSliuyi if (lpBootData!=NULL) 23476af099aSliuyi { 23576af099aSliuyi m_BootData=lpBootData; 23676af099aSliuyi m_BootSize=dwBootSize; 23776af099aSliuyi bCheck=CrcCheck(); 23876af099aSliuyi if (!bCheck) 23976af099aSliuyi { 24076af099aSliuyi return; 24176af099aSliuyi } 24276af099aSliuyi PSTRUCT_RKBOOT_HEAD pBootHead; 24376af099aSliuyi pBootHead = (PSTRUCT_RKBOOT_HEAD)(m_BootData); 244*46bb4c07Sliuyi if (( pBootHead->uiTag!=0x544F4F42)&&(pBootHead->uiTag!=0x2052444C)) 24576af099aSliuyi { 24676af099aSliuyi bCheck=false; 24776af099aSliuyi return; 24876af099aSliuyi } 24976af099aSliuyi if (pBootHead->ucRc4Flag) 25076af099aSliuyi { 25176af099aSliuyi m_bRc4Disable = true; 25276af099aSliuyi } 25376af099aSliuyi else 25476af099aSliuyi m_bRc4Disable = false; 25576af099aSliuyi if (pBootHead->ucSignFlag=='S') 25676af099aSliuyi { 25776af099aSliuyi m_bSignFlag = true; 25876af099aSliuyi } 25976af099aSliuyi else 26076af099aSliuyi m_bSignFlag = false; 26176af099aSliuyi m_version = pBootHead->dwVersion; 26276af099aSliuyi m_mergeVersion = pBootHead->dwMergeVersion; 26376af099aSliuyi m_BootHeadSize = pBootHead->usSize; 26476af099aSliuyi m_releaseTime.usYear = pBootHead->stReleaseTime.usYear; 26576af099aSliuyi m_releaseTime.ucMonth = pBootHead->stReleaseTime.ucMonth; 26676af099aSliuyi m_releaseTime.ucDay = pBootHead->stReleaseTime.ucDay; 26776af099aSliuyi m_releaseTime.ucHour = pBootHead->stReleaseTime.ucHour; 26876af099aSliuyi m_releaseTime.ucMinute = pBootHead->stReleaseTime.ucMinute; 26976af099aSliuyi m_releaseTime.ucSecond = pBootHead->stReleaseTime.ucSecond; 27076af099aSliuyi m_supportDevice = pBootHead->emSupportChip; 27176af099aSliuyi 27276af099aSliuyi m_471Offset = pBootHead->dw471EntryOffset; 27376af099aSliuyi m_471Count = pBootHead->uc471EntryCount; 27476af099aSliuyi m_471Size = pBootHead->uc471EntrySize; 27576af099aSliuyi 27676af099aSliuyi m_472Offset = pBootHead->dw472EntryOffset; 27776af099aSliuyi m_472Count = pBootHead->uc472EntryCount; 27876af099aSliuyi m_472Size = pBootHead->uc472EntrySize; 27976af099aSliuyi 28076af099aSliuyi m_loaderOffset = pBootHead->dwLoaderEntryOffset; 28176af099aSliuyi m_loaderCount = pBootHead->ucLoaderEntryCount; 28276af099aSliuyi m_loaderSize = pBootHead->ucLoaderEntrySize; 28376af099aSliuyi 28476af099aSliuyi memcpy(m_crc,m_BootData+(m_BootSize-4),4); 28576af099aSliuyi } 28676af099aSliuyi else 28776af099aSliuyi { 28876af099aSliuyi bCheck = false; 28976af099aSliuyi m_BootData=NULL; 29076af099aSliuyi } 29176af099aSliuyi } 29276af099aSliuyi void CRKBoot::WCHAR_To_wchar(WCHAR *src,wchar_t *dst,int len) 29376af099aSliuyi { 29476af099aSliuyi int i; 29576af099aSliuyi memset(dst,0,len*sizeof(wchar_t)); 29676af099aSliuyi for (i=0;i<len;i++) 29776af099aSliuyi { 29876af099aSliuyi memcpy(dst,src,2); 29976af099aSliuyi src++; 30076af099aSliuyi dst++; 30176af099aSliuyi } 30276af099aSliuyi } 30376af099aSliuyi void CRKBoot::WCHAR_To_char(WCHAR *src,char *dst,int len) 30476af099aSliuyi { 30576af099aSliuyi int i; 30676af099aSliuyi memset(dst,0,len*sizeof(char)); 30776af099aSliuyi for (i=0;i<len;i++) 30876af099aSliuyi { 30976af099aSliuyi memcpy(dst,src,1); 31076af099aSliuyi src++; 31176af099aSliuyi dst++; 31276af099aSliuyi } 31376af099aSliuyi } 31476af099aSliuyi 315