/* * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd * Seth Liu 2017.03.01 * * SPDX-License-Identifier: GPL-2.0+ */ #include "RKBoot.h" extern UINT CRC_32(PBYTE pData, UINT ulSize); bool CRKBoot::GetRc4DisableFlag() { return m_bRc4Disable; } bool CRKBoot::GetSignFlag() { return m_bSignFlag; } DWORD CRKBoot::GetVersion() { return m_version; } DWORD CRKBoot::GetMergeVersion() { return m_mergeVersion; } STRUCT_RKTIME CRKBoot::GetReleaseTime() { return m_releaseTime; } ENUM_RKDEVICE_TYPE CRKBoot::GetSupportDevice() { return m_supportDevice; } UCHAR CRKBoot::GetEntry471Count() { return m_471Count; } UCHAR CRKBoot::GetEntry472Count() { return m_472Count; } UCHAR CRKBoot::GetEntryLoaderCount() { return m_loaderCount; } bool CRKBoot::CrcCheck() { UINT*pOldCrc,ulNewCrc; pOldCrc = (UINT*)(m_BootData+(m_BootSize-4)); ulNewCrc = CRC_32(m_BootData,m_BootSize-4); return (*pOldCrc==ulNewCrc)?true:false; } bool CRKBoot::SaveEntryFile(ENUM_RKBOOTENTRY type,UCHAR ucIndex,string fileName) { DWORD dwOffset; UCHAR ucCount,ucSize; switch ( type ) { case ENTRY471: dwOffset = m_471Offset; ucCount = m_471Count; ucSize = m_471Size; break; case ENTRY472: dwOffset = m_472Offset; ucCount = m_472Count; ucSize = m_472Size; break; case ENTRYLOADER: dwOffset = m_loaderOffset; ucCount = m_loaderCount; ucSize = m_loaderSize; break; default: return false; } if (ucIndex >= ucCount) { return false; } PSTRUCT_RKBOOT_ENTRY pEntry; pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); FILE *file=NULL; file = fopen(fileName.c_str(),"wb+"); if ( !file ) { return false; } fwrite(m_BootData+pEntry->dwDataOffset,1,pEntry->dwDataSize,file); fclose(file); return true; } bool CRKBoot::GetEntryProperty(ENUM_RKBOOTENTRY type,UCHAR ucIndex,DWORD &dwSize,DWORD &dwDelay,char *pName) { DWORD dwOffset; UCHAR ucCount,ucSize; switch ( type ) { case ENTRY471: dwOffset = m_471Offset; ucCount = m_471Count; ucSize = m_471Size; break; case ENTRY472: dwOffset = m_472Offset; ucCount = m_472Count; ucSize = m_472Size; break; case ENTRYLOADER: dwOffset = m_loaderOffset; ucCount = m_loaderCount; ucSize = m_loaderSize;//Loader长度生成时已经512对齐 break; default: return false; } if (ucIndex >= ucCount) { return false; } PSTRUCT_RKBOOT_ENTRY pEntry; pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); dwDelay = pEntry->dwDataDelay; dwSize = pEntry->dwDataSize; if (pName) { WCHAR_To_char(pEntry->szName,pName,20); } return true; } bool CRKBoot::GetEntryData(ENUM_RKBOOTENTRY type,UCHAR ucIndex,PBYTE lpData) { DWORD dwOffset; UCHAR ucCount,ucSize; switch ( type ) { case ENTRY471: dwOffset = m_471Offset; ucCount = m_471Count; ucSize = m_471Size; break; case ENTRY472: dwOffset = m_472Offset; ucCount = m_472Count; ucSize = m_472Size; break; case ENTRYLOADER: dwOffset = m_loaderOffset; ucCount = m_loaderCount; ucSize = m_loaderSize; break; default: return false; } if (ucIndex >= ucCount) { return false; } PSTRUCT_RKBOOT_ENTRY pEntry; pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex)); memcpy(lpData,m_BootData+pEntry->dwDataOffset,pEntry->dwDataSize); return true; } char CRKBoot::GetIndexByName(ENUM_RKBOOTENTRY type,char *pName) { DWORD dwOffset; UCHAR ucCount,ucSize; switch ( type ) { case ENTRY471: dwOffset = m_471Offset; ucCount = m_471Count; ucSize = m_471Size; break; case ENTRY472: dwOffset = m_472Offset; ucCount = m_472Count; ucSize = m_472Size; break; case ENTRYLOADER: dwOffset = m_loaderOffset; ucCount = m_loaderCount; ucSize = m_loaderSize; break; default: return -1; } for (UCHAR i=0;iszName,szName,20); if (strcasecmp(pName,szName)==0) { return i; } } return -1; } CRKBoot::~CRKBoot() { if (m_BootData!=NULL) { delete []m_BootData; } } CRKBoot::CRKBoot(PBYTE lpBootData,DWORD dwBootSize,bool &bCheck) { Rc4DisableFlag.setContainer(this); Rc4DisableFlag.getter(&CRKBoot::GetRc4DisableFlag); SignFlag.setContainer(this); SignFlag.getter(&CRKBoot::GetSignFlag); Version.setContainer(this); Version.getter(&CRKBoot::GetVersion); MergeVersion.setContainer(this); MergeVersion.getter(&CRKBoot::GetMergeVersion); ReleaseTime.setContainer(this); ReleaseTime.getter(&CRKBoot::GetReleaseTime); SupportDevice.setContainer(this); SupportDevice.getter(&CRKBoot::GetSupportDevice); Entry471Count.setContainer(this); Entry471Count.getter(&CRKBoot::GetEntry471Count); Entry472Count.setContainer(this); Entry472Count.getter(&CRKBoot::GetEntry472Count); EntryLoaderCount.setContainer(this); EntryLoaderCount.getter(&CRKBoot::GetEntryLoaderCount); bCheck = true; if (lpBootData!=NULL) { m_BootData=lpBootData; m_BootSize=dwBootSize; bCheck=CrcCheck(); if (!bCheck) { return; } PSTRUCT_RKBOOT_HEAD pBootHead; pBootHead = (PSTRUCT_RKBOOT_HEAD)(m_BootData); if (( pBootHead->uiTag!=0x544F4F42)&&(pBootHead->uiTag!=0x2052444C)) { bCheck=false; return; } if (pBootHead->ucRc4Flag) { m_bRc4Disable = true; } else m_bRc4Disable = false; if (pBootHead->ucSignFlag=='S') { m_bSignFlag = true; } else m_bSignFlag = false; m_version = pBootHead->dwVersion; m_mergeVersion = pBootHead->dwMergeVersion; m_BootHeadSize = pBootHead->usSize; m_releaseTime.usYear = pBootHead->stReleaseTime.usYear; m_releaseTime.ucMonth = pBootHead->stReleaseTime.ucMonth; m_releaseTime.ucDay = pBootHead->stReleaseTime.ucDay; m_releaseTime.ucHour = pBootHead->stReleaseTime.ucHour; m_releaseTime.ucMinute = pBootHead->stReleaseTime.ucMinute; m_releaseTime.ucSecond = pBootHead->stReleaseTime.ucSecond; m_supportDevice = pBootHead->emSupportChip; m_471Offset = pBootHead->dw471EntryOffset; m_471Count = pBootHead->uc471EntryCount; m_471Size = pBootHead->uc471EntrySize; m_472Offset = pBootHead->dw472EntryOffset; m_472Count = pBootHead->uc472EntryCount; m_472Size = pBootHead->uc472EntrySize; m_loaderOffset = pBootHead->dwLoaderEntryOffset; m_loaderCount = pBootHead->ucLoaderEntryCount; m_loaderSize = pBootHead->ucLoaderEntrySize; memcpy(m_crc,m_BootData+(m_BootSize-4),4); } else { bCheck = false; m_BootData=NULL; } } void CRKBoot::WCHAR_To_wchar(WCHAR *src,wchar_t *dst,int len) { int i; memset(dst,0,len*sizeof(wchar_t)); for (i=0;i