xref: /rkdeveloptool/RKBoot.cpp (revision 76af099afcbcafd97801028de2ba3421d3c12865)
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