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 <unistd.h>
9 #include <dirent.h>
10 #include "config.h"
11 #include "DefineHeader.h"
12 #include "gpt.h"
13 #include "RKLog.h"
14 #include "RKScan.h"
15 #include "RKComm.h"
16 #include "RKDevice.h"
17 #include "RKImage.h"
18 extern const char *szManufName[];
19 CRKLog *g_pLogObject=NULL;
20 CONFIG_ITEM_VECTOR g_ConfigItemVec;
21 #define DEFAULT_RW_LBA 128
22 #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
23 #define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
24 #define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
25 #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
26 #define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B);
27 #define NORMAL_COLOR_ATTR printf("%c[0m", 0x1B);
28 extern UINT CRC_32(unsigned char* pData, UINT ulSize);
29 extern unsigned short CRC_16(unsigned char* aData, UINT aSize);
30 extern void P_RC4(unsigned char* buf, unsigned short len);
31 extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len);
32 /*
33 u8 test_gpt_head[] = {
34 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B,
38 0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08};
40 */
41
usage()42 void usage()
43 {
44 printf("\r\n---------------------Tool Usage ---------------------\r\n");
45 printf("Help:\t\t\t-h or --help\r\n");
46 printf("Version:\t\t-v or --version\r\n");
47 printf("ListDevice:\t\tld\r\n");
48 printf("DownloadBoot:\t\tdb <Loader>\r\n");
49 printf("UpgradeLoader:\t\tul <Loader>\r\n");
50 printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n");
51 printf("WriteLBA:\t\twl <BeginSec> <File>\r\n");
52 printf("WriteLBA:\t\twlx <PartitionName> <File>\r\n");
53 printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
54 printf("WriteParameter:\t\tprm <parameter>\r\n");
55 printf("PrintPartition:\t\tppt \r\n");
56 printf("EraseFlash:\t\tef \r\n");
57 printf("TestDevice:\t\ttd\r\n");
58 printf("ResetDevice:\t\trd [subcode]\r\n");
59 printf("ChangeStorage:\t\tcs [storage: 1=EMMC, 2=SD, 9=SPINOR]\r\n");
60 printf("ReadFlashID:\t\trid\r\n");
61 printf("ReadFlashInfo:\t\trfi\r\n");
62 printf("ReadChipInfo:\t\trci\r\n");
63 printf("ReadCapability:\t\trcb\r\n");
64 printf("PackBootLoader:\t\tpack\r\n");
65 printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
66 printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
67 printf("-------------------------------------------------------\r\n\r\n");
68 }
ProgressInfoProc(UINT deviceLayer,ENUM_PROGRESS_PROMPT promptID,long long totalValue,long long currentValue,ENUM_CALL_STEP emCall)69 void ProgressInfoProc(UINT deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
70 {
71 string strInfoText="";
72 char szText[256];
73 switch (promptID) {
74 case TESTDEVICE_PROGRESS:
75 snprintf(szText, sizeof(szText), "Test Device total %lld, current %lld", totalValue, currentValue);
76 strInfoText = szText;
77 break;
78 case LOWERFORMAT_PROGRESS:
79 snprintf(szText, sizeof(szText), "Lowerformat Device total %lld, current %lld", totalValue, currentValue);
80 strInfoText = szText;
81 break;
82 case DOWNLOADIMAGE_PROGRESS:
83 snprintf(szText, sizeof(szText), "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
84 strInfoText = szText;
85 break;
86 case CHECKIMAGE_PROGRESS:
87 snprintf(szText, sizeof(szText), "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
88 strInfoText = szText;
89 break;
90 case TAGBADBLOCK_PROGRESS:
91 snprintf(szText, sizeof(szText), "Tag Bad Block total %lld, current %lld", totalValue, currentValue);
92 strInfoText = szText;
93 break;
94 case TESTBLOCK_PROGRESS:
95 snprintf(szText, sizeof(szText), "Test Block total %lld, current %lld", totalValue, currentValue);
96 strInfoText = szText;
97 break;
98 case ERASEFLASH_PROGRESS:
99 snprintf(szText, sizeof(szText), "Erase Flash total %lld, current %lld", totalValue, currentValue);
100 strInfoText = szText;
101 break;
102 case ERASESYSTEM_PROGRESS:
103 snprintf(szText, sizeof(szText), "Erase System partition total %lld, current %lld", totalValue, currentValue);
104 strInfoText = szText;
105 break;
106 case ERASEUSERDATA_PROGRESS:
107 snprintf(szText, sizeof(szText), "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue);
108 strInfoText = szText;
109 break;
110 }
111 if (strInfoText.size() > 0){
112 CURSOR_MOVEUP_LINE(1);
113 CURSOR_DEL_LINE;
114 printf("%s\r\n", strInfoText.c_str());
115 }
116 if (emCall == CALL_LAST)
117 deviceLayer = 0;
118 }
119
strupr(char * szSrc)120 char *strupr(char *szSrc)
121 {
122 char *p = szSrc;
123 while(*p){
124 if ((*p >= 'a') && (*p <= 'z'))
125 *p = *p - 'a' + 'A';
126 p++;
127 }
128 return szSrc;
129 }
PrintData(PBYTE pData,int nSize)130 void PrintData(PBYTE pData, int nSize)
131 {
132 char szPrint[17] = "\0";
133 int i;
134 for( i = 0; i < nSize; i++){
135 if(i % 16 == 0){
136 if(i / 16 > 0)
137 printf(" %s\r\n", szPrint);
138 printf("%08d ", i / 16);
139 }
140 printf("%02X ", pData[i]);
141 szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
142 }
143 if(i / 16 > 0)
144 printf(" %s\r\n", szPrint);
145 }
146
find_config_item(CONFIG_ITEM_VECTOR & vecItems,const char * pszName)147 int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName)
148 {
149 unsigned int i;
150 for(i = 0; i < vecItems.size(); i++){
151 if (strcasecmp(pszName, vecItems[i].szItemName) == 0){
152 return i;
153 }
154 }
155 return -1;
156 }
string_to_uuid(string strUUid,char * uuid)157 void string_to_uuid(string strUUid, char *uuid)
158 {
159 unsigned int i;
160 char value;
161 memset(uuid, 0, 16);
162 for (i =0; i < strUUid.size(); i++) {
163 value = 0;
164 if ((strUUid[i] >= '0')&&(strUUid[i] <= '9'))
165 value = strUUid[i] - '0';
166 if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f'))
167 value = strUUid[i] - 'a' + 10;
168 if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F'))
169 value = strUUid[i] - 'A' + 10;
170 if ((i % 2) == 0)
171 uuid[i / 2] += (value << 4);
172 else
173 uuid[i / 2] += value;
174 }
175 unsigned int *p32;
176 unsigned short *p16;
177 p32 = (unsigned int*)uuid;
178 *p32 = cpu_to_be32(*p32);
179 p16 = (unsigned short *)(uuid + 4);
180 *p16 = cpu_to_be16(*p16);
181 p16 = (unsigned short *)(uuid + 6);
182 *p16 = cpu_to_be16(*p16);
183 }
184
parse_config(char * pConfig,CONFIG_ITEM_VECTOR & vecItem)185 bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
186 {
187
188 stringstream configStream(pConfig);
189 string strLine, strItemName, strItemValue;
190 string::size_type line_size,pos;
191 STRUCT_CONFIG_ITEM item;
192 vecItem.clear();
193 while (!configStream.eof()){
194 getline(configStream, strLine);
195 line_size = strLine.size();
196 if (line_size == 0)
197 continue;
198 if (strLine[line_size-1] == '\r'){
199 strLine = strLine.substr(0, line_size-1);
200 }
201 strLine.erase(0, strLine.find_first_not_of(" "));
202 strLine.erase(strLine.find_last_not_of(" ") + 1);
203 if (strLine.size()==0 )
204 continue;
205 if (strLine[0] == '#')
206 continue;
207 pos = strLine.find("=");
208 if (pos == string::npos){
209 continue;
210 }
211 strItemName = strLine.substr(0, pos);
212 strItemValue = strLine.substr(pos + 1);
213 strItemName.erase(0, strItemName.find_first_not_of(" "));
214 strItemName.erase(strItemName.find_last_not_of(" ") + 1);
215 strItemValue.erase(0, strItemValue.find_first_not_of(" "));
216 strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
217 if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
218 strcpy(item.szItemName, strItemName.c_str());
219 strcpy(item.szItemValue, strItemValue.c_str());
220 vecItem.push_back(item);
221 }
222 }
223 return true;
224
225 }
parse_config_file(const char * pConfigFile,CONFIG_ITEM_VECTOR & vecItem)226 bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
227 {
228 FILE *file = NULL;
229 file = fopen(pConfigFile, "rb");
230 if( !file ){
231 if (g_pLogObject)
232 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile);
233 return false;
234 }
235 int iFileSize;
236 fseek(file, 0, SEEK_END);
237 iFileSize = ftell(file);
238 fseek(file, 0, SEEK_SET);
239 char *pConfigBuf = NULL;
240 pConfigBuf = new char[iFileSize + 1];
241 if (!pConfigBuf){
242 fclose(file);
243 return false;
244 }
245 memset(pConfigBuf, 0, iFileSize + 1);
246 int iRead;
247 iRead = fread(pConfigBuf, 1, iFileSize, file);
248 if (iRead != iFileSize){
249 if (g_pLogObject)
250 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize);
251 fclose(file);
252 delete []pConfigBuf;
253 return false;
254 }
255 fclose(file);
256 bool bRet;
257 bRet = parse_config(pConfigBuf, vecItem);
258 delete []pConfigBuf;
259 return bRet;
260 }
ParsePartitionInfo(string & strPartInfo,string & strName,UINT & uiOffset,UINT & uiLen)261 bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
262 {
263 string::size_type pos,prevPos;
264 string strOffset,strLen;
265 int iCount;
266 prevPos = pos = 0;
267 if (strPartInfo.size() <= 0) {
268 return false;
269 }
270 pos = strPartInfo.find('@');
271 if (pos == string::npos) {
272 return false;
273 }
274 strLen = strPartInfo.substr(prevPos, pos - prevPos);
275 strLen.erase(0, strLen.find_first_not_of(" "));
276 strLen.erase(strLen.find_last_not_of(" ") + 1);
277 if (strchr(strLen.c_str(), '-')) {
278 uiLen = 0xFFFFFFFF;
279 } else {
280 iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
281 if (iCount != 1) {
282 return false;
283 }
284 }
285
286 prevPos = pos + 1;
287 pos = strPartInfo.find('(',prevPos);
288 if (pos == string::npos) {
289 return false;
290 }
291 strOffset = strPartInfo.substr(prevPos, pos - prevPos);
292 strOffset.erase(0, strOffset.find_first_not_of(" "));
293 strOffset.erase(strOffset.find_last_not_of(" ") + 1);
294 iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
295 if (iCount != 1) {
296 return false;
297 }
298 prevPos = pos + 1;
299 pos = strPartInfo.find(')', prevPos);
300 if (pos == string::npos) {
301 return false;
302 }
303 strName = strPartInfo.substr(prevPos, pos - prevPos);
304 strName.erase(0, strName.find_first_not_of(" "));
305 strName.erase(strName.find_last_not_of(" ") + 1);
306
307 return true;
308 }
ParseUuidInfo(string & strUuidInfo,string & strName,string & strUUid)309 bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid)
310 {
311 string::size_type pos(0);
312
313 if (strUuidInfo.size() <= 0) {
314 return false;
315 }
316 pos = strUuidInfo.find('=');
317 if (pos == string::npos) {
318 return false;
319 }
320 strName = strUuidInfo.substr(0, pos);
321 strName.erase(0, strName.find_first_not_of(" "));
322 strName.erase(strName.find_last_not_of(" ") + 1);
323
324 strUUid = strUuidInfo.substr(pos+1);
325 strUUid.erase(0, strUUid.find_first_not_of(" "));
326 strUUid.erase(strUUid.find_last_not_of(" ") + 1);
327
328 while(true) {
329 pos = 0;
330 if( (pos = strUUid.find("-")) != string::npos)
331 strUUid.replace(pos,1,"");
332 else
333 break;
334 }
335 if (strUUid.size() != 32)
336 return false;
337 return true;
338 }
339
340
parse_parameter(char * pParameter,PARAM_ITEM_VECTOR & vecItem,CONFIG_ITEM_VECTOR & vecUuidItem)341 bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
342 {
343 stringstream paramStream(pParameter);
344 bool bRet,bFind = false;
345 string strLine, strPartition, strPartInfo, strPartName, strUUid;
346 string::size_type line_size, pos, posColon, posComma;
347 UINT uiPartOffset, uiPartSize;
348 STRUCT_PARAM_ITEM item;
349 STRUCT_CONFIG_ITEM uuid_item;
350 vecItem.clear();
351 vecUuidItem.clear();
352 while (!paramStream.eof()) {
353 getline(paramStream,strLine);
354 line_size = strLine.size();
355 if (line_size == 0)
356 continue;
357 if (strLine[line_size - 1] == '\r'){
358 strLine = strLine.substr(0, line_size - 1);
359 }
360 strLine.erase(0, strLine.find_first_not_of(" "));
361 strLine.erase(strLine.find_last_not_of(" ") + 1);
362 if (strLine.size()==0 )
363 continue;
364 if (strLine[0] == '#')
365 continue;
366 pos = strLine.find("uuid:");
367 if (pos != string::npos) {
368 strPartInfo = strLine.substr(pos+5);
369 bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid);
370 if (bRet) {
371 strcpy(uuid_item.szItemName, strPartName.c_str());
372 string_to_uuid(strUUid,uuid_item.szItemValue);
373 vecUuidItem.push_back(uuid_item);
374 }
375 continue;
376 }
377
378 pos = strLine.find("mtdparts");
379 if (pos == string::npos) {
380 continue;
381 }
382 bFind = true;
383 posColon = strLine.find(':', pos);
384 if (posColon == string::npos) {
385 continue;
386 }
387 strPartition = strLine.substr(posColon + 1);
388 pos = 0;
389 posComma = strPartition.find(',', pos);
390 while (posComma != string::npos) {
391 strPartInfo = strPartition.substr(pos, posComma - pos);
392 bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
393 if (bRet) {
394 strcpy(item.szItemName, strPartName.c_str());
395 item.uiItemOffset = uiPartOffset;
396 item.uiItemSize = uiPartSize;
397 vecItem.push_back(item);
398 }
399 pos = posComma + 1;
400 posComma = strPartition.find(',', pos);
401 }
402 strPartInfo = strPartition.substr(pos);
403 if (strPartInfo.size() > 0) {
404 bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
405 if (bRet) {
406 strcpy(item.szItemName, strPartName.c_str());
407 item.uiItemOffset = uiPartOffset;
408 item.uiItemSize = uiPartSize;
409 vecItem.push_back(item);
410 }
411 }
412 }
413 return bFind;
414
415 }
parse_parameter_file(char * pParamFile,PARAM_ITEM_VECTOR & vecItem,CONFIG_ITEM_VECTOR & vecUuidItem)416 bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
417 {
418 FILE *file = NULL;
419 file = fopen(pParamFile, "rb");
420 if( !file ) {
421 if (g_pLogObject)
422 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
423 return false;
424 }
425 int iFileSize;
426 fseek(file, 0, SEEK_END);
427 iFileSize = ftell(file);
428 fseek(file, 0, SEEK_SET);
429 char *pParamBuf = NULL;
430 pParamBuf = new char[iFileSize];
431 if (!pParamBuf) {
432 fclose(file);
433 return false;
434 }
435 int iRead;
436 iRead = fread(pParamBuf, 1, iFileSize, file);
437 if (iRead != iFileSize) {
438 if (g_pLogObject)
439 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
440 fclose(file);
441 delete []pParamBuf;
442 return false;
443 }
444 fclose(file);
445 bool bRet;
446 bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem);
447 delete []pParamBuf;
448 return bRet;
449 }
is_sparse_image(char * szImage)450 bool is_sparse_image(char *szImage)
451 {
452 FILE *file = NULL;
453 sparse_header head;
454 u32 uiRead;
455 file = fopen(szImage, "rb");
456 if( !file ) {
457 if (g_pLogObject)
458 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
459 return false;
460 }
461 uiRead = fread(&head, 1, sizeof(head), file);
462 if (uiRead != sizeof(head)) {
463 if (g_pLogObject)
464 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head));
465 fclose(file);
466 return false;
467 }
468 fclose(file);
469 if (head.magic!=SPARSE_HEADER_MAGIC)
470 {
471 return false;
472 }
473 return true;
474
475 }
is_ubifs_image(char * szImage)476 bool is_ubifs_image(char *szImage)
477 {
478 FILE *file = NULL;
479 u32 magic;
480 u32 uiRead;
481 file = fopen(szImage, "rb");
482 if( !file ) {
483 if (g_pLogObject)
484 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
485 return false;
486 }
487 uiRead = fread(&magic, 1, sizeof(magic), file);
488 if (uiRead != sizeof(magic)) {
489 if (g_pLogObject)
490 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(magic));
491 fclose(file);
492 return false;
493 }
494 fclose(file);
495 if (magic!=UBI_HEADER_MAGIC)
496 {
497 return false;
498 }
499 return true;
500 }
gen_rand_uuid(unsigned char * uuid_bin)501 void gen_rand_uuid(unsigned char *uuid_bin)
502 {
503 efi_guid_t id;
504 unsigned int *ptr = (unsigned int *)&id;
505 unsigned int i;
506
507 /* Set all fields randomly */
508 for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
509 *(ptr + i) = cpu_to_be32(rand());
510
511 id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
512 id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
513
514 memcpy(uuid_bin, id.raw, sizeof(id));
515 }
516
prepare_gpt_backup(u8 * master,u8 * backup)517 void prepare_gpt_backup(u8 *master, u8 *backup)
518 {
519 gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
520 gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
521 u32 calc_crc32;
522 u64 val;
523
524 /* recalculate the values for the Backup GPT Header */
525 val = le64_to_cpu(gptMasterHead->my_lba);
526 gptBackupHead->my_lba = gptMasterHead->alternate_lba;
527 gptBackupHead->alternate_lba = cpu_to_le64(val);
528 gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
529 gptBackupHead->header_crc32 = 0;
530
531 calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
532 gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
533 }
get_lba_from_gpt(u8 * master,char * pszName,u64 * lba,u64 * lba_end)534 bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end)
535 {
536 gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
537 gpt_entry *gptEntry = NULL;
538 u32 i,j;
539 u8 zerobuf[GPT_ENTRY_SIZE];
540 bool bFound = false;
541 memset(zerobuf,0,GPT_ENTRY_SIZE);
542
543 for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
544 gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
545 if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
546 break;
547 for (j = 0; j < strlen(pszName); j++)
548 if (gptEntry->partition_name[j] != pszName[j])
549 break;
550 if (gptEntry->partition_name[j] != 0)
551 continue;
552 if (j == strlen(pszName)) {
553 bFound = true;
554 break;
555 }
556 }
557 if (bFound) {
558 *lba = le64_to_cpu(gptEntry->starting_lba);
559 if (gptMasterHead->last_usable_lba == gptEntry->ending_lba)
560 *lba_end = 0xFFFFFFFF;
561 else
562 *lba_end = le64_to_cpu(gptEntry->ending_lba);
563 return true;
564 }
565 return false;
566 }
get_lba_from_param(u8 * param,char * pszName,u32 * part_offset,u32 * part_size)567 bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size)
568 {
569 u32 i;
570 bool bFound = false, bRet;
571 PARAM_ITEM_VECTOR vecItem;
572 CONFIG_ITEM_VECTOR vecUuid;
573
574 bRet = parse_parameter((char *)param, vecItem, vecUuid);
575 if (!bRet)
576 return false;
577
578 for (i = 0; i < vecItem.size(); i++) {
579 if (strcasecmp(pszName, vecItem[i].szItemName)==0) {
580 bFound = true;
581 break;
582 }
583 }
584 if (bFound) {
585 *part_offset = vecItem[i].uiItemOffset;
586 *part_size = vecItem[i].uiItemSize;
587 return true;
588 }
589 return false;
590 }
591
update_gpt_disksize(u8 * master,u8 * backup,u32 total_sector)592 void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector)
593 {
594 gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
595 gpt_entry *gptLastPartEntry = NULL;
596 u32 i;
597 u64 old_disksize;
598 u8 zerobuf[GPT_ENTRY_SIZE];
599
600 memset(zerobuf,0,GPT_ENTRY_SIZE);
601 old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1;
602 for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
603 gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
604 if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0)
605 break;
606 }
607 i--;
608 gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry));
609
610 gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1);
611 gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34);
612
613 if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition
614 gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34);
615 gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
616 }
617 gptMasterHead->header_crc32 = 0;
618 gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header)));
619 memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS);
620 memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE);
621 prepare_gpt_backup(master, backup);
622
623 }
load_gpt_buffer(char * pParamFile,u8 * master,u8 * backup)624 bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup)
625 {
626 FILE *file = NULL;
627 file = fopen(pParamFile, "rb");
628 if( !file ) {
629 if (g_pLogObject)
630 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
631 return false;
632 }
633 int iFileSize;
634 fseek(file, 0, SEEK_END);
635 iFileSize = ftell(file);
636 fseek(file, 0, SEEK_SET);
637 if (iFileSize != 67 * SECTOR_SIZE) {
638 if (g_pLogObject)
639 g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile);
640 fclose(file);
641 return false;
642 }
643
644 int iRead;
645 iRead = fread(master, 1, 34 * SECTOR_SIZE, file);
646 if (iRead != 34 * SECTOR_SIZE) {
647 if (g_pLogObject)
648 g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE);
649 fclose(file);
650 return false;
651 }
652 iRead = fread(backup, 1, 33 * SECTOR_SIZE, file);
653 if (iRead != 33 * SECTOR_SIZE) {
654 if (g_pLogObject)
655 g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE);
656 fclose(file);
657 return false;
658 }
659 fclose(file);
660 return true;
661 }
create_gpt_buffer(u8 * gpt,PARAM_ITEM_VECTOR & vecParts,CONFIG_ITEM_VECTOR & vecUuid,u64 diskSectors)662 void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
663 {
664 legacy_mbr *mbr = (legacy_mbr *)gpt;
665 gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
666 gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
667 u32 i,j;
668 int pos;
669 string strPartName;
670 string::size_type colonPos;
671 /*1.protective mbr*/
672 memset(gpt, 0, SECTOR_SIZE);
673 mbr->signature = MSDOS_MBR_SIGNATURE;
674 mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
675 mbr->partition_record[0].start_sect = 1;
676 mbr->partition_record[0].nr_sects = (u32)-1;
677 /*2.gpt header*/
678 memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
679 gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
680 gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
681 gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
682 gptHead->my_lba = cpu_to_le64(1);
683 gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
684 gptHead->first_usable_lba = cpu_to_le64(34);
685 gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
686 gptHead->partition_entry_lba = cpu_to_le64(2);
687 gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
688 gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
689 gptHead->header_crc32 = 0;
690 gptHead->partition_entry_array_crc32 = 0;
691 gen_rand_uuid(gptHead->disk_guid.raw);
692
693 /*3.gpt partition entry*/
694 memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
695 for (i = 0; i < vecParts.size(); i++) {
696 gen_rand_uuid(gptEntry->partition_type_guid.raw);
697 gen_rand_uuid(gptEntry->unique_partition_guid.raw);
698 gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
699 gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
700 gptEntry->attributes.raw = 0;
701 strPartName = vecParts[i].szItemName;
702 colonPos = strPartName.find_first_of(':');
703 if (colonPos != string::npos) {
704 if (strPartName.find("bootable") != string::npos)
705 gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
706 if (strPartName.find("grow") != string::npos)
707 gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
708 strPartName = strPartName.substr(0, colonPos);
709 vecParts[i].szItemName[strPartName.size()] = 0;
710 }
711 for (j = 0; j < strlen(vecParts[i].szItemName); j++)
712 gptEntry->partition_name[j] = vecParts[i].szItemName[j];
713 if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1)
714 memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
715 gptEntry++;
716 }
717
718 gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
719 gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
720
721 }
MakeSector0(PBYTE pSector,USHORT usFlashDataSec,USHORT usFlashBootSec,bool rc4Flag)722 bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
723 {
724 PRK28_IDB_SEC0 pSec0;
725 memset(pSector, 0, SECTOR_SIZE);
726 pSec0 = (PRK28_IDB_SEC0)pSector;
727
728 pSec0->dwTag = 0x0FF0AA55;
729 pSec0->uiRc4Flag = rc4Flag;
730 pSec0->usBootCode1Offset = 0x4;
731 pSec0->usBootCode2Offset = 0x4;
732 pSec0->usBootDataSize = usFlashDataSec;
733 pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
734 return true;
735 }
736
737
MakeSector1(PBYTE pSector)738 bool MakeSector1(PBYTE pSector)
739 {
740 PRK28_IDB_SEC1 pSec1;
741 memset(pSector, 0, SECTOR_SIZE);
742 pSec1 = (PRK28_IDB_SEC1)pSector;
743
744 pSec1->usSysReservedBlock = 0xC;
745 pSec1->usDisk0Size = 0xFFFF;
746 pSec1->uiChipTag = 0x38324B52;
747 return true;
748 }
749
MakeSector2(PBYTE pSector)750 bool MakeSector2(PBYTE pSector)
751 {
752 PRK28_IDB_SEC2 pSec2;
753 memset(pSector, 0, SECTOR_SIZE);
754 pSec2 = (PRK28_IDB_SEC2)pSector;
755
756 strcpy(pSec2->szVcTag, "VC");
757 strcpy(pSec2->szCrcTag, "CRC");
758 return true;
759 }
760
MakeSector3(PBYTE pSector)761 bool MakeSector3(PBYTE pSector)
762 {
763 memset(pSector,0,SECTOR_SIZE);
764 return true;
765 }
766
MakeIDBlockData(PBYTE pDDR,PBYTE pLoader,PBYTE lpIDBlock,USHORT usFlashDataSec,USHORT usFlashBootSec,DWORD dwLoaderDataSize,DWORD dwLoaderSize,bool rc4Flag)767 int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
768 {
769 RK28_IDB_SEC0 sector0Info;
770 RK28_IDB_SEC1 sector1Info;
771 RK28_IDB_SEC2 sector2Info;
772 RK28_IDB_SEC3 sector3Info;
773 UINT i;
774 MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
775 MakeSector1((PBYTE)§or1Info);
776 if (!MakeSector2((PBYTE)§or2Info)) {
777 return -6;
778 }
779 if (!MakeSector3((PBYTE)§or3Info)) {
780 return -7;
781 }
782 sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE);
783 sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE);
784 sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE);
785
786 memcpy(lpIDBlock, §or0Info, SECTOR_SIZE);
787 memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE);
788 memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE);
789
790 if (rc4Flag) {
791 for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
792 P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
793 for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
794 P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
795 }
796
797 memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
798 memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
799
800 sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
801 memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE);
802 for(i = 0; i < 4; i++) {
803 if(i == 1) {
804 continue;
805 } else {
806 P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
807 }
808 }
809 return 0;
810 }
811
812
813
check_device_type(STRUCT_RKDEVICE_DESC & dev,UINT uiSupportType)814 bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
815 {
816 if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType)
817 return true;
818 else
819 {
820 ERROR_COLOR_ATTR;
821 printf("The device does not support this operation!");
822 NORMAL_COLOR_ATTR;
823 printf("\r\n");
824 return false;
825 }
826 }
MakeParamBuffer(char * pParamFile,char * & pParamData)827 bool MakeParamBuffer(char *pParamFile, char* &pParamData)
828 {
829 FILE *file=NULL;
830 file = fopen(pParamFile, "rb");
831 if( !file )
832 {
833 if (g_pLogObject)
834 g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile);
835 return false;
836 }
837 int iFileSize;
838 fseek(file,0,SEEK_END);
839 iFileSize = ftell(file);
840 fseek(file,0,SEEK_SET);
841 char *pParamBuf=NULL;
842 pParamBuf = new char[iFileSize + 12];
843 if (!pParamBuf)
844 {
845 fclose(file);
846 return false;
847 }
848 memset(pParamBuf,0,iFileSize+12);
849 *(UINT *)(pParamBuf) = 0x4D524150;
850
851 int iRead;
852 iRead = fread(pParamBuf+8,1,iFileSize,file);
853 if (iRead!=iFileSize)
854 {
855 if (g_pLogObject)
856 g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize);
857 fclose(file);
858 delete []pParamBuf;
859 return false;
860 }
861 fclose(file);
862
863 *(UINT *)(pParamBuf+4) = iFileSize;
864 *(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize);
865 pParamData = pParamBuf;
866 return true;
867 }
868
write_parameter(STRUCT_RKDEVICE_DESC & dev,char * szParameter)869 bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
870 {
871 CRKComm *pComm = NULL;
872 char *pParamBuf = NULL, writeBuf[512*1024];
873 int iRet, nParamSec, nParamSize;
874 bool bRet, bSuccess = false;
875 if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER))
876 return false;
877
878 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
879 if (!bRet) {
880 ERROR_COLOR_ATTR;
881 printf("Creating Comm Object failed!");
882 NORMAL_COLOR_ATTR;
883 printf("\r\n");
884 return bSuccess;
885 }
886 if (!MakeParamBuffer(szParameter, pParamBuf)) {
887 ERROR_COLOR_ATTR;
888 printf("Generating parameter failed!");
889 NORMAL_COLOR_ATTR;
890 printf("\r\n");
891 return bSuccess;
892 }
893 printf("Writing parameter...\r\n");
894 nParamSize = *(UINT *)(pParamBuf+4) + 12;
895 nParamSec = BYTE2SECTOR(nParamSize);
896 if (nParamSec > 1024) {
897 ERROR_COLOR_ATTR;
898 printf("parameter is too large!");
899 NORMAL_COLOR_ATTR;
900 printf("\r\n");
901 return bSuccess;
902 }
903 memset(writeBuf, 0, nParamSec*512);
904 memcpy(writeBuf, pParamBuf, nParamSize);
905 iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf);
906 if (iRet != ERR_SUCCESS) {
907 ERROR_COLOR_ATTR;
908 printf("Writing parameter failed!");
909 NORMAL_COLOR_ATTR;
910 printf("\r\n");
911 return bSuccess;
912 }
913
914 bSuccess = true;
915 CURSOR_MOVEUP_LINE(1);
916 CURSOR_DEL_LINE;
917 printf("Writing parameter succeeded.\r\n");
918 return bSuccess;
919 }
920
write_gpt(STRUCT_RKDEVICE_DESC & dev,char * szParameter)921 bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
922 {
923 u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
924 u32 total_size_sector;
925 CRKComm *pComm = NULL;
926 PARAM_ITEM_VECTOR vecItems;
927 CONFIG_ITEM_VECTOR vecUuid;
928 int iRet;
929 bool bRet, bSuccess = false;
930 if (!check_device_type(dev, RKUSB_MASKROM))
931 return false;
932
933 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
934 if (!bRet) {
935 ERROR_COLOR_ATTR;
936 printf("Creating Comm Object failed!");
937 NORMAL_COLOR_ATTR;
938 printf("\r\n");
939 return bSuccess;
940 }
941 printf("Writing gpt...\r\n");
942 //1.get flash info
943 iRet = pComm->RKU_ReadFlashInfo(flash_info);
944 if (iRet != ERR_SUCCESS) {
945 ERROR_COLOR_ATTR;
946 printf("Reading Flash Info failed!");
947 NORMAL_COLOR_ATTR;
948 printf("\r\n");
949 return bSuccess;
950 }
951 total_size_sector = *(u32 *)flash_info;
952 if (strstr(szParameter, ".img")) {
953 if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) {
954 ERROR_COLOR_ATTR;
955 printf("Loading partition image failed!");
956 NORMAL_COLOR_ATTR;
957 printf("\r\n");
958 return bSuccess;
959 }
960 update_gpt_disksize(master_gpt, backup_gpt, total_size_sector);
961 } else {
962 //2.get partition from parameter
963 bRet = parse_parameter_file(szParameter, vecItems, vecUuid);
964 if (!bRet) {
965 ERROR_COLOR_ATTR;
966 printf("Parsing parameter failed!");
967 NORMAL_COLOR_ATTR;
968 printf("\r\n");
969 return bSuccess;
970 }
971 //3.generate gpt info
972 create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector);
973 memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
974 memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
975 prepare_gpt_backup(master_gpt, backup_gpt);
976 }
977
978 //4. write gpt
979 iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
980 if (iRet != ERR_SUCCESS) {
981 ERROR_COLOR_ATTR;
982 printf("Writing master gpt failed!");
983 NORMAL_COLOR_ATTR;
984 printf("\r\n");
985 return bSuccess;
986 }
987 iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt);
988 if (iRet != ERR_SUCCESS) {
989 ERROR_COLOR_ATTR;
990 printf("Writing backup gpt failed!");
991 NORMAL_COLOR_ATTR;
992 printf("\r\n");
993 return bSuccess;
994 }
995
996 bSuccess = true;
997 CURSOR_MOVEUP_LINE(1);
998 CURSOR_DEL_LINE;
999 printf("Writing gpt succeeded.\r\n");
1000 return bSuccess;
1001 }
1002
1003 #include "boot_merger.h"
1004 #define ENTRY_ALIGN (2048)
1005 options gOpts;
1006
1007
1008 char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
1009 char* gConfigPath;
1010 uint8_t gBuf[MAX_MERGE_SIZE];
1011
fixPath(char * path)1012 static inline void fixPath(char* path) {
1013 int i, len = strlen(path);
1014 for(i=0; i<len; i++) {
1015 if (path[i] == '\\')
1016 path[i] = '/';
1017 else if (path[i] == '\r' || path[i] == '\n')
1018 path[i] = '\0';
1019 }
1020 }
1021
parseChip(FILE * file)1022 static bool parseChip(FILE* file) {
1023 if (SCANF_EAT(file) != 0) {
1024 return false;
1025 }
1026 if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
1027 return false;
1028 }
1029 printf("chip: %s\n", gOpts.chip);
1030 return true;
1031 }
1032
parseVersion(FILE * file)1033 static bool parseVersion(FILE* file) {
1034 if (SCANF_EAT(file) != 0) {
1035 return false;
1036 }
1037 if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
1038 return false;
1039 if (SCANF_EAT(file) != 0) {
1040 return false;
1041 }
1042 if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
1043 return false;
1044 printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
1045 return true;
1046 }
1047
parse471(FILE * file)1048 static bool parse471(FILE* file) {
1049 int i, index, pos;
1050 char buf[MAX_LINE_LEN];
1051
1052 if (SCANF_EAT(file) != 0) {
1053 return false;
1054 }
1055 if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
1056 return false;
1057 printf("num: %d\n", gOpts.code471Num);
1058 if (!gOpts.code471Num)
1059 return true;
1060 if (gOpts.code471Num < 0)
1061 return false;
1062 gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
1063 for (i=0; i<gOpts.code471Num; i++) {
1064 if (SCANF_EAT(file) != 0) {
1065 return false;
1066 }
1067 if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
1068 != 2)
1069 return false;
1070 index--;
1071 fixPath(buf);
1072 strcpy((char*)gOpts.code471Path[index], buf);
1073 printf("path%i: %s\n", index, gOpts.code471Path[index]);
1074 }
1075 pos = ftell(file);
1076 if (SCANF_EAT(file) != 0) {
1077 return false;
1078 }
1079 if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
1080 fseek(file, pos, SEEK_SET);
1081 printf("sleep: %d\n", gOpts.code471Sleep);
1082 return true;
1083 }
1084
parse472(FILE * file)1085 static bool parse472(FILE* file) {
1086 int i, index, pos;
1087 char buf[MAX_LINE_LEN];
1088
1089 if (SCANF_EAT(file) != 0) {
1090 return false;
1091 }
1092 if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
1093 return false;
1094 printf("num: %d\n", gOpts.code472Num);
1095 if (!gOpts.code472Num)
1096 return true;
1097 if (gOpts.code472Num < 0)
1098 return false;
1099 gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
1100 for (i=0; i<gOpts.code472Num; i++) {
1101 if (SCANF_EAT(file) != 0) {
1102 return false;
1103 }
1104 if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
1105 != 2)
1106 return false;
1107 fixPath(buf);
1108 index--;
1109 strcpy((char*)gOpts.code472Path[index], buf);
1110 printf("path%i: %s\n", index, gOpts.code472Path[index]);
1111 }
1112 pos = ftell(file);
1113 if (SCANF_EAT(file) != 0) {
1114 return false;
1115 }
1116 if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
1117 fseek(file, pos, SEEK_SET);
1118 printf("sleep: %d\n", gOpts.code472Sleep);
1119 return true;
1120 }
1121
parseLoader(FILE * file)1122 static bool parseLoader(FILE* file) {
1123 int i, j, index, pos;
1124 char buf[MAX_LINE_LEN];
1125 char buf2[MAX_LINE_LEN];
1126
1127 if (SCANF_EAT(file) != 0) {
1128 return false;
1129 }
1130 pos = ftell(file);
1131 if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
1132 fseek(file, pos, SEEK_SET);
1133 if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
1134 return false;
1135 }
1136 }
1137 printf("num: %d\n", gOpts.loaderNum);
1138 if (!gOpts.loaderNum)
1139 return false;
1140 if (gOpts.loaderNum < 0)
1141 return false;
1142 gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
1143 for (i=0; i<gOpts.loaderNum; i++) {
1144 if (SCANF_EAT(file) != 0) {
1145 return false;
1146 }
1147 if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
1148 != 2)
1149 return false;
1150 strcpy(gOpts.loader[index].name, buf);
1151 printf("name%d: %s\n", index, gOpts.loader[index].name);
1152 index++;
1153 }
1154 for (i=0; i<gOpts.loaderNum; i++) {
1155 if (SCANF_EAT(file) != 0) {
1156 return false;
1157 }
1158 if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
1159 != 2)
1160 return false;
1161 for (j=0; j<gOpts.loaderNum; j++) {
1162 if (!strcmp(gOpts.loader[j].name, buf)) {
1163 fixPath(buf2);
1164 strcpy(gOpts.loader[j].path, buf2);
1165 printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
1166 break;
1167 }
1168 }
1169 if (j >= gOpts.loaderNum) {
1170 return false;
1171 }
1172 }
1173 return true;
1174 }
1175
parseOut(FILE * file)1176 static bool parseOut(FILE* file) {
1177 if (SCANF_EAT(file) != 0) {
1178 return false;
1179 }
1180 if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
1181 return false;
1182 fixPath(gOpts.outPath);
1183 printf("out: %s\n", gOpts.outPath);
1184 return true;
1185 }
1186
1187
printOpts(FILE * out)1188 void printOpts(FILE* out) {
1189 int i;
1190 fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
1191 fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
1192 "=%d\n", gOpts.major, gOpts.minor);
1193
1194 fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
1195 for (i=0 ;i<gOpts.code471Num ;i++) {
1196 fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
1197 }
1198 if (gOpts.code471Sleep > 0)
1199 fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
1200
1201 fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
1202 for (i=0 ;i<gOpts.code472Num ;i++) {
1203 fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
1204 }
1205 if (gOpts.code472Sleep > 0)
1206 fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
1207
1208 fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
1209 for (i=0 ;i<gOpts.loaderNum ;i++) {
1210 fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
1211 }
1212 for (i=0 ;i<gOpts.loaderNum ;i++) {
1213 fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
1214 }
1215
1216 fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
1217 }
1218
parseOpts(void)1219 static bool parseOpts(void) {
1220 bool ret = false;
1221 bool chipOk = false;
1222 bool versionOk = false;
1223 bool code471Ok = true;
1224 bool code472Ok = true;
1225 bool loaderOk = false;
1226 bool outOk = false;
1227 char buf[MAX_LINE_LEN];
1228
1229 char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
1230 FILE* file;
1231 file = fopen(configPath, "r");
1232 if (!file) {
1233 fprintf(stderr, "config (%s) not found!\n", configPath);
1234 if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) {
1235 file = fopen(DEF_CONFIG_FILE, "w");
1236 if (file) {
1237 fprintf(stderr, "creating defconfig\n");
1238 printOpts(file);
1239 }
1240 }
1241 goto end;
1242 }
1243
1244 printf("Starting to parse...\n");
1245
1246 if (SCANF_EAT(file) != 0) {
1247 goto end;
1248 }
1249 while(fscanf(file, "%s", buf) == 1) {
1250 if (!strcmp(buf, SEC_CHIP)) {
1251 chipOk = parseChip(file);
1252 if (!chipOk) {
1253 printf("parseChip failed!\n");
1254 goto end;
1255 }
1256 } else if (!strcmp(buf, SEC_VERSION)) {
1257 versionOk = parseVersion(file);
1258 if (!versionOk) {
1259 printf("parseVersion failed!\n");
1260 goto end;
1261 }
1262 } else if (!strcmp(buf, SEC_471)) {
1263 code471Ok = parse471(file);
1264 if (!code471Ok) {
1265 printf("parse471 failed!\n");
1266 goto end;
1267 }
1268 } else if (!strcmp(buf, SEC_472)) {
1269 code472Ok = parse472(file);
1270 if (!code472Ok) {
1271 printf("parse472 failed!\n");
1272 goto end;
1273 }
1274 } else if (!strcmp(buf, SEC_LOADER)) {
1275 loaderOk = parseLoader(file);
1276 if (!loaderOk) {
1277 printf("parseLoader failed!\n");
1278 goto end;
1279 }
1280 } else if (!strcmp(buf, SEC_OUT)) {
1281 outOk = parseOut(file);
1282 if (!outOk) {
1283 printf("parseOut failed!\n");
1284 goto end;
1285 }
1286 } else if (buf[0] == '#') {
1287 continue;
1288 } else {
1289 printf("unknown sec: %s!\n", buf);
1290 goto end;
1291 }
1292 if (SCANF_EAT(file) != 0) {
1293 goto end;
1294 }
1295 }
1296
1297 if (chipOk && versionOk && code471Ok && code472Ok
1298 && loaderOk && outOk)
1299 ret = true;
1300 end:
1301 if (file)
1302 fclose(file);
1303 return ret;
1304 }
1305
initOpts(void)1306 bool initOpts(void) {
1307 //set default opts
1308 gOpts.major = DEF_MAJOR;
1309 gOpts.minor = DEF_MINOR;
1310 strcpy(gOpts.chip, DEF_CHIP);
1311 gOpts.code471Sleep = DEF_CODE471_SLEEP;
1312 gOpts.code472Sleep = DEF_CODE472_SLEEP;
1313 gOpts.code471Num = DEF_CODE471_NUM;
1314 gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
1315 strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
1316 gOpts.code472Num = DEF_CODE472_NUM;
1317 gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
1318 strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
1319 gOpts.loaderNum = DEF_LOADER_NUM;
1320 gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
1321 strcpy(gOpts.loader[0].name, DEF_LOADER0);
1322 strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
1323 strcpy(gOpts.loader[1].name, DEF_LOADER1);
1324 strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
1325 strcpy(gOpts.outPath, DEF_OUT_PATH);
1326
1327 return parseOpts();
1328 }
1329
1330 /************merge code****************/
1331
getBCD(unsigned short value)1332 static inline uint32_t getBCD(unsigned short value) {
1333 uint8_t tmp[2] = {0};
1334 int i;
1335 uint32_t ret;
1336 //if (value > 0xFFFF) {
1337 // return 0;
1338 //}
1339 for(i=0; i < 2; i++) {
1340 tmp[i] = (((value/10)%10)<<4) | (value%10);
1341 value /= 100;
1342 }
1343 ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
1344
1345 printf("ret: %x\n",ret);
1346 return ret&0xFF;
1347 }
1348
str2wide(const char * str,uint16_t * wide,int len)1349 static inline void str2wide(const char* str, uint16_t* wide, int len)
1350 {
1351 int i;
1352 for (i = 0; i < len; i++) {
1353 wide[i] = (uint16_t) str[i];
1354 }
1355 wide[len] = 0;
1356 }
1357
getName(char * path,uint16_t * dst)1358 static inline void getName(char* path, uint16_t* dst) {
1359 char* end;
1360 char* start;
1361 int len;
1362 if (!path || !dst)
1363 return;
1364 start = strrchr(path, '/');
1365 if (!start)
1366 start = path;
1367 else
1368 start++;
1369 end = strrchr(path, '.');
1370 if (!end || (end < start))
1371 end = path + strlen(path);
1372 len = end - start;
1373 if (len >= MAX_NAME_LEN)
1374 len = MAX_NAME_LEN -1;
1375 str2wide(start, dst, len);
1376
1377
1378 char name[MAX_NAME_LEN];
1379 memset(name, 0, sizeof(name));
1380 memcpy(name, start, len);
1381 printf("path: %s, name: %s\n", path, name);
1382
1383 }
1384
getFileSize(const char * path,uint32_t * size)1385 static inline bool getFileSize(const char *path, uint32_t* size) {
1386 struct stat st;
1387 if(stat(path, &st) < 0)
1388 return false;
1389 *size = st.st_size;
1390 printf("path: %s, size: %d\n", path, *size);
1391 return true;
1392 }
1393
getTime(void)1394 static inline rk_time getTime(void) {
1395 rk_time rkTime;
1396
1397 struct tm *tm;
1398 time_t tt = time(NULL);
1399 tm = localtime(&tt);
1400 rkTime.year = tm->tm_year + 1900;
1401 rkTime.month = tm->tm_mon + 1;
1402 rkTime.day = tm->tm_mday;
1403 rkTime.hour = tm->tm_hour;
1404 rkTime.minute = tm->tm_min;
1405 rkTime.second = tm->tm_sec;
1406 printf("%d-%d-%d %02d:%02d:%02d\n",
1407 rkTime.year, rkTime.month, rkTime.day,
1408 rkTime.hour, rkTime.minute, rkTime.second);
1409 return rkTime;
1410 }
1411
writeFile(FILE * outFile,const char * path,bool fix)1412 static bool writeFile(FILE* outFile, const char* path, bool fix) {
1413 bool ret = false;
1414 uint32_t size = 0, fixSize = 0;
1415 uint8_t* buf;
1416
1417 FILE* inFile = fopen(path, "rb");
1418 if (!inFile)
1419 goto end;
1420
1421 if (!getFileSize(path, &size))
1422 goto end;
1423 if (fix) {
1424 fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
1425 uint32_t tmp = fixSize % ENTRY_ALIGN;
1426 tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
1427 fixSize +=tmp;
1428 memset(gBuf, 0, fixSize);
1429 } else {
1430 memset(gBuf, 0, size+ENTRY_ALIGN);
1431 }
1432 if (!fread(gBuf, size, 1, inFile))
1433 goto end;
1434
1435 if (fix) {
1436
1437 buf = gBuf;
1438 size = fixSize;
1439 while(1) {
1440 P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
1441 buf += SMALL_PACKET;
1442 if (fixSize <= SMALL_PACKET)
1443 break;
1444 fixSize -= SMALL_PACKET;
1445 }
1446 } else {
1447 uint32_t tmp = size % ENTRY_ALIGN;
1448 tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
1449 size +=tmp;
1450 P_RC4(gBuf, size);
1451 }
1452
1453 if (!fwrite(gBuf, size, 1, outFile))
1454 goto end;
1455 ret = true;
1456 end:
1457 if (inFile)
1458 fclose(inFile);
1459 if (!ret)
1460 printf("writing entry (%s) failed\n", path);
1461 return ret;
1462 }
1463
saveEntry(FILE * outFile,char * path,rk_entry_type type,uint16_t delay,uint32_t * offset,char * fixName,bool fix)1464 static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
1465 uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
1466 uint32_t size;
1467 rk_boot_entry entry;
1468
1469 printf("writing: %s\n", path);
1470 memset(&entry, 0, sizeof(rk_boot_entry));
1471 getName(fixName ? fixName: path, entry.name);
1472 entry.size = sizeof(rk_boot_entry);
1473 entry.type = type;
1474 entry.dataOffset = *offset;
1475 if (!getFileSize(path, &size)) {
1476 printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
1477 return false;
1478 }
1479 if (fix)
1480 size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
1481 uint32_t tmp = size % ENTRY_ALIGN;
1482 size += tmp ? (ENTRY_ALIGN - tmp): 0;
1483 printf("alignment size: %d\n", size);
1484 entry.dataSize = size;
1485 entry.dataDelay = delay;
1486 *offset += size;
1487 fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
1488 return true;
1489 }
1490
convertChipType(const char * chip)1491 static inline uint32_t convertChipType(const char* chip) {
1492 char buffer[5];
1493 memset(buffer, 0, sizeof(buffer));
1494 memccpy(buffer, chip, '\0', sizeof(buffer));
1495 return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
1496 }
1497
getChipType(const char * chip)1498 static inline uint32_t getChipType(const char* chip) {
1499 printf("chip: %s\n", chip);
1500 int chipType = RKNONE_DEVICE;
1501 if(!chip) {
1502 goto end;
1503 }
1504 if (!strcmp(chip, CHIP_RK28)) {
1505 chipType = RK28_DEVICE;
1506 } else if (!strcmp(chip, CHIP_RK28)) {
1507 chipType = RK28_DEVICE;
1508 } else if (!strcmp(chip, CHIP_RK281X)) {
1509 chipType = RK281X_DEVICE;
1510 } else if (!strcmp(chip, CHIP_RKPANDA)) {
1511 chipType = RKPANDA_DEVICE;
1512 } else if (!strcmp(chip, CHIP_RK27)) {
1513 chipType = RK27_DEVICE;
1514 } else if (!strcmp(chip, CHIP_RKNANO)) {
1515 chipType = RKNANO_DEVICE;
1516 } else if (!strcmp(chip, CHIP_RKSMART)) {
1517 chipType = RKSMART_DEVICE;
1518 } else if (!strcmp(chip, CHIP_RKCROWN)) {
1519 chipType = RKCROWN_DEVICE;
1520 } else if (!strcmp(chip, CHIP_RKCAYMAN)) {
1521 chipType = RKCAYMAN_DEVICE;
1522 } else if (!strcmp(chip, CHIP_RK29)) {
1523 chipType = RK29_DEVICE;
1524 } else if (!strcmp(chip, CHIP_RK292X)) {
1525 chipType = RK292X_DEVICE;
1526 } else if (!strcmp(chip, CHIP_RK30)) {
1527 chipType = RK30_DEVICE;
1528 } else if (!strcmp(chip, CHIP_RK30B)) {
1529 chipType = RK30B_DEVICE;
1530 } else if (!strcmp(chip, CHIP_RK31)) {
1531 chipType = RK31_DEVICE;
1532 } else if (!strcmp(chip, CHIP_RK32)) {
1533 chipType = RK32_DEVICE;
1534 } else {
1535 chipType = convertChipType(chip + 2);
1536 }
1537
1538 end:
1539 printf("type: 0x%x\n", chipType);
1540 if (chipType == RKNONE_DEVICE) {
1541 printf("chip type not supported!\n");
1542 }
1543 return chipType;
1544 }
1545
getBoothdr(rk_boot_header * hdr)1546 static inline void getBoothdr(rk_boot_header* hdr) {
1547 memset(hdr, 0, sizeof(rk_boot_header));
1548 hdr->tag = TAG;
1549 hdr->size = sizeof(rk_boot_header);
1550 hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
1551 hdr->mergerVersion = MERGER_VERSION;
1552 hdr->releaseTime = getTime();
1553 hdr->chipType = getChipType(gOpts.chip);
1554
1555 hdr->code471Num = gOpts.code471Num;
1556 hdr->code471Offset = sizeof(rk_boot_header);
1557 hdr->code471Size = sizeof(rk_boot_entry);
1558
1559 hdr->code472Num = gOpts.code472Num;
1560 hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
1561 hdr->code472Size = sizeof(rk_boot_entry);
1562
1563 hdr->loaderNum = gOpts.loaderNum;
1564 hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
1565 hdr->loaderSize = sizeof(rk_boot_entry);
1566 #ifndef USE_P_RC4
1567 hdr->rc4Flag = 1;
1568 #endif
1569 }
1570
getCrc(const char * path)1571 static inline uint32_t getCrc(const char* path) {
1572 uint32_t size = 0;
1573 uint32_t crc = 0;
1574
1575 FILE* file = fopen(path, "rb");
1576 getFileSize(path, &size);
1577 if (!file)
1578 goto end;
1579 if (!fread(gBuf, size, 1, file))
1580 goto end;
1581 crc = CRC_32(gBuf, size);
1582 printf("crc: 0x%08x\n", crc);
1583 end:
1584 if (file)
1585 fclose(file);
1586 return crc;
1587 }
1588
mergeBoot(void)1589 bool mergeBoot(void) {
1590 uint32_t dataOffset;
1591 bool ret = false;
1592 int i;
1593 FILE* outFile;
1594 uint32_t crc;
1595 rk_boot_header hdr;
1596
1597 if (!initOpts())
1598 return false;
1599 {
1600 char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
1601 char version[MAX_LINE_LEN];
1602 snprintf(version, sizeof(version), "%s", gSubfix);
1603 if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
1604 subfix[0] = '\0';
1605 }
1606 strcat(gOpts.outPath, version);
1607 printf("fix opt: %s\n", gOpts.outPath);
1608 }
1609
1610 printf("---------------\nUSING CONFIG:\n");
1611 printOpts(stdout);
1612 printf("---------------\n\n");
1613
1614
1615 outFile = fopen(gOpts.outPath, "wb+");
1616 if (!outFile) {
1617 printf("Opening output file (%s) failed\n", gOpts.outPath);
1618 goto end;
1619 }
1620
1621 getBoothdr(&hdr);
1622 printf("Writing header...\n");
1623 fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
1624
1625 dataOffset = sizeof(rk_boot_header) +
1626 (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
1627 sizeof(rk_boot_entry);
1628
1629 printf("Writing code 471 entry...\n");
1630 for (i=0; i<gOpts.code471Num; i++) {
1631 if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
1632 &dataOffset, NULL, false))
1633 goto end;
1634 }
1635 printf("Writing code 472 entry...\n");
1636 for (i=0; i<gOpts.code472Num; i++) {
1637 if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
1638 &dataOffset, NULL, false))
1639 goto end;
1640 }
1641 printf("Writing loader entry...\n");
1642 for (i=0; i<gOpts.loaderNum; i++) {
1643 if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
1644 &dataOffset, gOpts.loader[i].name, true))
1645 goto end;
1646 }
1647
1648 printf("Writing code 471...\n");
1649 for (i=0; i<gOpts.code471Num; i++) {
1650 if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
1651 goto end;
1652 }
1653 printf("Writing code 472...\n");
1654 for (i=0; i<gOpts.code472Num; i++) {
1655 if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
1656 goto end;
1657 }
1658 printf("Writing loader...\n");
1659 for (i=0; i<gOpts.loaderNum; i++) {
1660 if (!writeFile(outFile, gOpts.loader[i].path, true))
1661 goto end;
1662 }
1663 fflush(outFile);
1664
1665 printf("Writing crc...\n");
1666 crc = getCrc(gOpts.outPath);
1667 if (!fwrite(&crc, sizeof(crc), 1, outFile))
1668 goto end;
1669 printf("Done.\n");
1670 ret = true;
1671 end:
1672 if (outFile)
1673 fclose(outFile);
1674 return ret;
1675 }
1676
1677 /************merge code end************/
1678 /************unpack code***************/
1679
wide2str(const uint16_t * wide,char * str,int len)1680 static inline void wide2str(const uint16_t* wide, char* str, int len)
1681 {
1682 int i;
1683 for (i = 0; i < len; i++) {
1684 str[i] = (char) (wide[i] & 0xFF);
1685 }
1686 }
1687
unpackEntry(rk_boot_entry * entry,const char * name,FILE * inFile)1688 static bool unpackEntry(rk_boot_entry* entry, const char* name,
1689 FILE* inFile) {
1690 bool ret = false;
1691 int size, i;
1692 FILE* outFile = fopen(name, "wb+");
1693 if (!outFile)
1694 goto end;
1695 printf("unpacking entry (%s)\n", name);
1696 fseek(inFile, entry->dataOffset, SEEK_SET);
1697 size = entry->dataSize;
1698 if (!fread(gBuf, size, 1, inFile))
1699 goto end;
1700 if (entry->type == ENTRY_LOADER) {
1701 for(i=0; i<size/SMALL_PACKET; i++)
1702 P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
1703 if (size % SMALL_PACKET)
1704 {
1705 P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
1706 }
1707 } else {
1708 P_RC4(gBuf, size);
1709 }
1710 if (!fwrite(gBuf, size, 1, outFile))
1711 goto end;
1712 ret = true;
1713 end:
1714 if (outFile)
1715 fclose(outFile);
1716 return ret;
1717 }
1718
unpackBoot(char * path)1719 bool unpackBoot(char* path) {
1720 bool ret = false;
1721 FILE* inFile = fopen(path, "rb");
1722 int entryNum, i;
1723 char name[MAX_NAME_LEN];
1724 rk_boot_entry* entrys;
1725 if (!inFile) {
1726 fprintf(stderr, "loader (%s) not found\n", path);
1727 goto end;
1728 }
1729
1730 rk_boot_header hdr;
1731 if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
1732 fprintf(stderr, "reading header failed\n");
1733 goto end;
1734 }
1735 printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
1736 entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
1737 entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
1738 if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
1739 fprintf(stderr, "reading data failed\n");
1740 goto end;
1741 }
1742
1743 printf("entry num: %d\n", entryNum);
1744 for (i=0; i<entryNum; i++) {
1745 wide2str(entrys[i].name, name, MAX_NAME_LEN);
1746
1747 printf("entry: t=%d, name=%s, off=%d, size=%d\n",
1748 entrys[i].type, name, entrys[i].dataOffset,
1749 entrys[i].dataSize);
1750 if (!unpackEntry(entrys + i, name, inFile)) {
1751 fprintf(stderr, "unpacking entry (%s) failed\n", name);
1752 goto end;
1753 }
1754 }
1755 printf("done\n");
1756 ret = true;
1757 end:
1758 if (inFile)
1759 fclose(inFile);
1760 return ret;
1761 }
1762
download_boot(STRUCT_RKDEVICE_DESC & dev,char * szLoader)1763 bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1764 {
1765 if (!check_device_type(dev, RKUSB_MASKROM))
1766 return false;
1767 CRKImage *pImage = NULL;
1768 CRKBoot *pBoot = NULL;
1769 bool bRet, bSuccess = false;
1770 int iRet;
1771
1772 pImage = new CRKImage(szLoader, bRet);
1773 if (!bRet){
1774 ERROR_COLOR_ATTR;
1775 printf("Opening loader failed, exiting download boot!");
1776 NORMAL_COLOR_ATTR;
1777 printf("\r\n");
1778 return bSuccess;
1779 } else {
1780 pBoot = (CRKBoot *)pImage->m_bootObject;
1781 CRKComm *pComm = NULL;
1782 CRKDevice *pDevice = NULL;
1783
1784 dev.emDeviceType = pBoot->SupportDevice;
1785 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1786 if (!bRet) {
1787 if (pImage)
1788 delete pImage;
1789 ERROR_COLOR_ATTR;
1790 printf("Creating Comm Object failed!");
1791 NORMAL_COLOR_ATTR;
1792 printf("\r\n");
1793 return bSuccess;
1794 }
1795
1796 pDevice = new CRKDevice(dev);
1797 if (!pDevice) {
1798 if (pImage)
1799 delete pImage;
1800 if (pComm)
1801 delete pComm;
1802 ERROR_COLOR_ATTR;
1803 printf("Creating device object failed!");
1804 NORMAL_COLOR_ATTR;
1805 printf("\r\n");
1806 return bSuccess;
1807 }
1808
1809 pDevice->SetObject(pImage, pComm, g_pLogObject);
1810 printf("Downloading bootloader...\r\n");
1811 iRet = pDevice->DownloadBoot();
1812
1813 CURSOR_MOVEUP_LINE(1);
1814 CURSOR_DEL_LINE;
1815 if (iRet == 0) {
1816 bSuccess = true;
1817 printf("Downloading bootloader succeeded.\r\n");
1818 }
1819 else
1820 printf("Downloading bootloader failed!\r\n");
1821
1822 if (pImage)
1823 delete pImage;
1824 if(pDevice)
1825 delete pDevice;
1826 }
1827 return bSuccess;
1828 }
upgrade_loader(STRUCT_RKDEVICE_DESC & dev,char * szLoader)1829 bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1830 {
1831 if (!check_device_type(dev, RKUSB_MASKROM))
1832 return false;
1833 CRKImage *pImage = NULL;
1834 CRKBoot *pBoot = NULL;
1835 CRKComm *pComm = NULL;
1836 bool bRet,bNewIDBlock=false, bSuccess = false;
1837 int iRet;
1838 unsigned int i;
1839 signed char index;
1840 USHORT usFlashDataSec, usFlashBootSec, usFlashHeadSec;
1841 DWORD dwLoaderSize, dwLoaderDataSize, dwLoaderHeadSize, dwDelay, dwSectorNum;
1842 char loaderCodeName[] = "FlashBoot";
1843 char loaderDataName[] = "FlashData";
1844 char loaderHeadName[] = "FlashHead";
1845 PBYTE loaderCodeBuffer = NULL;
1846 PBYTE loaderDataBuffer = NULL;
1847 PBYTE loaderHeadBuffer = NULL;
1848 PBYTE pIDBData = NULL;
1849 BYTE capability[8];
1850 pImage = new CRKImage(szLoader, bRet);
1851 if (!bRet){
1852 ERROR_COLOR_ATTR;
1853 printf("Opening loader failed, exiting upgrade loader!");
1854 NORMAL_COLOR_ATTR;
1855 printf("\r\n");
1856 goto Exit_UpgradeLoader;
1857 } else {
1858 pBoot = (CRKBoot *)pImage->m_bootObject;
1859 dev.emDeviceType = pBoot->SupportDevice;
1860 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1861 if (!bRet) {
1862 ERROR_COLOR_ATTR;
1863 printf("Creating Comm Object failed!");
1864 NORMAL_COLOR_ATTR;
1865 printf("\r\n");
1866 goto Exit_UpgradeLoader;
1867 }
1868
1869 printf("Upgrading loader...\r\n");
1870 index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1871 if (index == -1) {
1872 if (g_pLogObject) {
1873 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1874 }
1875 goto Exit_UpgradeLoader;
1876 }
1877 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1878 if (!bRet) {
1879 if (g_pLogObject) {
1880 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1881 }
1882 goto Exit_UpgradeLoader;
1883 }
1884
1885 loaderCodeBuffer = new BYTE[dwLoaderSize];
1886 memset(loaderCodeBuffer, 0, dwLoaderSize);
1887 if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1888 if (g_pLogObject) {
1889 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1890 }
1891 goto Exit_UpgradeLoader;
1892 }
1893
1894 index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1895 if (index == -1) {
1896 if (g_pLogObject) {
1897 g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1898 }
1899 delete []loaderCodeBuffer;
1900 return -4;
1901 }
1902
1903 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1904 if (!bRet) {
1905 if (g_pLogObject) {
1906 g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1907 }
1908 goto Exit_UpgradeLoader;
1909 }
1910
1911 loaderDataBuffer = new BYTE[dwLoaderDataSize];
1912 memset(loaderDataBuffer, 0, dwLoaderDataSize);
1913 if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1914 if (g_pLogObject) {
1915 g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1916 }
1917 goto Exit_UpgradeLoader;
1918 }
1919
1920 index = pBoot->GetIndexByName(ENTRYLOADER, loaderHeadName);
1921 if (index != -1) {
1922 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderHeadSize, dwDelay);
1923 if (!bRet) {
1924 if (g_pLogObject) {
1925 g_pLogObject->Record("ERROR: %s --> Get LoaderHead Entry Size failed", __func__);
1926 }
1927 goto Exit_UpgradeLoader;
1928 }
1929
1930 loaderHeadBuffer= new BYTE[dwLoaderHeadSize];
1931 memset(loaderHeadBuffer, 0, dwLoaderHeadSize);
1932 if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderHeadBuffer)) {
1933 if (g_pLogObject) {
1934 g_pLogObject->Record("ERROR: %s --> Get LoaderHead Data failed", __func__);
1935 }
1936 goto Exit_UpgradeLoader;
1937 }
1938
1939 iRet = pComm->RKU_ReadCapability(capability);
1940 if (iRet != ERR_SUCCESS)
1941 {
1942 if (g_pLogObject)
1943 g_pLogObject->Record("ERROR: %s --> read capability failed", __func__);
1944 goto Exit_UpgradeLoader;
1945 }
1946 if ((capability[1] & 1) == 0) {
1947 if (g_pLogObject)
1948 g_pLogObject->Record("ERROR: %s --> device did not support to upgrade the loader", __func__);
1949 ERROR_COLOR_ATTR;
1950 printf("Device not support to upgrade the loader!");
1951 NORMAL_COLOR_ATTR;
1952 printf("\r\n");
1953 goto Exit_UpgradeLoader;
1954 }
1955 bNewIDBlock = true;
1956 }
1957
1958 usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1959 usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1960 if (bNewIDBlock) {
1961 usFlashHeadSec = (ALIGN(dwLoaderHeadSize, 2048)) / SECTOR_SIZE;
1962 dwSectorNum = usFlashHeadSec + usFlashDataSec + usFlashBootSec;
1963 } else
1964 dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1965 pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1966 if (!pIDBData) {
1967 ERROR_COLOR_ATTR;
1968 printf("Allocating memory failed!");
1969 NORMAL_COLOR_ATTR;
1970 printf("\r\n");
1971 goto Exit_UpgradeLoader;
1972 }
1973 memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1974 if (bNewIDBlock) {
1975 if (pBoot->Rc4DisableFlag)
1976 {//close rc4 encryption
1977 for (i=0;i<dwLoaderHeadSize/SECTOR_SIZE;i++)
1978 {
1979 P_RC4(loaderHeadBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
1980 }
1981 for (i=0;i<dwLoaderDataSize/SECTOR_SIZE;i++)
1982 {
1983 P_RC4(loaderDataBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
1984 }
1985 for (i=0;i<dwLoaderSize/SECTOR_SIZE;i++)
1986 {
1987 P_RC4(loaderCodeBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
1988 }
1989 }
1990 memcpy(pIDBData, loaderHeadBuffer, dwLoaderHeadSize);
1991 memcpy(pIDBData+SECTOR_SIZE*usFlashHeadSec, loaderDataBuffer, dwLoaderDataSize);
1992 memcpy(pIDBData+SECTOR_SIZE*(usFlashHeadSec+usFlashDataSec), loaderCodeBuffer, dwLoaderSize);
1993 } else {
1994 iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
1995 if (iRet != 0) {
1996 ERROR_COLOR_ATTR;
1997 printf("Making idblock failed!");
1998 NORMAL_COLOR_ATTR;
1999 printf("\r\n");
2000 goto Exit_UpgradeLoader;
2001 }
2002 }
2003
2004 iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
2005 CURSOR_MOVEUP_LINE(1);
2006 CURSOR_DEL_LINE;
2007 if (iRet == ERR_SUCCESS) {
2008 //pComm->Reset_Usb_Device();
2009 bSuccess = true;
2010 printf("Upgrading loader succeeded.\r\n");
2011 } else {
2012 printf("Upgrading loader failed!\r\n");
2013 goto Exit_UpgradeLoader;
2014 }
2015 }
2016 Exit_UpgradeLoader:
2017 if (pImage)
2018 delete pImage;
2019 if (pComm)
2020 delete pComm;
2021 if (loaderCodeBuffer)
2022 delete []loaderCodeBuffer;
2023 if (loaderDataBuffer)
2024 delete []loaderDataBuffer;
2025 if (loaderHeadBuffer)
2026 delete []loaderHeadBuffer;
2027 if (pIDBData)
2028 delete []pIDBData;
2029 return bSuccess;
2030 }
print_gpt(STRUCT_RKDEVICE_DESC & dev)2031 bool print_gpt(STRUCT_RKDEVICE_DESC &dev)
2032 {
2033 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2034 return false;
2035 u8 master_gpt[34 * SECTOR_SIZE];
2036 gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE);
2037 bool bRet, bSuccess = false;
2038 int iRet;
2039 gpt_entry *gptEntry = NULL;
2040 u32 i,j;
2041 u8 zerobuf[GPT_ENTRY_SIZE];
2042 memset(zerobuf,0,GPT_ENTRY_SIZE);
2043 CRKComm *pComm = NULL;
2044 char partName[36];
2045 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2046 if (!bRet) {
2047 ERROR_COLOR_ATTR;
2048 printf("Creating Comm Object failed!");
2049 NORMAL_COLOR_ATTR;
2050 printf("\r\n");
2051 return bSuccess;
2052 }
2053 iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt);
2054 if(ERR_SUCCESS == iRet) {
2055 if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
2056 goto Exit_PrintGpt;
2057 }
2058
2059 } else {
2060 if (g_pLogObject)
2061 g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
2062 printf("Read GPT failed!\r\n");
2063 goto Exit_PrintGpt;
2064 }
2065
2066 printf("**********Partition Info(GPT)**********\r\n");
2067 printf("NO LBA Name \r\n");
2068 for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) {
2069 gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
2070 if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
2071 break;
2072 memset(partName, 0 , 36);
2073 j = 0;
2074 while (gptEntry->partition_name[j]) {
2075 partName[j] = (char)gptEntry->partition_name[j];
2076 j++;
2077 }
2078 printf("%02d %08X %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName);
2079 }
2080 bSuccess = true;
2081 Exit_PrintGpt:
2082 if (pComm)
2083 delete pComm;
2084 return bSuccess;
2085 }
print_parameter(STRUCT_RKDEVICE_DESC & dev)2086 bool print_parameter(STRUCT_RKDEVICE_DESC &dev)
2087 {
2088 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2089 return false;
2090 u8 param_buf[512 * SECTOR_SIZE];
2091 bool bRet, bSuccess = false;
2092 int iRet;
2093 u32 i, nParamSize;
2094 CRKComm *pComm = NULL;
2095 PARAM_ITEM_VECTOR vecParamItem;
2096 CONFIG_ITEM_VECTOR vecUuidItem;
2097 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2098 if (!bRet) {
2099 ERROR_COLOR_ATTR;
2100 printf("Creating Comm Object failed!");
2101 NORMAL_COLOR_ATTR;
2102 printf("\r\n");
2103 return bSuccess;
2104 }
2105 iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf);
2106 if(ERR_SUCCESS == iRet) {
2107 if (*(u32 *)param_buf != 0x4D524150) {
2108 goto Exit_PrintParam;
2109 }
2110
2111 } else {
2112 if (g_pLogObject)
2113 g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2114 printf("Read parameter failed!\r\n");
2115 goto Exit_PrintParam;
2116 }
2117 nParamSize = *(u32 *)(param_buf + 4);
2118 memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8);
2119
2120 bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem);
2121 if (!bRet) {
2122 if (g_pLogObject)
2123 g_pLogObject->Record("Error: parse parameter failed");
2124 printf("Parse parameter failed!\r\n");
2125 goto Exit_PrintParam;
2126 }
2127 printf("**********Partition Info(parameter)**********\r\n");
2128 printf("NO LBA Name \r\n");
2129 for (i = 0; i < vecParamItem.size(); i++) {
2130 printf("%02d %08X %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName);
2131 }
2132 bSuccess = true;
2133 Exit_PrintParam:
2134 if (pComm)
2135 delete pComm;
2136 return bSuccess;
2137 }
2138
erase_flash(STRUCT_RKDEVICE_DESC & dev)2139 bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
2140 {
2141 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2142 return false;
2143 CRKImage *pImage = NULL;
2144 bool bRet, bSuccess = false;
2145 int iRet;
2146 CRKScan *pScan = NULL;
2147 pScan = new CRKScan();
2148 pScan->SetVidPid();
2149
2150 CRKComm *pComm = NULL;
2151 CRKDevice *pDevice = NULL;
2152
2153 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2154 if (!bRet) {
2155 if (pScan)
2156 delete pScan;
2157 ERROR_COLOR_ATTR;
2158 printf("Creating Comm Object failed!");
2159 NORMAL_COLOR_ATTR;
2160 printf("\r\n");
2161 return bSuccess;
2162 }
2163
2164 pDevice = new CRKDevice(dev);
2165 if (!pDevice) {
2166 if (pComm)
2167 delete pComm;
2168 if (pScan)
2169 delete pScan;
2170 ERROR_COLOR_ATTR;
2171 printf("Creating device object failed!");
2172 NORMAL_COLOR_ATTR;
2173 printf("\r\n");
2174 return bSuccess;
2175 }
2176
2177 pDevice->SetObject(pImage, pComm, g_pLogObject);
2178 pDevice->CallBackPointer = ProgressInfoProc;
2179
2180 printf("Starting to erase flash...\r\n");
2181 bRet = pDevice->GetFlashInfo();
2182 if (!bRet) {
2183 if (pDevice)
2184 delete pDevice;
2185 if (pScan)
2186 delete pScan;
2187 ERROR_COLOR_ATTR;
2188 printf("Getting flash info from device failed!");
2189 NORMAL_COLOR_ATTR;
2190 printf("\r\n");
2191 return bSuccess;
2192 }
2193 iRet = pDevice->EraseAllBlocks();
2194 if (pDevice)
2195 delete pDevice;
2196
2197 if (iRet == 0) {
2198 if (pScan) {
2199 pScan->SetVidPid();
2200 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
2201 delete pScan;
2202 }
2203 CURSOR_MOVEUP_LINE(1);
2204 CURSOR_DEL_LINE;
2205 bSuccess = true;
2206 printf("Erasing flash complete.\r\n");
2207 }
2208
2209 return bSuccess;
2210 }
2211
test_device(STRUCT_RKDEVICE_DESC & dev)2212 bool test_device(STRUCT_RKDEVICE_DESC &dev)
2213 {
2214 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2215 return false;
2216 CRKUsbComm *pComm = NULL;
2217 bool bRet, bSuccess = false;
2218 int iRet;
2219 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2220 if (bRet) {
2221 iRet = pComm->RKU_TestDeviceReady();
2222 if (iRet != ERR_SUCCESS) {
2223 if (g_pLogObject)
2224 g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
2225 printf("Test Device failed!\r\n");
2226 } else {
2227 bSuccess = true;
2228 printf("Test Device OK.\r\n");
2229 }
2230 } else {
2231 printf("Test Device quit, creating comm object failed!\r\n");
2232 }
2233 if (pComm) {
2234 delete pComm;
2235 pComm = NULL;
2236 }
2237 return bSuccess;
2238 }
reset_device(STRUCT_RKDEVICE_DESC & dev,BYTE subCode=RST_NONE_SUBCODE)2239 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
2240 {
2241 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2242 return false;
2243 CRKUsbComm *pComm = NULL;
2244 bool bRet, bSuccess = false;
2245 int iRet;
2246 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2247 if (bRet) {
2248 iRet = pComm->RKU_ResetDevice(subCode);
2249 if (iRet != ERR_SUCCESS) {
2250 if (g_pLogObject)
2251 g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
2252 printf("Reset Device failed!\r\n");
2253 } else {
2254 bSuccess = true;
2255 printf("Reset Device OK.\r\n");
2256 }
2257 } else {
2258 printf("Reset Device quit, creating comm object failed!\r\n");
2259 }
2260 if (pComm) {
2261 delete pComm;
2262 pComm = NULL;
2263 }
2264 return bSuccess;
2265 }
2266
change_storage(STRUCT_RKDEVICE_DESC & dev,BYTE storage)2267 bool change_storage(STRUCT_RKDEVICE_DESC &dev, BYTE storage)
2268 {
2269 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2270 return false;
2271 CRKUsbComm *pComm = NULL;
2272 bool bRet, bSuccess = false;
2273 int iRet;
2274 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2275 if (bRet) {
2276 iRet = pComm->RKU_ChangeStorage(storage);
2277 if (iRet != ERR_SUCCESS) {
2278 if (g_pLogObject)
2279 g_pLogObject->Record("Error: RKU_ChangeStorage failed, err=%d", iRet);
2280 printf("Change Storage failed!\r\n");
2281 goto failed;
2282 }
2283 /* No error is returned if the selected storage is not available.
2284 * Read back the current storage to know if the change is effective.
2285 */
2286 BYTE current_storage;
2287 iRet = pComm->RKU_ReadStorage(¤t_storage);
2288 if (iRet != ERR_SUCCESS) {
2289 if (g_pLogObject)
2290 g_pLogObject->Record("Error: RKU_ReadStorage failed, err=%d", iRet);
2291 printf("Change Storage failed!\r\n");
2292 goto failed;
2293 }
2294 if (storage == current_storage) {
2295 bSuccess = true;
2296 printf("Change Storage OK.\r\n");
2297 } else {
2298 printf("Change Storage failed! Storage %u is not available.\r\n", storage);
2299 }
2300 } else {
2301 printf("Change Storage quit, creating comm object failed!\r\n");
2302 }
2303 failed:
2304 if (pComm) {
2305 delete pComm;
2306 pComm = NULL;
2307 }
2308 return bSuccess;
2309 }
2310
2311
2312
read_flash_id(STRUCT_RKDEVICE_DESC & dev)2313 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
2314 {
2315 CRKUsbComm *pComm = NULL;
2316 bool bRet, bSuccess = false;
2317 int iRet;
2318 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2319 return bSuccess;
2320
2321 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2322 if (bRet) {
2323 BYTE flashID[5];
2324 iRet = pComm->RKU_ReadFlashID(flashID);
2325 if (iRet != ERR_SUCCESS) {
2326 if (g_pLogObject)
2327 g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
2328 printf("Reading flash ID failed!\r\n");
2329 } else {
2330 printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
2331 bSuccess = true;
2332 }
2333 } else {
2334 printf("Read Flash ID quit, creating comm object failed!\r\n");
2335 }
2336 if (pComm) {
2337 delete pComm;
2338 pComm = NULL;
2339 }
2340 return bSuccess;
2341 }
read_flash_info(STRUCT_RKDEVICE_DESC & dev)2342 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
2343 {
2344 CRKUsbComm *pComm = NULL;
2345 bool bRet, bSuccess = false;
2346 int iRet;
2347 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2348 return bSuccess;
2349
2350 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2351 if (bRet) {
2352 STRUCT_FLASHINFO_CMD info;
2353 UINT uiRead;
2354 iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
2355 if (iRet != ERR_SUCCESS) {
2356 if (g_pLogObject)
2357 g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
2358 printf("Read Flash Info failed!\r\n");
2359 } else {
2360 printf("Flash Info:\r\n");
2361 if (info.bManufCode <= 7) {
2362 printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
2363 }
2364 else
2365 printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
2366
2367 printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
2368 printf("\tFlash Size: %d Sectors\r\n", info.uiFlashSize);
2369 printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
2370 printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
2371 printf("\tECC Bits: %d\r\n", info.bECCBits);
2372 printf("\tAccess Time: %d\r\n", info.bAccessTime);
2373 printf("\tFlash CS: ");
2374 for(int i = 0; i < 8; i++) {
2375 if( info.bFlashCS & (1 << i) )
2376 printf("Flash<%d> ", i);
2377 }
2378 printf("\r\n");
2379 bSuccess = true;
2380 }
2381 }else {
2382 printf("Read Flash Info quit, creating comm object failed!\r\n");
2383 }
2384 if (pComm) {
2385 delete pComm;
2386 pComm = NULL;
2387 }
2388 return bSuccess;
2389 }
read_chip_info(STRUCT_RKDEVICE_DESC & dev)2390 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
2391 {
2392 CRKUsbComm *pComm = NULL;
2393 bool bRet, bSuccess = false;
2394 int iRet;
2395 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2396 return bSuccess;
2397
2398 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2399 if (bRet) {
2400 BYTE chipInfo[16];
2401 iRet = pComm->RKU_ReadChipInfo(chipInfo);
2402 if (iRet != ERR_SUCCESS) {
2403 if (g_pLogObject)
2404 g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
2405 printf("Read Chip Info failed!\r\n");
2406 } else {
2407 string strChipInfo;
2408 g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
2409 printf("Chip Info: %s\r\n", strChipInfo.c_str());
2410 bSuccess = true;
2411 }
2412 } else {
2413 printf("Read Chip Info quit, creating comm object failed!\r\n");
2414 }
2415 if (pComm) {
2416 delete pComm;
2417 pComm = NULL;
2418 }
2419 return bSuccess;
2420 }
read_capability(STRUCT_RKDEVICE_DESC & dev)2421 bool read_capability(STRUCT_RKDEVICE_DESC &dev)
2422 {
2423 CRKUsbComm *pComm = NULL;
2424 bool bRet, bSuccess = false;
2425 int iRet;
2426 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2427 return bSuccess;
2428
2429 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2430 if (bRet) {
2431
2432 BYTE capability[8];
2433 iRet = pComm->RKU_ReadCapability(capability);
2434 if (iRet != ERR_SUCCESS)
2435 {
2436 if (g_pLogObject)
2437 g_pLogObject->Record("Error:read_capability failed,err=%d", iRet);
2438 printf("Read capability Fail!\r\n");
2439 } else {
2440 printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n",
2441 capability[0], capability[1], capability[2], capability[3],
2442 capability[4], capability[5], capability[6], capability[7]);
2443 if (capability[0] & 1)
2444 {
2445 printf("Direct LBA:\tenabled\r\n");
2446 }
2447
2448 if (capability[0] & 2)
2449 {
2450 printf("Vendor Storage:\tenabled\r\n");
2451 }
2452
2453 if (capability[0] & 4)
2454 {
2455 printf("First 4m Access:\tenabled\r\n");
2456 }
2457 if (capability[0] & 8)
2458 {
2459 printf("Read LBA:\tenabled\r\n");
2460 }
2461
2462 if (capability[0] & 20)
2463 {
2464 printf("Read Com Log:\tenabled\r\n");
2465 }
2466
2467 if (capability[0] & 40)
2468 {
2469 printf("Read IDB Config:\tenabled\r\n");
2470 }
2471
2472 if (capability[0] & 80)
2473 {
2474 printf("Read Secure Mode:\tenabled\r\n");
2475 }
2476
2477 if (capability[1] & 1)
2478 {
2479 printf("New IDB:\tenabled\r\n");
2480 }
2481 bSuccess = true;
2482 }
2483 } else {
2484 printf("Read capability quit, creating comm object failed!\r\n");
2485 }
2486 if (pComm) {
2487 delete pComm;
2488 pComm = NULL;
2489 }
2490 return bSuccess;
2491 }
read_param(STRUCT_RKDEVICE_DESC & dev,u8 * pParam)2492 bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam)
2493 {
2494 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2495 return false;
2496 CRKUsbComm *pComm = NULL;
2497 bool bRet, bSuccess = false;
2498 int iRet;
2499 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2500 if (bRet) {
2501 iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam);
2502 if(ERR_SUCCESS == iRet) {
2503 if (*(u32 *)pParam != 0x4D524150) {
2504 goto Exit_ReadParam;
2505 }
2506 } else {
2507 if (g_pLogObject)
2508 g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2509 printf("Read parameter failed!\r\n");
2510 goto Exit_ReadParam;
2511 }
2512 bSuccess = true;
2513 }
2514 Exit_ReadParam:
2515 if (pComm) {
2516 delete pComm;
2517 pComm = NULL;
2518 }
2519 return bSuccess;
2520 }
2521
2522
read_gpt(STRUCT_RKDEVICE_DESC & dev,u8 * pGpt)2523 bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt)
2524 {
2525 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2526 return false;
2527 gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE);
2528 CRKUsbComm *pComm = NULL;
2529 bool bRet, bSuccess = false;
2530 int iRet;
2531 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2532 if (bRet) {
2533 iRet = pComm->RKU_ReadLBA( 0, 34, pGpt);
2534 if(ERR_SUCCESS == iRet) {
2535 if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
2536 goto Exit_ReadGPT;
2537 }
2538 } else {
2539 if (g_pLogObject)
2540 g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
2541 printf("Read GPT failed!\r\n");
2542 goto Exit_ReadGPT;
2543 }
2544 bSuccess = true;
2545 }
2546 Exit_ReadGPT:
2547 if (pComm) {
2548 delete pComm;
2549 pComm = NULL;
2550 }
2551 return bSuccess;
2552 }
read_lba(STRUCT_RKDEVICE_DESC & dev,UINT uiBegin,UINT uiLen,char * szFile)2553 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
2554 {
2555 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2556 return false;
2557 CRKUsbComm *pComm = NULL;
2558 FILE *file = NULL;
2559 bool bRet, bFirst = true, bSuccess = false;
2560 int iRet;
2561 UINT iTotalRead = 0,iRead = 0;
2562 int nSectorSize = 512;
2563 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
2564 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2565 if (bRet) {
2566 if(szFile) {
2567 file = fopen(szFile, "wb+");
2568 if( !file ) {
2569 printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
2570 goto Exit_ReadLBA;
2571 }
2572 }
2573
2574 while(uiLen > 0) {
2575 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
2576 iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
2577 iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
2578 if(ERR_SUCCESS == iRet) {
2579 uiLen -= iRead;
2580 iTotalRead += iRead;
2581
2582 if(szFile) {
2583 fwrite(pBuf, 1, iRead * nSectorSize, file);
2584 if (bFirst){
2585 if (iTotalRead >= 1024)
2586 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
2587 else
2588 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
2589 bFirst = false;
2590 } else {
2591 CURSOR_MOVEUP_LINE(1);
2592 CURSOR_DEL_LINE;
2593 if (iTotalRead >= 1024)
2594 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
2595 else
2596 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
2597 }
2598 }
2599 else
2600 PrintData(pBuf, nSectorSize * iRead);
2601 } else {
2602 if (g_pLogObject)
2603 g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
2604
2605 printf("Read LBA failed!\r\n");
2606 goto Exit_ReadLBA;
2607 }
2608 }
2609 bSuccess = true;
2610 } else {
2611 printf("Read LBA quit, creating comm object failed!\r\n");
2612 }
2613 Exit_ReadLBA:
2614 if (pComm) {
2615 delete pComm;
2616 pComm = NULL;
2617 }
2618 if (file)
2619 fclose(file);
2620 return bSuccess;
2621 }
erase_ubi_block(STRUCT_RKDEVICE_DESC & dev,u32 uiOffset,u32 uiPartSize)2622 bool erase_ubi_block(STRUCT_RKDEVICE_DESC &dev, u32 uiOffset, u32 uiPartSize)
2623 {
2624 STRUCT_FLASHINFO_CMD info;
2625 CRKComm *pComm = NULL;
2626 BYTE flashID[5];
2627 bool bRet,bSuccess=false;
2628 UINT uiReadCount,uiStartBlock,uiEraseBlock,uiBlockCount,uiErasePos;
2629 int iRet;
2630 DWORD *pID=NULL;
2631
2632 printf("Erase ubi in, offset=0x%08x,size=0x%08x!\r\n",uiOffset,uiPartSize);
2633 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2634 return false;
2635 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2636 if (!bRet)
2637 {
2638 printf("Erase ubi quit, creating comm object failed!\r\n");
2639 goto EXIT_UBI_ERASE;
2640 }
2641 iRet = pComm->RKU_ReadFlashID(flashID);
2642 if(iRet!=ERR_SUCCESS)
2643 {
2644 if (g_pLogObject)
2645 {
2646 g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashID failed,RetCode(%d)",iRet);
2647 }
2648 goto EXIT_UBI_ERASE;
2649 }
2650 pID = (DWORD *)flashID;
2651
2652 if (*pID==0x434d4d45)//emmc
2653 {
2654 bSuccess = true;
2655 goto EXIT_UBI_ERASE;
2656 }
2657
2658 iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info,&uiReadCount);
2659 if (iRet!=ERR_SUCCESS)
2660 {
2661 if (g_pLogObject)
2662 g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashInfo err=%d", iRet);
2663 goto EXIT_UBI_ERASE;
2664 }
2665 if (uiPartSize==0xFFFFFFFF)
2666 uiPartSize = info.uiFlashSize - uiOffset;
2667
2668 uiStartBlock = uiOffset / info.usBlockSize;
2669 uiEraseBlock = (uiPartSize + info.usBlockSize -1) / info.usBlockSize;
2670
2671
2672 printf("Erase block start, offset=0x%08x,count=0x%08x!\r\n",uiStartBlock,uiEraseBlock);
2673 uiErasePos=uiStartBlock;
2674 while (uiEraseBlock>0)
2675 {
2676 uiBlockCount = (uiEraseBlock<MAX_ERASE_BLOCKS)?uiEraseBlock:MAX_ERASE_BLOCKS;
2677
2678 iRet = pComm->RKU_EraseBlock(0,uiErasePos,uiBlockCount,ERASE_FORCE);
2679 if ((iRet!=ERR_SUCCESS)&&(iRet!=ERR_FOUND_BAD_BLOCK))
2680 {
2681 if (g_pLogObject)
2682 {
2683 g_pLogObject->Record("Error:EraseUBIBlock-->RKU_EraseBlock failed,RetCode(%d)",iRet);
2684 }
2685 goto EXIT_UBI_ERASE;
2686 }
2687
2688 uiErasePos += uiBlockCount;
2689 uiEraseBlock -= uiBlockCount;
2690 }
2691 bSuccess = true;
2692 EXIT_UBI_ERASE:
2693 if (pComm)
2694 delete pComm;
2695 return bSuccess;
2696 }
erase_partition(CRKUsbComm * pComm,UINT uiOffset,UINT uiSize)2697 bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize)
2698 {
2699 UINT uiErase=1024*32;
2700 bool bSuccess = true;
2701 int iRet;
2702 while (uiSize)
2703 {
2704 if (uiSize>=uiErase)
2705 {
2706 iRet = pComm->RKU_EraseLBA(uiOffset,uiErase);
2707 uiSize -= uiErase;
2708 uiOffset += uiErase;
2709 }
2710 else
2711 {
2712 iRet = pComm->RKU_EraseLBA(uiOffset,uiSize);
2713 uiSize = 0;
2714 uiOffset += uiSize;
2715 }
2716 if (iRet!=ERR_SUCCESS)
2717 {
2718 if (g_pLogObject)
2719 {
2720 g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet);
2721 }
2722 bSuccess = false;
2723 break;
2724 }
2725 }
2726 return bSuccess;
2727
2728 }
EatSparseChunk(FILE * file,chunk_header & chunk)2729 bool EatSparseChunk(FILE *file, chunk_header &chunk)
2730 {
2731 UINT uiRead;
2732 uiRead = fread(&chunk, 1, sizeof(chunk_header), file);
2733 if (uiRead != sizeof(chunk_header)) {
2734 if (g_pLogObject)
2735 {
2736 g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno);
2737 }
2738 return false;
2739 }
2740 return true;
2741 }
EatSparseData(FILE * file,PBYTE pBuf,DWORD dwSize)2742 bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize)
2743 {
2744 UINT uiRead;
2745 uiRead = fread(pBuf, 1, dwSize, file);
2746 if (uiRead!=dwSize)
2747 {
2748 if (g_pLogObject)
2749 {
2750 g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno);
2751 }
2752 return false;
2753 }
2754 return true;
2755 }
2756
write_sparse_lba(STRUCT_RKDEVICE_DESC & dev,UINT uiBegin,UINT uiSize,char * szFile)2757 bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile)
2758 {
2759 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2760 return false;
2761 CRKUsbComm *pComm = NULL;
2762 FILE *file = NULL;
2763 bool bRet, bSuccess = false, bFirst = true;
2764 int iRet;
2765 u64 iTotalWrite = 0, iFileSize = 0,dwChunkDataSize;
2766 UINT iRead = 0, uiTransferSec, curChunk, i;
2767 UINT dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc;
2768 BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA];
2769 sparse_header header;
2770 chunk_header chunk;
2771 dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE;
2772 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2773 if (bRet) {
2774
2775 file = fopen(szFile, "rb");
2776 if( !file ) {
2777 printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile);
2778 goto Exit_WriteSparseLBA;
2779 }
2780 fseeko(file, 0, SEEK_SET);
2781 iRead = fread(&header, 1, sizeof(header), file);
2782 if (iRead != sizeof(sparse_header))
2783 {
2784 if (g_pLogObject)
2785 {
2786 g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno);
2787 }
2788 goto Exit_WriteSparseLBA;
2789 }
2790 iFileSize = header.blk_sz * (u64)header.total_blks;
2791 iTotalWrite = 0;
2792 curChunk = 0;
2793 if (uiSize==(u32)-1)
2794 uiSize = ALIGN(iFileSize, SECTOR_SIZE);
2795 bRet = erase_partition(pComm, uiBegin, uiSize);
2796 if (!bRet) {
2797 printf("%s failed, erase partition error\r\n", __func__);
2798 goto Exit_WriteSparseLBA;
2799 }
2800 while(curChunk < header.total_chunks)
2801 {
2802 if (!EatSparseChunk(file, chunk)) {
2803 goto Exit_WriteSparseLBA;
2804 }
2805 curChunk++;
2806 switch (chunk.chunk_type) {
2807 case CHUNK_TYPE_RAW:
2808 dwChunkDataSize = chunk.total_sz - sizeof(chunk_header);
2809 while (dwChunkDataSize) {
2810 memset(pBuf, 0, dwMaxReadWriteBytes);
2811 if (dwChunkDataSize >= dwMaxReadWriteBytes) {
2812 dwTransferBytes = dwMaxReadWriteBytes;
2813 uiTransferSec = DEFAULT_RW_LBA;
2814 } else {
2815 dwTransferBytes = dwChunkDataSize;
2816 uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
2817 }
2818 if (!EatSparseData(file, pBuf, dwTransferBytes)) {
2819 goto Exit_WriteSparseLBA;
2820 }
2821 iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
2822 if( ERR_SUCCESS == iRet ) {
2823 dwChunkDataSize -= dwTransferBytes;
2824 iTotalWrite += dwTransferBytes;
2825 uiBegin += uiTransferSec;
2826 } else {
2827 if (g_pLogObject) {
2828 g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)", __func__, iTotalWrite, iRet);
2829 }
2830 goto Exit_WriteSparseLBA;
2831 }
2832 if (bFirst) {
2833 if (iTotalWrite >= 1024)
2834 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
2835 else
2836 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
2837 bFirst = false;
2838 } else {
2839 CURSOR_MOVEUP_LINE(1);
2840 CURSOR_DEL_LINE;
2841 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
2842 }
2843 }
2844 break;
2845 case CHUNK_TYPE_FILL:
2846 dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz;
2847 if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) {
2848 goto Exit_WriteSparseLBA;
2849 }
2850 while (dwChunkDataSize) {
2851 memset(pBuf, 0, dwMaxReadWriteBytes);
2852 if (dwChunkDataSize >= dwMaxReadWriteBytes) {
2853 dwTransferBytes = dwMaxReadWriteBytes;
2854 uiTransferSec = DEFAULT_RW_LBA;
2855 } else {
2856 dwTransferBytes = dwChunkDataSize;
2857 uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
2858 }
2859 for (i = 0; i < dwTransferBytes / 4; i++) {
2860 *(DWORD *)(pBuf + i * 4) = dwFillByte;
2861 }
2862 iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
2863 if( ERR_SUCCESS == iRet ) {
2864 dwChunkDataSize -= dwTransferBytes;
2865 iTotalWrite += dwTransferBytes;
2866 uiBegin += uiTransferSec;
2867 } else {
2868 if (g_pLogObject) {
2869 g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet);
2870 }
2871 goto Exit_WriteSparseLBA;
2872 }
2873 if (bFirst) {
2874 if (iTotalWrite >= 1024)
2875 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
2876 else
2877 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
2878 bFirst = false;
2879 } else {
2880 CURSOR_MOVEUP_LINE(1);
2881 CURSOR_DEL_LINE;
2882 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
2883 }
2884 }
2885 break;
2886 case CHUNK_TYPE_DONT_CARE:
2887 dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz;
2888 iTotalWrite += dwChunkDataSize;
2889 uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1));
2890 uiBegin += uiTransferSec;
2891 if (bFirst) {
2892 if (iTotalWrite >= 1024)
2893 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
2894 else
2895 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
2896 bFirst = false;
2897 } else {
2898 CURSOR_MOVEUP_LINE(1);
2899 CURSOR_DEL_LINE;
2900 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
2901 }
2902 break;
2903 case CHUNK_TYPE_CRC32:
2904 EatSparseData(file,(PBYTE)&dwCrc,4);
2905 break;
2906 }
2907 }
2908 bSuccess = true;
2909 } else {
2910 printf("Write LBA quit, creating comm object failed!\r\n");
2911 }
2912 Exit_WriteSparseLBA:
2913 if (pComm) {
2914 delete pComm;
2915 pComm = NULL;
2916 }
2917 if (file)
2918 fclose(file);
2919 return bSuccess;
2920
2921 }
2922
write_lba(STRUCT_RKDEVICE_DESC & dev,UINT uiBegin,char * szFile)2923 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
2924 {
2925 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2926 return false;
2927 CRKUsbComm *pComm = NULL;
2928 FILE *file = NULL;
2929 bool bRet, bFirst = true, bSuccess = false;
2930 int iRet;
2931 long long iTotalWrite = 0, iFileSize = 0;
2932 UINT iWrite = 0, iRead = 0;
2933 UINT uiLen;
2934 int nSectorSize = 512;
2935 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
2936
2937
2938 pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2939 if (bRet) {
2940 file = fopen(szFile, "rb");
2941 if( !file ) {
2942 printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
2943 goto Exit_WriteLBA;
2944 }
2945
2946 iRet = fseeko(file, 0, SEEK_END);
2947 iFileSize = ftello(file);
2948 fseeko(file, 0, SEEK_SET);
2949 while(iTotalWrite < iFileSize) {
2950 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
2951 iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
2952 uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
2953 iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
2954 if(ERR_SUCCESS == iRet) {
2955 uiBegin += uiLen;
2956 iTotalWrite += iWrite;
2957 if (bFirst) {
2958 if (iTotalWrite >= 1024)
2959 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
2960 else
2961 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
2962 bFirst = false;
2963 } else {
2964 CURSOR_MOVEUP_LINE(1);
2965 CURSOR_DEL_LINE;
2966 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
2967 }
2968 } else {
2969 if (g_pLogObject)
2970 g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
2971
2972 printf("Write LBA failed!\r\n");
2973 goto Exit_WriteLBA;
2974 }
2975 }
2976 bSuccess = true;
2977 } else {
2978 printf("Write LBA quit, creating comm object failed!\r\n");
2979 }
2980 Exit_WriteLBA:
2981 if (pComm) {
2982 delete pComm;
2983 pComm = NULL;
2984 }
2985 if (file)
2986 fclose(file);
2987 return bSuccess;
2988 }
2989
split_item(STRING_VECTOR & vecItems,char * pszItems)2990 void split_item(STRING_VECTOR &vecItems, char *pszItems)
2991 {
2992 string strItem;
2993 char szItem[100];
2994 char *pos = NULL, *pStart;
2995 pStart = pszItems;
2996 pos = strchr(pStart, ',');
2997 while(pos != NULL) {
2998 memset(szItem, 0, sizeof(szItem));
2999 strncpy(szItem, pStart, pos - pStart);
3000 strItem = szItem;
3001 vecItems.push_back(strItem);
3002 pStart = pos + 1;
3003 if (*pStart == 0)
3004 break;
3005 pos = strchr(pStart, ',');
3006 }
3007 if (strlen(pStart) > 0) {
3008 memset(szItem, 0, sizeof(szItem));
3009 strncpy(szItem, pStart, sizeof(szItem)-1);
3010 strItem = szItem;
3011 vecItems.push_back(strItem);
3012 }
3013 }
3014
tag_spl(char * tag,char * spl)3015 void tag_spl(char *tag, char *spl)
3016 {
3017 FILE *file = NULL;
3018 int len;
3019
3020 if(!tag || !spl)
3021 return;
3022 len = strlen(tag);
3023 printf("tag len=%d\n",len);
3024 file = fopen(spl, "rb");
3025 if( !file ){
3026 return;
3027 }
3028 int iFileSize;
3029 fseek(file, 0, SEEK_END);
3030 iFileSize = ftell(file);
3031 fseek(file, 0, SEEK_SET);
3032 char *Buf = NULL;
3033 Buf = new char[iFileSize + len + 1];
3034 if (!Buf){
3035 fclose(file);
3036 return;
3037 }
3038 memset(Buf, 0, iFileSize + 1);
3039 memcpy(Buf, tag, len);
3040 int iRead;
3041 iRead = fread(Buf+len, 1, iFileSize, file);
3042 if (iRead != iFileSize){
3043 fclose(file);
3044 delete []Buf;
3045 return;
3046 }
3047 fclose(file);
3048
3049 len = strlen(spl);
3050 char *taggedspl = new char[len + 5];
3051 strcpy(taggedspl, spl);
3052 strcpy(taggedspl + len, ".tag");
3053 taggedspl[len+4] = 0;
3054 printf("Writing tagged spl to %s\n", taggedspl);
3055
3056 file = fopen(taggedspl, "wb");
3057 if( !file ){
3058 delete []taggedspl;
3059 delete []Buf;
3060 return;
3061 }
3062 fwrite(Buf, 1, iFileSize+len, file);
3063 fclose(file);
3064 delete []taggedspl;
3065 delete []Buf;
3066 printf("done\n");
3067 return;
3068 }
list_device(CRKScan * pScan)3069 void list_device(CRKScan *pScan)
3070 {
3071 STRUCT_RKDEVICE_DESC desc;
3072 string strDevType;
3073 int i,cnt;
3074 cnt = pScan->DEVICE_COUNTS;
3075 if (cnt == 0) {
3076 printf("not found any devices!\r\n");
3077 return;
3078 }
3079 for (i=0;i<cnt;i++)
3080 {
3081 pScan->GetDevice(desc, i);
3082 if (desc.emUsbType==RKUSB_MASKROM)
3083 strDevType = "Maskrom";
3084 else if (desc.emUsbType==RKUSB_LOADER)
3085 strDevType = "Loader";
3086 else
3087 strDevType = "Unknown";
3088 printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid,
3089 desc.usPid,desc.uiLocationID,strDevType.c_str());
3090 }
3091
3092 }
3093
3094
handle_command(int argc,char * argv[],CRKScan * pScan)3095 bool handle_command(int argc, char* argv[], CRKScan *pScan)
3096 {
3097 string strCmd;
3098 strCmd = argv[1];
3099 ssize_t cnt;
3100 bool bRet,bSuccess = false;
3101 char *s;
3102 int i, ret;
3103 STRUCT_RKDEVICE_DESC dev;
3104 u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE];
3105 u64 lba, lba_end;
3106 u32 part_size, part_offset;
3107
3108 transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
3109 s = (char*)strCmd.c_str();
3110 for(i = 0; i < (int)strlen(s); i++)
3111 s[i] = toupper(s[i]);
3112
3113 if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
3114 usage();
3115 return true;
3116 } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
3117 printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
3118 return true;
3119 } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
3120 mergeBoot();
3121 return true;
3122 } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
3123 string strLoader = argv[2];
3124 unpackBoot((char*)strLoader.c_str());
3125 return true;
3126 } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
3127 if (argc == 4) {
3128 string tag = argv[2];
3129 string spl = argv[3];
3130 printf("tag %s to %s\n", tag.c_str(), spl.c_str());
3131 tag_spl((char*)tag.c_str(), (char*)spl.c_str());
3132 return true;
3133 }
3134 printf("tagspl: parameter error\n");
3135 usage();
3136 }
3137 cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
3138 if(strcmp(strCmd.c_str(), "LD") == 0) {
3139 list_device(pScan);
3140 return (cnt>0)?true:false;
3141 }
3142
3143 if (cnt < 1) {
3144 ERROR_COLOR_ATTR;
3145 printf("Did not find any rockusb device, please plug device in!");
3146 NORMAL_COLOR_ATTR;
3147 printf("\r\n");
3148 return bSuccess;
3149 } else if (cnt > 1) {
3150 ERROR_COLOR_ATTR;
3151 printf("Found too many rockusb devices, please plug devices out!");
3152 NORMAL_COLOR_ATTR;
3153 printf("\r\n");
3154 return bSuccess;
3155 }
3156
3157 bRet = pScan->GetDevice(dev, 0);
3158 if (!bRet) {
3159 ERROR_COLOR_ATTR;
3160 printf("Getting information about rockusb device failed!");
3161 NORMAL_COLOR_ATTR;
3162 printf("\r\n");
3163 return bSuccess;
3164 }
3165
3166 if(strcmp(strCmd.c_str(), "RD") == 0) {
3167 if ((argc != 2) && (argc != 3))
3168 printf("Parameter of [RD] command is invalid, please check help!\r\n");
3169 else {
3170 if (argc == 2)
3171 bSuccess = reset_device(dev);
3172 else {
3173 UINT uiSubCode;
3174 char *pszEnd;
3175 uiSubCode = strtoul(argv[2], &pszEnd, 0);
3176 if (*pszEnd)
3177 printf("Subcode is invalid, please check!\r\n");
3178 else {
3179 if (uiSubCode <= 5)
3180 bSuccess = reset_device(dev, uiSubCode);
3181 else
3182 printf("Subcode is invalid, please check!\r\n");
3183 }
3184 }
3185 }
3186 } else if(strcmp(strCmd.c_str(), "CS") == 0) {
3187 if (argc != 3)
3188 printf("Parameter of [CS] command is invalid, please check help!\r\n");
3189 else {
3190 UINT uiSubCode;
3191 char *pszEnd;
3192 uiSubCode = strtoul(argv[2], &pszEnd, 0);
3193 if (*pszEnd)
3194 printf("Storage is invalid, please check!\r\n");
3195 else {
3196 bSuccess = change_storage(dev, uiSubCode);
3197 }
3198 }
3199 } else if(strcmp(strCmd.c_str(), "TD") == 0) {
3200 bSuccess = test_device(dev);
3201 } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
3202 bSuccess = read_flash_id(dev);
3203 } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
3204 bSuccess = read_flash_info(dev);
3205 } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
3206 bSuccess = read_chip_info(dev);
3207 } else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability
3208 bSuccess = read_capability(dev);
3209 } else if(strcmp(strCmd.c_str(), "DB") == 0) {
3210 if (argc > 2) {
3211 string strLoader;
3212 strLoader = argv[2];
3213 bSuccess = download_boot(dev, (char *)strLoader.c_str());
3214 } else if (argc == 2) {
3215 ret = find_config_item(g_ConfigItemVec, "loader");
3216 if (ret == -1)
3217 printf("Did not find loader item in config!\r\n");
3218 else
3219 bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
3220 } else
3221 printf("Parameter of [DB] command is invalid, please check help!\r\n");
3222 } else if(strcmp(strCmd.c_str(), "GPT") == 0) {
3223 if (argc > 2) {
3224 string strParameter;
3225 strParameter = argv[2];
3226 bSuccess = write_gpt(dev, (char *)strParameter.c_str());
3227 } else
3228 printf("Parameter of [GPT] command is invalid, please check help!\r\n");
3229 } else if(strcmp(strCmd.c_str(), "PRM") == 0) {
3230 if (argc > 2) {
3231 string strParameter;
3232 strParameter = argv[2];
3233 bSuccess = write_parameter(dev, (char *)strParameter.c_str());
3234 } else
3235 printf("Parameter of [PRM] command is invalid, please check help!\r\n");
3236 } else if(strcmp(strCmd.c_str(), "UL") == 0) {
3237 if (argc > 2) {
3238 string strLoader;
3239 strLoader = argv[2];
3240 bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
3241 } else
3242 printf("Parameter of [UL] command is invalid, please check help!\r\n");
3243 } else if(strcmp(strCmd.c_str(), "EF") == 0) {
3244 if (argc == 2) {
3245 bSuccess = erase_flash(dev);
3246 } else
3247 printf("Parameter of [EF] command is invalid, please check help!\r\n");
3248 } else if(strcmp(strCmd.c_str(), "WL") == 0) {
3249 if (argc == 4) {
3250 UINT uiBegin;
3251 char *pszEnd;
3252 uiBegin = strtoul(argv[2], &pszEnd, 0);
3253 if (*pszEnd)
3254 printf("Begin is invalid, please check!\r\n");
3255 else {
3256 if (is_sparse_image(argv[3]))
3257 bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]);
3258 else {
3259 bSuccess = true;
3260 if (is_ubifs_image(argv[3]))
3261 bSuccess = erase_ubi_block(dev, (u32)uiBegin, (u32)-1);
3262 if (bSuccess)
3263 bSuccess = write_lba(dev, (u32)uiBegin, argv[3]);
3264 else
3265 printf("Failure of Erase for writing ubi image!\r\n");
3266 }
3267 }
3268 } else
3269 printf("Parameter of [WL] command is invalid, please check help!\r\n");
3270 } else if(strcmp(strCmd.c_str(), "WLX") == 0) {
3271 if (argc == 4) {
3272 bRet = read_gpt(dev, master_gpt);
3273 if (bRet) {
3274 bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end);
3275 if (bRet) {
3276 if (is_sparse_image(argv[3]))
3277 bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]);
3278 else {
3279 bSuccess = true;
3280 if (is_ubifs_image(argv[3]))
3281 {
3282 if (lba_end == 0xFFFFFFFF)
3283 bSuccess = erase_ubi_block(dev, (u32)lba, (u32)lba_end);
3284 else
3285 bSuccess = erase_ubi_block(dev, (u32)lba, (u32)(lba_end - lba + 1));
3286 }
3287 if (bSuccess)
3288 bSuccess = write_lba(dev, (u32)lba, argv[3]);
3289 else
3290 printf("Failure of Erase for writing ubi image!\r\n");
3291 }
3292 } else
3293 printf("No found %s partition\r\n", argv[2]);
3294 } else {
3295 bRet = read_param(dev, param_buffer);
3296 if (bRet) {
3297 bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size);
3298 if (bRet) {
3299 if (is_sparse_image(argv[3]))
3300 bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]);
3301 else {
3302
3303 bSuccess = true;
3304 if (is_ubifs_image(argv[3]))
3305 bSuccess = erase_ubi_block(dev, part_offset, part_size);
3306 if (bSuccess)
3307 bSuccess = write_lba(dev, part_offset, argv[3]);
3308 else
3309 printf("Failure of Erase for writing ubi image!\r\n");
3310 }
3311 } else
3312 printf("No found %s partition\r\n", argv[2]);
3313 }
3314 else
3315 printf("Not found any partition table!\r\n");
3316 }
3317
3318 } else
3319 printf("Parameter of [WLX] command is invalid, please check help!\r\n");
3320 } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
3321 char *pszEnd;
3322 UINT uiBegin, uiLen;
3323 if (argc != 5)
3324 printf("Parameter of [RL] command is invalid, please check help!\r\n");
3325 else {
3326 uiBegin = strtoul(argv[2], &pszEnd, 0);
3327 if (*pszEnd)
3328 printf("Begin is invalid, please check!\r\n");
3329 else {
3330 uiLen = strtoul(argv[3], &pszEnd, 0);
3331 if (*pszEnd)
3332 printf("Len is invalid, please check!\r\n");
3333 else {
3334 bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
3335 }
3336 }
3337 }
3338 } else if(strcmp(strCmd.c_str(), "PPT") == 0) {
3339 if (argc == 2) {
3340 bSuccess = print_gpt(dev);
3341 if (!bSuccess) {
3342 bSuccess = print_parameter(dev);
3343 if (!bSuccess)
3344 printf("Not found any partition table!\r\n");
3345 }
3346 } else
3347 printf("Parameter of [PPT] command is invalid, please check help!\r\n");
3348 } else {
3349 printf("command is invalid!\r\n");
3350 usage();
3351 }
3352 return bSuccess;
3353 }
3354
3355
main(int argc,char * argv[])3356 int main(int argc, char* argv[])
3357 {
3358 CRKScan *pScan = NULL;
3359 int ret;
3360 char szProgramProcPath[100];
3361 char szProgramDir[256];
3362 string strLogDir,strConfigFile;
3363 struct stat statBuf;
3364
3365 g_ConfigItemVec.clear();
3366
3367 #ifndef __MINGW32__
3368 snprintf(szProgramProcPath, sizeof(szProgramProcPath), "/proc/%d/exe", getpid());
3369 if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
3370 strcpy(szProgramDir, ".");
3371 else
3372 #else
3373 strcpy(szProgramDir, ".");
3374 #endif
3375 {
3376 char *pSlash;
3377 pSlash = strrchr(szProgramDir, '/');
3378 if (pSlash)
3379 *pSlash = '\0';
3380 }
3381
3382 strLogDir = szProgramDir;
3383 strLogDir += "/log/";
3384 strConfigFile = szProgramDir;
3385 strConfigFile += "/config.ini";
3386 if (opendir(strLogDir.c_str()) == NULL)
3387 #ifndef __MINGW32__
3388 mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
3389 #else
3390 mkdir(strLogDir.c_str());
3391 #endif
3392 g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
3393
3394 if(stat(strConfigFile.c_str(), &statBuf) < 0) {
3395 if (g_pLogObject) {
3396 g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
3397 }
3398 } else if (S_ISREG(statBuf.st_mode)) {
3399 parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
3400 }
3401
3402 ret = libusb_init(NULL);
3403 if (ret < 0) {
3404 if (g_pLogObject) {
3405 g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
3406 delete g_pLogObject;
3407 }
3408 return -1;
3409 }
3410
3411 pScan = new CRKScan();
3412 if (!pScan) {
3413 if (g_pLogObject) {
3414 g_pLogObject->Record("Error: failed to create object for searching device");
3415 delete g_pLogObject;
3416 }
3417 libusb_exit(NULL);
3418 return -2;
3419 }
3420 pScan->SetVidPid();
3421
3422 if (argc == 1)
3423 usage();
3424 else if (!handle_command(argc, argv, pScan))
3425 return -0xFF;
3426 if (pScan)
3427 delete pScan;
3428 if (g_pLogObject)
3429 delete g_pLogObject;
3430 libusb_exit(NULL);
3431 return 0;
3432 }
3433