xref: /rkdeveloptool/RKBoot.cpp (revision 21b25fd4a70331819b557fe93015b635b9594543)
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 }
18*21b25fd4SDave Murphy UINT CRKBoot::GetVersion()
1976af099aSliuyi {
2076af099aSliuyi 	return m_version;
2176af099aSliuyi }
22*21b25fd4SDave Murphy UINT 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);
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 }
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