1 /*
2 * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
3 * Seth Liu 2017.03.01
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8 #include "RKBoot.h"
9 extern UINT CRC_32(PBYTE pData, UINT ulSize);
GetRc4DisableFlag()10 bool CRKBoot::GetRc4DisableFlag()
11 {
12 return m_bRc4Disable;
13 }
GetSignFlag()14 bool CRKBoot::GetSignFlag()
15 {
16 return m_bSignFlag;
17 }
GetVersion()18 UINT CRKBoot::GetVersion()
19 {
20 return m_version;
21 }
GetMergeVersion()22 UINT CRKBoot::GetMergeVersion()
23 {
24 return m_mergeVersion;
25 }
GetReleaseTime()26 STRUCT_RKTIME CRKBoot::GetReleaseTime()
27 {
28 return m_releaseTime;
29 }
GetSupportDevice()30 ENUM_RKDEVICE_TYPE CRKBoot::GetSupportDevice()
31 {
32 return m_supportDevice;
33 }
GetEntry471Count()34 UCHAR CRKBoot::GetEntry471Count()
35 {
36 return m_471Count;
37 }
GetEntry472Count()38 UCHAR CRKBoot::GetEntry472Count()
39 {
40 return m_472Count;
41 }
GetEntryLoaderCount()42 UCHAR CRKBoot::GetEntryLoaderCount()
43 {
44 return m_loaderCount;
45 }
CrcCheck()46 bool CRKBoot::CrcCheck()
47 {
48 UINT*pOldCrc,ulNewCrc;
49 pOldCrc = (UINT*)(m_BootData+(m_BootSize-4));
50 ulNewCrc = CRC_32(m_BootData,m_BootSize-4);
51 return (*pOldCrc==ulNewCrc)?true:false;
52 }
SaveEntryFile(ENUM_RKBOOTENTRY type,UCHAR ucIndex,string fileName)53 bool CRKBoot::SaveEntryFile(ENUM_RKBOOTENTRY type,UCHAR ucIndex,string fileName)
54 {
55 DWORD dwOffset;
56 UCHAR ucCount,ucSize;
57 switch ( type )
58 {
59 case ENTRY471:
60 dwOffset = m_471Offset;
61 ucCount = m_471Count;
62 ucSize = m_471Size;
63 break;
64 case ENTRY472:
65 dwOffset = m_472Offset;
66 ucCount = m_472Count;
67 ucSize = m_472Size;
68 break;
69 case ENTRYLOADER:
70 dwOffset = m_loaderOffset;
71 ucCount = m_loaderCount;
72 ucSize = m_loaderSize;
73 break;
74 default:
75 return false;
76 }
77 if (ucIndex >= ucCount)
78 {
79 return false;
80 }
81 PSTRUCT_RKBOOT_ENTRY pEntry;
82 pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex));
83 FILE *file=NULL;
84 file = fopen(fileName.c_str(),"wb+");
85 if ( !file )
86 {
87 return false;
88 }
89 fwrite(m_BootData+pEntry->dwDataOffset,1,pEntry->dwDataSize,file);
90 fclose(file);
91 return true;
92 }
GetEntryProperty(ENUM_RKBOOTENTRY type,UCHAR ucIndex,DWORD & dwSize,DWORD & dwDelay,char * pName)93 bool CRKBoot::GetEntryProperty(ENUM_RKBOOTENTRY type,UCHAR ucIndex,DWORD &dwSize,DWORD &dwDelay,char *pName)
94 {
95 DWORD dwOffset;
96 UCHAR ucCount,ucSize;
97 switch ( type )
98 {
99 case ENTRY471:
100 dwOffset = m_471Offset;
101 ucCount = m_471Count;
102 ucSize = m_471Size;
103 break;
104 case ENTRY472:
105 dwOffset = m_472Offset;
106 ucCount = m_472Count;
107 ucSize = m_472Size;
108 break;
109 case ENTRYLOADER:
110 dwOffset = m_loaderOffset;
111 ucCount = m_loaderCount;
112 ucSize = m_loaderSize;//Loader��������ʱ�Ѿ�512����
113 break;
114 default:
115 return false;
116 }
117 if (ucIndex >= ucCount)
118 {
119 return false;
120 }
121 PSTRUCT_RKBOOT_ENTRY pEntry;
122 pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex));
123 dwDelay = pEntry->dwDataDelay;
124 dwSize = pEntry->dwDataSize;
125 if (pName)
126 {
127 WCHAR_To_char(pEntry->szName,pName,20);
128 }
129 return true;
130 }
GetEntryData(ENUM_RKBOOTENTRY type,UCHAR ucIndex,PBYTE lpData)131 bool CRKBoot::GetEntryData(ENUM_RKBOOTENTRY type,UCHAR ucIndex,PBYTE lpData)
132 {
133 DWORD dwOffset;
134 UCHAR ucCount,ucSize;
135 switch ( type )
136 {
137 case ENTRY471:
138 dwOffset = m_471Offset;
139 ucCount = m_471Count;
140 ucSize = m_471Size;
141 break;
142 case ENTRY472:
143 dwOffset = m_472Offset;
144 ucCount = m_472Count;
145 ucSize = m_472Size;
146 break;
147 case ENTRYLOADER:
148 dwOffset = m_loaderOffset;
149 ucCount = m_loaderCount;
150 ucSize = m_loaderSize;
151 break;
152 default:
153 return false;
154 }
155 if (ucIndex >= ucCount)
156 {
157 return false;
158 }
159 PSTRUCT_RKBOOT_ENTRY pEntry;
160 pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*ucIndex));
161 memcpy(lpData,m_BootData+pEntry->dwDataOffset,pEntry->dwDataSize);
162 return true;
163 }
GetIndexByName(ENUM_RKBOOTENTRY type,char * pName)164 char CRKBoot::GetIndexByName(ENUM_RKBOOTENTRY type,char *pName)
165 {
166 DWORD dwOffset;
167 UCHAR ucCount,ucSize;
168 switch ( type )
169 {
170 case ENTRY471:
171 dwOffset = m_471Offset;
172 ucCount = m_471Count;
173 ucSize = m_471Size;
174 break;
175 case ENTRY472:
176 dwOffset = m_472Offset;
177 ucCount = m_472Count;
178 ucSize = m_472Size;
179 break;
180 case ENTRYLOADER:
181 dwOffset = m_loaderOffset;
182 ucCount = m_loaderCount;
183 ucSize = m_loaderSize;
184 break;
185 default:
186 return -1;
187 }
188
189 for (UCHAR i=0;i<ucCount;i++)
190 {
191 PSTRUCT_RKBOOT_ENTRY pEntry;
192 pEntry = (PSTRUCT_RKBOOT_ENTRY)(m_BootData+dwOffset+(ucSize*i));
193
194 char szName[20];
195 WCHAR_To_char(pEntry->szName,szName,20);
196
197 if (strcasecmp(pName,szName)==0)
198 {
199 return i;
200 }
201 }
202 return -1;
203 }
~CRKBoot()204 CRKBoot::~CRKBoot()
205 {
206 if (m_BootData!=NULL)
207 {
208 delete []m_BootData;
209 }
210 }
211
CRKBoot(PBYTE lpBootData,DWORD dwBootSize,bool & bCheck)212 CRKBoot::CRKBoot(PBYTE lpBootData,DWORD dwBootSize,bool &bCheck)
213 {
214 Rc4DisableFlag.setContainer(this);
215 Rc4DisableFlag.getter(&CRKBoot::GetRc4DisableFlag);
216 SignFlag.setContainer(this);
217 SignFlag.getter(&CRKBoot::GetSignFlag);
218 Version.setContainer(this);
219 Version.getter(&CRKBoot::GetVersion);
220 MergeVersion.setContainer(this);
221 MergeVersion.getter(&CRKBoot::GetMergeVersion);
222 ReleaseTime.setContainer(this);
223 ReleaseTime.getter(&CRKBoot::GetReleaseTime);
224 SupportDevice.setContainer(this);
225 SupportDevice.getter(&CRKBoot::GetSupportDevice);
226 Entry471Count.setContainer(this);
227 Entry471Count.getter(&CRKBoot::GetEntry471Count);
228 Entry472Count.setContainer(this);
229 Entry472Count.getter(&CRKBoot::GetEntry472Count);
230 EntryLoaderCount.setContainer(this);
231 EntryLoaderCount.getter(&CRKBoot::GetEntryLoaderCount);
232 bCheck = true;
233 if (lpBootData!=NULL)
234 {
235 m_BootData=lpBootData;
236 m_BootSize=dwBootSize;
237 bCheck=CrcCheck();
238 if (!bCheck)
239 {
240 return;
241 }
242 PSTRUCT_RKBOOT_HEAD pBootHead;
243 pBootHead = (PSTRUCT_RKBOOT_HEAD)(m_BootData);
244 if (( pBootHead->uiTag!=0x544F4F42)&&(pBootHead->uiTag!=0x2052444C))
245 {
246 bCheck=false;
247 return;
248 }
249 if (pBootHead->ucRc4Flag)
250 {
251 m_bRc4Disable = true;
252 }
253 else
254 m_bRc4Disable = false;
255 if (pBootHead->ucSignFlag=='S')
256 {
257 m_bSignFlag = true;
258 }
259 else
260 m_bSignFlag = false;
261 m_version = pBootHead->dwVersion;
262 m_mergeVersion = pBootHead->dwMergeVersion;
263 m_BootHeadSize = pBootHead->usSize;
264 m_releaseTime.usYear = pBootHead->stReleaseTime.usYear;
265 m_releaseTime.ucMonth = pBootHead->stReleaseTime.ucMonth;
266 m_releaseTime.ucDay = pBootHead->stReleaseTime.ucDay;
267 m_releaseTime.ucHour = pBootHead->stReleaseTime.ucHour;
268 m_releaseTime.ucMinute = pBootHead->stReleaseTime.ucMinute;
269 m_releaseTime.ucSecond = pBootHead->stReleaseTime.ucSecond;
270 m_supportDevice = pBootHead->emSupportChip;
271
272 m_471Offset = pBootHead->dw471EntryOffset;
273 m_471Count = pBootHead->uc471EntryCount;
274 m_471Size = pBootHead->uc471EntrySize;
275
276 m_472Offset = pBootHead->dw472EntryOffset;
277 m_472Count = pBootHead->uc472EntryCount;
278 m_472Size = pBootHead->uc472EntrySize;
279
280 m_loaderOffset = pBootHead->dwLoaderEntryOffset;
281 m_loaderCount = pBootHead->ucLoaderEntryCount;
282 m_loaderSize = pBootHead->ucLoaderEntrySize;
283
284 memcpy(m_crc,m_BootData+(m_BootSize-4),4);
285 }
286 else
287 {
288 bCheck = false;
289 m_BootData=NULL;
290 }
291 }
WCHAR_To_wchar(WCHAR * src,wchar_t * dst,int len)292 void CRKBoot::WCHAR_To_wchar(WCHAR *src,wchar_t *dst,int len)
293 {
294 int i;
295 memset(dst,0,len*sizeof(wchar_t));
296 for (i=0;i<len;i++)
297 {
298 memcpy(dst,src,2);
299 src++;
300 dst++;
301 }
302 }
WCHAR_To_char(WCHAR * src,char * dst,int len)303 void CRKBoot::WCHAR_To_char(WCHAR *src,char *dst,int len)
304 {
305 int i;
306 memset(dst,0,len*sizeof(char));
307 for (i=0;i<len;i++)
308 {
309 memcpy(dst,src,1);
310 src++;
311 dst++;
312 }
313 }
314
315