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);
GetRc4DisableFlag()1076af099aSliuyi bool CRKBoot::GetRc4DisableFlag()
1176af099aSliuyi {
1276af099aSliuyi return m_bRc4Disable;
1376af099aSliuyi }
GetSignFlag()1476af099aSliuyi bool CRKBoot::GetSignFlag()
1576af099aSliuyi {
1676af099aSliuyi return m_bSignFlag;
1776af099aSliuyi }
GetVersion()18*21b25fd4SDave Murphy UINT CRKBoot::GetVersion()
1976af099aSliuyi {
2076af099aSliuyi return m_version;
2176af099aSliuyi }
GetMergeVersion()22*21b25fd4SDave Murphy UINT CRKBoot::GetMergeVersion()
2376af099aSliuyi {
2476af099aSliuyi return m_mergeVersion;
2576af099aSliuyi }
GetReleaseTime()2676af099aSliuyi STRUCT_RKTIME CRKBoot::GetReleaseTime()
2776af099aSliuyi {
2876af099aSliuyi return m_releaseTime;
2976af099aSliuyi }
GetSupportDevice()3076af099aSliuyi ENUM_RKDEVICE_TYPE CRKBoot::GetSupportDevice()
3176af099aSliuyi {
3276af099aSliuyi return m_supportDevice;
3376af099aSliuyi }
GetEntry471Count()3476af099aSliuyi UCHAR CRKBoot::GetEntry471Count()
3576af099aSliuyi {
3676af099aSliuyi return m_471Count;
3776af099aSliuyi }
GetEntry472Count()3876af099aSliuyi UCHAR CRKBoot::GetEntry472Count()
3976af099aSliuyi {
4076af099aSliuyi return m_472Count;
4176af099aSliuyi }
GetEntryLoaderCount()4276af099aSliuyi UCHAR CRKBoot::GetEntryLoaderCount()
4376af099aSliuyi {
4476af099aSliuyi return m_loaderCount;
4576af099aSliuyi }
CrcCheck()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 }
SaveEntryFile(ENUM_RKBOOTENTRY type,UCHAR ucIndex,string fileName)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 }
GetEntryProperty(ENUM_RKBOOTENTRY type,UCHAR ucIndex,DWORD & dwSize,DWORD & dwDelay,char * pName)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 }
GetEntryData(ENUM_RKBOOTENTRY type,UCHAR ucIndex,PBYTE lpData)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 }
GetIndexByName(ENUM_RKBOOTENTRY type,char * pName)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 }
~CRKBoot()20476af099aSliuyi CRKBoot::~CRKBoot()
20576af099aSliuyi {
20676af099aSliuyi if (m_BootData!=NULL)
20776af099aSliuyi {
20876af099aSliuyi delete []m_BootData;
20976af099aSliuyi }
21076af099aSliuyi }
21176af099aSliuyi
CRKBoot(PBYTE lpBootData,DWORD dwBootSize,bool & bCheck)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);
24446bb4c07Sliuyi 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 }
WCHAR_To_wchar(WCHAR * src,wchar_t * dst,int len)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 }
WCHAR_To_char(WCHAR * src,char * dst,int len)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