xref: /rkdeveloptool/main.cpp (revision 8df2d64a809a0bd3732b418e5659324ca8a9aa31)
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[37;40m", 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 
42 void usage()
43 {
44 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
45 	printf("Help:             -H\r\n");
46 	printf("Version:          -V\r\n");
47 	printf("DownloadBoot:	DB <Loader>\r\n");
48 	printf("UpgradeLoader:	UL <Loader>\r\n");
49 	printf("ReadLBA:		RL  <BeginSec> <SectorLen> <File>\r\n");
50 	printf("WriteLBA:		WL  <BeginSec> <File>\r\n");
51 	printf("WriteGPT:       GPT <parameter>\r\n");
52 	printf("EraseFlash:		EF \r\n");
53 	printf("TestDevice:		TD\r\n");
54 	printf("ResetDevice:	RD [subcode]\r\n");
55 	printf("ReadFlashID:	RID\r\n");
56 	printf("ReadFlashInfo:	RFI\r\n");
57 	printf("ReadChipInfo:	RCI\r\n");
58 	printf("-------------------------------------------------------\r\n\r\n");
59 }
60 void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
61 {
62 	string strInfoText="";
63 	char szText[256];
64 	switch (promptID) {
65 	case TESTDEVICE_PROGRESS:
66 		sprintf(szText, "Test Device Total(%lld),Current(%lld)", totalValue, currentValue);
67 		strInfoText = szText;
68 		break;
69 	case LOWERFORMAT_PROGRESS:
70 		sprintf(szText, "Lowerformat Device Total(%lld),Current(%lld)", totalValue, currentValue);
71 		strInfoText = szText;
72 		break;
73 	case DOWNLOADIMAGE_PROGRESS:
74 		sprintf(szText, "Download Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
75 		strInfoText = szText;
76 		break;
77 	case CHECKIMAGE_PROGRESS:
78 		sprintf(szText, "Check Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
79 		strInfoText = szText;
80 		break;
81 	case TAGBADBLOCK_PROGRESS:
82 		sprintf(szText, "Tag Bad Block Total(%lld),Current(%lld)", totalValue, currentValue);
83 		strInfoText = szText;
84 		break;
85 	case TESTBLOCK_PROGRESS:
86 		sprintf(szText, "Test Block Total(%lld),Current(%lld)", totalValue, currentValue);
87 		strInfoText = szText;
88 		break;
89 	case ERASEFLASH_PROGRESS:
90 		sprintf(szText, "Erase Flash Total(%lld),Current(%lld)", totalValue, currentValue);
91 		strInfoText = szText;
92 		break;
93 	case ERASESYSTEM_PROGRESS:
94 		sprintf(szText, "Erase System partition Total(%lld),Current(%lld)", totalValue, currentValue);
95 		strInfoText = szText;
96 		break;
97 	case ERASEUSERDATA_PROGRESS:
98 		sprintf(szText, "<LocationID=%x> Erase Userdata partition Total(%lld),Current(%lld)",deviceLayer,totalValue, currentValue);
99 		strInfoText = szText;
100 		break;
101 	}
102 	if (strInfoText.size() > 0){
103 		CURSOR_MOVEUP_LINE(1);
104 		CURSOR_DEL_LINE;
105 		printf("%s\r\n", strInfoText.c_str());
106 	}
107 	if (emCall == CALL_LAST)
108 		deviceLayer = 0;
109 }
110 
111 char *strupr(char *szSrc)
112 {
113 	char *p = szSrc;
114 	while(*p){
115 		if ((*p >= 'a') && (*p <= 'z'))
116 			*p = *p - 'a' + 'A';
117 		p++;
118 	}
119 	return szSrc;
120 }
121 void PrintData(PBYTE pData, int nSize)
122 {
123 	char szPrint[17] = "\0";
124 	int i;
125 	for( i = 0; i < nSize; i++){
126 		if(i % 16 == 0){
127 			if(i / 16 > 0)
128 				printf("     %s\r\n", szPrint);
129 			printf("%08d ", i / 16);
130 		}
131 		printf("%02X ", pData[i]);
132 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
133 	}
134 	if(i / 16 > 0)
135 		printf("     %s\r\n", szPrint);
136 }
137 
138 bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
139 {
140 	if (!pszSrc)
141 		return false;
142 	int nSrcLen = strlen(pszSrc);
143 	int nDestLen = nSrcLen * 2;
144 
145 	pszDest = NULL;
146 	pszDest = new wchar_t[nDestLen];
147 	if (!pszDest)
148 		return false;
149 	nDestLen = nDestLen * sizeof(wchar_t);
150 	memset(pszDest, 0, nDestLen);
151 	int iRet;
152 	iconv_t cd;
153 	cd = iconv_open("UTF-32", "UTF-8");
154 	if((iconv_t)-1 == cd) {
155 		delete []pszDest;
156 		pszDest = NULL;
157 	      return false;
158 	 }
159 	char *pIn, *pOut;
160 	pIn = (char *)pszSrc;
161 	pOut = (char *)pszDest;
162 
163 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
164 
165 	if(iRet == -1) {
166 		delete []pszDest;
167 		pszDest = NULL;
168 		iconv_close(cd);
169 		return false;
170 	 }
171 
172 	 iconv_close(cd);
173 
174 	 return true;
175 }
176 bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
177 {
178 	if (!pszSrc)
179 		return false;
180 	int nSrcLen = wcslen(pszSrc);
181 	int nDestLen = nSrcLen * 2;
182 	nSrcLen = nSrcLen * sizeof(wchar_t);
183 	pszDest = NULL;
184 	pszDest = new char[nDestLen];
185 	if (!pszDest)
186 		return false;
187 	memset(pszDest, 0, nDestLen);
188 	int iRet;
189 	iconv_t cd;
190 	cd = iconv_open("UTF-8", "UTF-32");
191 
192 	if((iconv_t)-1 == cd) {
193 		delete []pszDest;
194 		pszDest = NULL;
195 	      return false;
196 	 }
197 	char *pIn, *pOut;
198 	pIn = (char *)pszSrc;
199 	pOut = (char *)pszDest;
200 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
201 
202 	if(iRet == -1) {
203 		delete []pszDest;
204 		pszDest = NULL;
205 		iconv_close(cd);
206 		return false;
207 	 }
208 
209 	 iconv_close(cd);
210 
211 	 return true;
212 }
213 int find_config_item(const char *pszName)
214 {
215 	unsigned int i;
216 	for(i = 0; i < g_ConfigItemVec.size(); i++){
217 		if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){
218 			return i;
219 		}
220 	}
221 	return -1;
222 }
223 
224 bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
225 {
226 
227 	stringstream configStream(pConfig);
228 	string strLine, strItemName, strItemValue;
229 	string::size_type line_size,pos;
230 	STRUCT_CONFIG_ITEM item;
231 	vecItem.clear();
232 	while (!configStream.eof()){
233 		getline(configStream, strLine);
234 		line_size = strLine.size();
235 		if (line_size == 0)
236 			continue;
237 		if (strLine[line_size-1] == '\r'){
238 			strLine = strLine.substr(0, line_size-1);
239 		}
240 		strLine.erase(0, strLine.find_first_not_of(" "));
241 		strLine.erase(strLine.find_last_not_of(" ") + 1);
242 		if (strLine.size()==0 )
243 			continue;
244 		if (strLine[0] == '#')
245 			continue;
246 		pos = strLine.find("=");
247 		if (pos == string::npos){
248 			continue;
249 		}
250 		strItemName = strLine.substr(0, pos);
251 		strItemValue = strLine.substr(pos + 1);
252 		strItemName.erase(0, strItemName.find_first_not_of(" "));
253 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
254 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
255 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
256 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
257 			strcpy(item.szItemName, strItemName.c_str());
258 			strcpy(item.szItemValue, strItemValue.c_str());
259 			vecItem.push_back(item);
260 		}
261 	}
262 	return true;
263 
264 }
265 bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
266 {
267 	FILE *file = NULL;
268 	file = fopen(pConfigFile, "rb");
269 	if( !file ){
270 		if (g_pLogObject)
271 			g_pLogObject->Record("parse_config_file failed,err=%d,can't open file: %s\r\n", errno, pConfigFile);
272 		return false;
273 	}
274 	int iFileSize;
275 	fseek(file, 0, SEEK_END);
276 	iFileSize = ftell(file);
277 	fseek(file, 0, SEEK_SET);
278 	char *pConfigBuf = NULL;
279 	pConfigBuf = new char[iFileSize + 1];
280 	if (!pConfigBuf){
281 		fclose(file);
282 		return false;
283 	}
284 	memset(pConfigBuf, 0, iFileSize + 1);
285 	int iRead;
286 	iRead = fread(pConfigBuf, 1, iFileSize, file);
287 	if (iRead != iFileSize){
288 		if (g_pLogObject)
289 			g_pLogObject->Record("parse_config_file failed,err=%d, read=%d, total=%d\r\n", errno, iRead, iFileSize);
290 		fclose(file);
291 		delete []pConfigBuf;
292 		return false;
293 	}
294 	fclose(file);
295 	bool bRet;
296 	bRet = parse_config(pConfigBuf, vecItem);
297 	delete []pConfigBuf;
298 	return bRet;
299 }
300 bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
301 {
302 	string::size_type pos,prevPos;
303 	string strOffset,strLen;
304 	int iCount;
305 	prevPos = pos = 0;
306 	if (strPartInfo.size() <= 0) {
307 		return false;
308 	}
309 	pos = strPartInfo.find('@');
310 	if (pos == string::npos) {
311 		return false;
312 	}
313 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
314 	strLen.erase(0, strLen.find_first_not_of(" "));
315 	strLen.erase(strLen.find_last_not_of(" ") + 1);
316 	if (strchr(strLen.c_str(), '-')) {
317 		uiLen = 0xFFFFFFFF;
318 	} else {
319 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
320 		if (iCount != 1) {
321 			return false;
322 		}
323 	}
324 
325 	prevPos = pos + 1;
326 	pos = strPartInfo.find('(',prevPos);
327 	if (pos == string::npos) {
328 		return false;
329 	}
330 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
331 	strOffset.erase(0, strOffset.find_first_not_of(" "));
332 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
333 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
334 	if (iCount != 1) {
335 		return false;
336 	}
337 	prevPos = pos + 1;
338 	pos = strPartInfo.find(')', prevPos);
339 	if (pos == string::npos) {
340 		return false;
341 	}
342 	strName = strPartInfo.substr(prevPos, pos - prevPos);
343 	strName.erase(0, strName.find_first_not_of(" "));
344 	strName.erase(strName.find_last_not_of(" ") + 1);
345 
346 	return true;
347 }
348 
349 bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem)
350 {
351 	stringstream paramStream(pParameter);
352 	bool bRet,bFind = false;
353 	string strLine, strPartition, strPartInfo, strPartName;
354 	string::size_type line_size, pos, posColon, posComma;
355 	UINT uiPartOffset, uiPartSize;
356 	STRUCT_PARAM_ITEM item;
357 	vecItem.clear();
358 	while (!paramStream.eof()) {
359 		getline(paramStream,strLine);
360 		line_size = strLine.size();
361 		if (line_size == 0)
362 			continue;
363 		if (strLine[line_size - 1] == '\r'){
364 			strLine = strLine.substr(0, line_size - 1);
365 		}
366 		strLine.erase(0, strLine.find_first_not_of(" "));
367 		strLine.erase(strLine.find_last_not_of(" ") + 1);
368 		if (strLine.size()==0 )
369 			continue;
370 		if (strLine[0] == '#')
371 			continue;
372 		pos = strLine.find("mtdparts");
373 		if (pos == string::npos) {
374 			continue;
375 		}
376 		bFind = true;
377 		posColon = strLine.find(':', pos);
378 		if (posColon == string::npos) {
379 			continue;
380 		}
381 		strPartition = strLine.substr(posColon + 1);
382 		pos = 0;
383 		posComma = strPartition.find(',', pos);
384 		while (posComma != string::npos) {
385 			strPartInfo = strPartition.substr(pos, posComma - pos);
386 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
387 			if (bRet) {
388 				strcpy(item.szItemName, strPartName.c_str());
389 				item.uiItemOffset = uiPartOffset;
390 				item.uiItemSize = uiPartSize;
391 				vecItem.push_back(item);
392 			}
393 			pos = posComma + 1;
394 			posComma = strPartition.find(',', pos);
395 		}
396 		strPartInfo = strPartition.substr(pos);
397 		if (strPartInfo.size() > 0) {
398 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
399 			if (bRet) {
400 				strcpy(item.szItemName, strPartName.c_str());
401 				item.uiItemOffset = uiPartOffset;
402 				item.uiItemSize = uiPartSize;
403 				vecItem.push_back(item);
404 			}
405 		}
406 		break;
407 	}
408 	return bFind;
409 
410 }
411 bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem)
412 {
413 	FILE *file = NULL;
414 	file = fopen(pParamFile, "rb");
415 	if( !file ) {
416 		if (g_pLogObject)
417 			g_pLogObject->Record("parse_parameter_file failed, err=%d, can't open file: %s\r\n", errno, pParamFile);
418 		return false;
419 	}
420 	int iFileSize;
421 	fseek(file, 0, SEEK_END);
422 	iFileSize = ftell(file);
423 	fseek(file, 0, SEEK_SET);
424 	char *pParamBuf = NULL;
425 	pParamBuf = new char[iFileSize];
426 	if (!pParamBuf) {
427 		fclose(file);
428 		return false;
429 	}
430 	int iRead;
431 	iRead = fread(pParamBuf, 1, iFileSize, file);
432 	if (iRead != iFileSize) {
433 		if (g_pLogObject)
434 			g_pLogObject->Record("parse_parameter_file failed, err=%d, read=%d, total=%d\r\n", errno,iRead,iFileSize);
435 		fclose(file);
436 		delete []pParamBuf;
437 		return false;
438 	}
439 	fclose(file);
440 	bool bRet;
441 	bRet = parse_parameter(pParamBuf, vecItem);
442 	delete []pParamBuf;
443 	return bRet;
444 }
445 void gen_rand_uuid(unsigned char *uuid_bin)
446 {
447 	efi_guid_t id;
448 	unsigned int *ptr = (unsigned int *)&id;
449 	unsigned int i;
450 
451 	/* Set all fields randomly */
452 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
453 		*(ptr + i) = cpu_to_be32(rand());
454 
455 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
456 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
457 
458 	memcpy(uuid_bin, id.raw, sizeof(id));
459 }
460 
461 void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, u64 diskSectors)
462 {
463 	legacy_mbr *mbr = (legacy_mbr *)gpt;
464 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
465 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
466 	u32 i,j;
467 	string strPartName;
468 	string::size_type colonPos;
469 	/*1.protective mbr*/
470 	memset(gpt, 0, SECTOR_SIZE);
471 	mbr->signature = MSDOS_MBR_SIGNATURE;
472 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
473 	mbr->partition_record[0].start_sect = 1;
474 	mbr->partition_record[0].nr_sects = (u32)-1;
475 	/*2.gpt header*/
476 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
477 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
478 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
479 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
480 	gptHead->my_lba = cpu_to_le64(1);
481 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
482 	gptHead->first_usable_lba = cpu_to_le64(34);
483 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
484 	gptHead->partition_entry_lba = cpu_to_le64(2);
485 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
486 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
487 	gptHead->header_crc32 = 0;
488 	gptHead->partition_entry_array_crc32 = 0;
489 	gen_rand_uuid(gptHead->disk_guid.raw);
490 
491 	/*3.gpt partition entry*/
492 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
493 	for (i = 0; i < vecParts.size(); i++) {
494 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
495 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
496 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
497 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
498 		gptEntry->attributes.raw = 0;
499 		strPartName = vecParts[i].szItemName;
500 		colonPos = strPartName.find_first_of(':');
501 		if (colonPos != string::npos) {
502 			if (strPartName.find("bootable") != string::npos)
503 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
504 			strPartName = strPartName.substr(0, colonPos);
505 			vecParts[i].szItemName[strPartName.size()] = 0;
506 		}
507 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
508 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
509 		gptEntry++;
510 	}
511 
512 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
513 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
514 
515 }
516 bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec)
517 {
518 	PRK28_IDB_SEC0 pSec0;
519 	memset(pSector, 0, SECTOR_SIZE);
520 	pSec0 = (PRK28_IDB_SEC0)pSector;
521 
522 	pSec0->dwTag = 0x0FF0AA55;
523 	pSec0->uiRc4Flag = 1;
524 	pSec0->usBootCode1Offset = 0x4;
525 	pSec0->usBootCode2Offset = 0x4;
526 	pSec0->usBootDataSize = usFlashDataSec;
527 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
528 	return true;
529 }
530 
531 
532 bool MakeSector1(PBYTE pSector)
533 {
534 	PRK28_IDB_SEC1 pSec1;
535 	memset(pSector, 0, SECTOR_SIZE);
536 	pSec1 = (PRK28_IDB_SEC1)pSector;
537 
538 	pSec1->usSysReservedBlock = 0xC;
539 	pSec1->usDisk0Size = 0xFFFF;
540 	pSec1->uiChipTag = 0x38324B52;
541 	return true;
542 }
543 
544 bool MakeSector2(PBYTE pSector)
545 {
546 	PRK28_IDB_SEC2 pSec2;
547 	memset(pSector, 0, SECTOR_SIZE);
548 	pSec2 = (PRK28_IDB_SEC2)pSector;
549 
550 	strcpy(pSec2->szVcTag, "VC");
551 	strcpy(pSec2->szCrcTag, "CRC");
552 	return true;
553 }
554 
555 bool MakeSector3(PBYTE pSector)
556 {
557 	memset(pSector,0,SECTOR_SIZE);
558 	return true;
559 }
560 
561 int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize)
562 {
563 	RK28_IDB_SEC0 sector0Info;
564 	RK28_IDB_SEC1 sector1Info;
565 	RK28_IDB_SEC2 sector2Info;
566 	RK28_IDB_SEC3 sector3Info;
567 	UINT i;
568 
569 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec);
570 	MakeSector1((PBYTE)&sector1Info);
571 	if (!MakeSector2((PBYTE)&sector2Info)) {
572 		return -6;
573 	}
574 	if (!MakeSector3((PBYTE)&sector3Info)) {
575 		return -7;
576 	}
577 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
578 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
579 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
580 
581 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
582 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
583 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
584 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
585 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
586 
587 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
588 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
589 	for(i = 0; i < 4; i++) {
590 		if(i == 1) {
591 			continue;
592 		} else {
593 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
594 		}
595 	}
596 	return 0;
597 }
598 
599 
600 
601 bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
602 {
603 	if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
604 		return true;
605 	else
606 	{
607 		ERROR_COLOR_ATTR;
608 		printf("The  Device did not support this operation!");
609 		NORMAL_COLOR_ATTR;
610 		printf("\r\n");
611 		return false;
612 	}
613 }
614 bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
615 {
616 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
617 	u32 total_size_sector;
618 	CRKComm *pComm = NULL;
619 	PARAM_ITEM_VECTOR vecItems;
620 	int iRet;
621 	bool bRet, bSuccess = false;
622 	if (!check_device_type(dev, RKUSB_MASKROM))
623 		return false;
624 
625 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
626 	if (!bRet) {
627 		ERROR_COLOR_ATTR;
628 		printf("Creating Comm Object failed!");
629 		NORMAL_COLOR_ATTR;
630 		printf("\r\n");
631 		return bSuccess;
632 	}
633 	printf("Write gpt...\r\n");
634 	//1.get flash info
635 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
636 	if (iRet != ERR_SUCCESS) {
637 		ERROR_COLOR_ATTR;
638 		printf("Reading Flash Info failed!");
639 		NORMAL_COLOR_ATTR;
640 		printf("\r\n");
641 		return bSuccess;
642 	}
643 	total_size_sector = *(u32 *)flash_info;
644 	//2.get partition from parameter
645 	bRet = parse_parameter_file(szParameter, vecItems);
646 	if (!bRet) {
647 		ERROR_COLOR_ATTR;
648 		printf("Parsing parameter failed!");
649 		NORMAL_COLOR_ATTR;
650 		printf("\r\n");
651 		return bSuccess;
652 	}
653 	vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 34;
654 	//3.generate gpt info
655 	create_gpt_buffer(master_gpt, vecItems, total_size_sector);
656 	memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
657 	memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
658 	//4. write gpt
659 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
660 	if (iRet != ERR_SUCCESS) {
661 		ERROR_COLOR_ATTR;
662 		printf("Writing master gpt failed!");
663 		NORMAL_COLOR_ATTR;
664 		printf("\r\n");
665 		return bSuccess;
666 	}
667 	iRet = pComm->RKU_WriteLBA(total_size_sector - 34, 33, backup_gpt);
668 	if (iRet != ERR_SUCCESS) {
669 		ERROR_COLOR_ATTR;
670 		printf("Writing backup gpt failed!");
671 		NORMAL_COLOR_ATTR;
672 		printf("\r\n");
673 		return bSuccess;
674 	}
675 	bSuccess = true;
676 	CURSOR_MOVEUP_LINE(1);
677 	CURSOR_DEL_LINE;
678 	printf("Write gpt ok.\r\n");
679 	return bSuccess;
680 }
681 
682 bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
683 {
684 	if (!check_device_type(dev, RKUSB_MASKROM))
685 		return false;
686 	CRKImage *pImage = NULL;
687 	CRKBoot *pBoot = NULL;
688 	bool bRet, bSuccess = false;
689 	int iRet;
690 
691 	pImage = new CRKImage(szLoader, bRet);
692 	if (!bRet){
693 		ERROR_COLOR_ATTR;
694 		printf("Open loader failed,exit download boot!");
695 		NORMAL_COLOR_ATTR;
696 		printf("\r\n");
697 		return bSuccess;
698 	} else {
699 		pBoot = (CRKBoot *)pImage->m_bootObject;
700 		CRKComm *pComm = NULL;
701 		CRKDevice *pDevice = NULL;
702 
703 		dev.emDeviceType = pBoot->SupportDevice;
704 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
705 		if (!bRet) {
706 			if (pImage)
707 				delete pImage;
708 			ERROR_COLOR_ATTR;
709 			printf("Creating Comm Object failed!");
710 			NORMAL_COLOR_ATTR;
711 			printf("\r\n");
712 			return bSuccess;
713 		}
714 
715 		pDevice = new CRKDevice(dev);
716 		if (!pDevice) {
717 			if (pImage)
718 				delete pImage;
719 			if (pComm)
720 				delete pComm;
721 			ERROR_COLOR_ATTR;
722 			printf("Creating device object failed!");
723 			NORMAL_COLOR_ATTR;
724 			printf("\r\n");
725 			return bSuccess;
726 		}
727 
728 		pDevice->SetObject(pImage, pComm, g_pLogObject);
729 		printf("Download boot...\r\n");
730 		iRet = pDevice->DownloadBoot();
731 
732 		CURSOR_MOVEUP_LINE(1);
733 		CURSOR_DEL_LINE;
734 		if (iRet == 0) {
735 			pComm->Reset_Usb_Device();
736 			CRKScan *pScan = NULL;
737 			pScan = new CRKScan();
738 			if (pScan) {
739 				pScan->SetVidPid();
740 				pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
741 				delete pScan;
742 			}
743 			bSuccess = true;
744 			printf("Download boot ok.\r\n");
745 		}
746 		else
747 			printf("Download boot failed!\r\n");
748 
749 		if (pImage)
750 			delete pImage;
751 		if(pDevice)
752 			delete pDevice;
753 	}
754 	return bSuccess;
755 }
756 bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
757 {
758 	if (!check_device_type(dev, RKUSB_MASKROM))
759 		return false;
760 	CRKImage *pImage = NULL;
761 	CRKBoot *pBoot = NULL;
762 	CRKComm *pComm = NULL;
763 	bool bRet, bSuccess = false;
764 	int iRet;
765 	char index;
766 	USHORT usFlashDataSec, usFlashBootSec;
767 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
768 	char loaderCodeName[] = "FlashBoot";
769 	char loaderDataName[] = "FlashData";
770 	PBYTE loaderCodeBuffer = NULL;
771 	PBYTE loaderDataBuffer = NULL;
772 	PBYTE pIDBData = NULL;
773 	pImage = new CRKImage(szLoader, bRet);
774 	if (!bRet){
775 		ERROR_COLOR_ATTR;
776 		printf("Open loader failed,exit upgrade loader!");
777 		NORMAL_COLOR_ATTR;
778 		printf("\r\n");
779 		goto Exit_UpgradeLoader;
780 	} else {
781 		pBoot = (CRKBoot *)pImage->m_bootObject;
782 		dev.emDeviceType = pBoot->SupportDevice;
783 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
784 		if (!bRet) {
785 			ERROR_COLOR_ATTR;
786 			printf("Creating Comm Object failed!");
787 			NORMAL_COLOR_ATTR;
788 			printf("\r\n");
789 			goto Exit_UpgradeLoader;
790 		}
791 
792 		printf("Upgrade loader...\r\n");
793 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
794 		if (index == -1) {
795 			if (g_pLogObject) {
796 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed");
797 			}
798 			goto Exit_UpgradeLoader;
799 		}
800 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
801 		if (!bRet) {
802 			if (g_pLogObject) {
803 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed");
804 			}
805 			goto Exit_UpgradeLoader;
806 		}
807 
808 		loaderCodeBuffer = new BYTE[dwLoaderSize];
809 		memset(loaderCodeBuffer, 0, dwLoaderSize);
810 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
811 			if (g_pLogObject) {
812 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed");
813 			}
814 			goto Exit_UpgradeLoader;
815 		}
816 
817 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
818 		if (index == -1) {
819 			if (g_pLogObject) {
820 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed");
821 			}
822 			delete []loaderCodeBuffer;
823 			return -4;
824 		}
825 
826 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
827 		if (!bRet) {
828 			if (g_pLogObject) {
829 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed");
830 			}
831 			goto Exit_UpgradeLoader;
832 		}
833 
834 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
835 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
836 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
837 			if (g_pLogObject) {
838 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed");
839 			}
840 			goto Exit_UpgradeLoader;
841 		}
842 
843 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
844 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
845 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
846 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
847 		if (!pIDBData) {
848 			ERROR_COLOR_ATTR;
849 			printf("New memory failed!");
850 			NORMAL_COLOR_ATTR;
851 			printf("\r\n");
852 			goto Exit_UpgradeLoader;
853 		}
854 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
855 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize);
856 		if (iRet != 0) {
857 			ERROR_COLOR_ATTR;
858 			printf("Make idblock failed!");
859 			NORMAL_COLOR_ATTR;
860 			printf("\r\n");
861 			goto Exit_UpgradeLoader;
862 		}
863 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
864 		CURSOR_MOVEUP_LINE(1);
865 		CURSOR_DEL_LINE;
866 		if (iRet == ERR_SUCCESS) {
867 			pComm->Reset_Usb_Device();
868 			bSuccess = true;
869 			printf("Upgrade loader ok.\r\n");
870 		} else {
871 			printf("Upgrade loader failed!\r\n");
872 			goto Exit_UpgradeLoader;
873 		}
874 	}
875 Exit_UpgradeLoader:
876 	if (pImage)
877 		delete pImage;
878 	if (pComm)
879 		delete pComm;
880 	if (loaderCodeBuffer)
881 		delete []loaderCodeBuffer;
882 	if (loaderDataBuffer)
883 		delete []loaderDataBuffer;
884 	if (pIDBData)
885 		delete []pIDBData;
886 	return bSuccess;
887 }
888 
889 bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
890 {
891 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
892 		return false;
893 	CRKImage *pImage = NULL;
894 	bool bRet, bSuccess = false;
895 	int iRet;
896 	CRKScan *pScan = NULL;
897 	pScan = new CRKScan();
898 	pScan->SetVidPid();
899 
900 	CRKComm *pComm = NULL;
901 	CRKDevice *pDevice = NULL;
902 
903 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
904 	if (!bRet) {
905 		if (pScan)
906 			delete pScan;
907 		ERROR_COLOR_ATTR;
908 		printf("Creating Comm Object failed!");
909 		NORMAL_COLOR_ATTR;
910 		printf("\r\n");
911 		return bSuccess;
912 	}
913 
914 	pDevice = new CRKDevice(dev);
915 	if (!pDevice) {
916 		if (pComm)
917 			delete pComm;
918 		if (pScan)
919 			delete pScan;
920 		ERROR_COLOR_ATTR;
921 		printf("Creating device object failed!");
922 		NORMAL_COLOR_ATTR;
923 		printf("\r\n");
924 		return bSuccess;
925 	}
926 
927 	pDevice->SetObject(pImage, pComm, g_pLogObject);
928 	pDevice->CallBackPointer = ProgressInfoProc;
929 
930 	printf("Start to erase flash...\r\n");
931 	iRet = pDevice->EraseAllBlocks();
932 	if (pDevice)
933 		delete pDevice;
934 
935 	if (iRet == 0) {
936 		if (pScan) {
937 			pScan->SetVidPid();
938 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
939 			delete pScan;
940 		}
941 		CURSOR_MOVEUP_LINE(1);
942 		CURSOR_DEL_LINE;
943 		bSuccess = true;
944 		printf("Erase flash ok.\r\n");
945 	}
946 
947 	return bSuccess;
948 }
949 
950 bool test_device(STRUCT_RKDEVICE_DESC &dev)
951 {
952 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
953 		return false;
954 	CRKUsbComm *pComm = NULL;
955 	bool bRet, bSuccess = false;
956 	int iRet;
957 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
958 	if (bRet) {
959 		iRet = pComm->RKU_TestDeviceReady();
960 		if (iRet != ERR_SUCCESS) {
961 			if (g_pLogObject)
962 				g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet);
963 			printf("Test Device Fail!\r\n");
964 		} else {
965 			bSuccess = true;
966 			printf("Test Device OK.\r\n");
967 		}
968 	} else {
969 		printf("Test Device quit,Creating comm object failed!\r\n");
970 	}
971 	if (pComm) {
972 		delete pComm;
973 		pComm = NULL;
974 	}
975 	return bSuccess;
976 }
977 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
978 {
979 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
980 		return false;
981 	CRKUsbComm *pComm = NULL;
982 	bool bRet, bSuccess = false;
983 	int iRet;
984 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
985 	if (bRet) {
986 		iRet = pComm->RKU_ResetDevice(subCode);
987 		if (iRet != ERR_SUCCESS) {
988 			if (g_pLogObject)
989 				g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet);
990 			printf("Reset Device Fail!\r\n");
991 		} else {
992 			bSuccess = true;
993 			printf("Reset Device OK.\r\n");
994 		}
995 	} else {
996 		printf("Reset Device quit,Creating comm object failed!\r\n");
997 	}
998 	if (pComm) {
999 		delete pComm;
1000 		pComm = NULL;
1001 	}
1002 	return bSuccess;
1003 }
1004 
1005 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
1006 {
1007 	CRKUsbComm *pComm = NULL;
1008 	bool bRet, bSuccess = false;
1009 	int iRet;
1010 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
1011 		return bSuccess;
1012 
1013 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
1014 	if (bRet) {
1015 		BYTE flashID[5];
1016 		iRet = pComm->RKU_ReadFlashID(flashID);
1017 		if (iRet != ERR_SUCCESS) {
1018 			if (g_pLogObject)
1019 				g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet);
1020 			printf("Read flash ID Fail!\r\n");
1021 		} else {
1022 			printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
1023 			bSuccess = true;
1024 		}
1025 	} else {
1026 		printf("Read flash ID quit,Creating comm object failed!\r\n");
1027 	}
1028 	if (pComm) {
1029 		delete pComm;
1030 		pComm = NULL;
1031 	}
1032 	return bSuccess;
1033 }
1034 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
1035 {
1036 	CRKUsbComm *pComm = NULL;
1037 	bool bRet, bSuccess = false;
1038 	int iRet;
1039 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
1040 		return bSuccess;
1041 
1042 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
1043 	if (bRet) {
1044 		STRUCT_FLASHINFO_CMD info;
1045 		UINT uiRead;
1046 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
1047 		if (iRet != ERR_SUCCESS) {
1048 			if (g_pLogObject)
1049 				g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet);
1050 			printf("Read flash Info Fail!\r\n");
1051 		} else {
1052 			printf("Flash Info:\r\n");
1053 			if (info.bManufCode <= 7) {
1054 				printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
1055 			}
1056 			else
1057 				printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode);
1058 
1059 			printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024);
1060 			printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2);
1061 			printf("\tPage Size: %dKB\r\n", info.bPageSize / 2);
1062 			printf("\tECC Bits: %d\r\n", info.bECCBits);
1063 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
1064 			printf("\tFlash CS: ");
1065 			for(int i = 0; i < 8; i++) {
1066 				if( info.bFlashCS & (1 << i) )
1067 					printf("Flash<%d> ", i);
1068 			}
1069 			printf("\r\n");
1070 			bSuccess = true;
1071 		}
1072 	}else {
1073 		printf("Read flash Info quit,Creating comm object failed!\r\n");
1074 	}
1075 	if (pComm) {
1076 		delete pComm;
1077 		pComm = NULL;
1078 	}
1079 	return bSuccess;
1080 }
1081 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
1082 {
1083 	CRKUsbComm *pComm = NULL;
1084 	bool bRet, bSuccess = false;
1085 	int iRet;
1086 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
1087 		return bSuccess;
1088 
1089 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
1090 	if (bRet) {
1091 		BYTE chipInfo[16];
1092 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
1093 		if (iRet != ERR_SUCCESS) {
1094 			if (g_pLogObject)
1095 				g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet);
1096 			printf("Read Chip Info Fail!\r\n");
1097 		} else {
1098 			string strChipInfo;
1099 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
1100 			printf("Chip Info:%s\r\n", strChipInfo.c_str());
1101 			bSuccess = true;
1102 		}
1103 	} else {
1104 		printf("Read Chip Info quit,Creating comm object failed!\r\n");
1105 	}
1106 	if (pComm) {
1107 		delete pComm;
1108 		pComm = NULL;
1109 	}
1110 	return bSuccess;
1111 }
1112 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
1113 {
1114 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
1115 		return false;
1116 	CRKUsbComm *pComm = NULL;
1117 	FILE *file = NULL;
1118 	bool bRet, bFirst = true, bSuccess = false;
1119 	int iRet;
1120 	UINT iTotalRead = 0,iRead = 0;
1121 	int nSectorSize = 512;
1122 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
1123 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
1124 	if (bRet) {
1125 		if(szFile) {
1126 			file = fopen(szFile, "wb+");
1127 			if( !file ) {
1128 				printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
1129 				goto Exit_ReadLBA;
1130 			}
1131 		}
1132 
1133 		while(uiLen > 0) {
1134 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
1135 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
1136 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
1137 			if(ERR_SUCCESS == iRet) {
1138 				uiLen -= iRead;
1139 				iTotalRead += iRead;
1140 
1141 				if(szFile) {
1142 					fwrite(pBuf, 1, iRead * nSectorSize, file);
1143 					if (bFirst){
1144 						if (iTotalRead >= 1024)
1145 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
1146 						else
1147 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
1148 						bFirst = false;
1149 					} else {
1150 						CURSOR_MOVEUP_LINE(1);
1151 						CURSOR_DEL_LINE;
1152 						if (iTotalRead >= 1024)
1153 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
1154 						else
1155 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
1156 					}
1157 				}
1158 				else
1159 					PrintData(pBuf, nSectorSize * iRead);
1160 			} else {
1161 				if (g_pLogObject)
1162 					g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet);
1163 
1164 				printf("Read LBA failed!\r\n");
1165 				goto Exit_ReadLBA;
1166 			}
1167 		}
1168 		bSuccess = true;
1169 	} else {
1170 		printf("Read LBA quit,Creating comm object failed!\r\n");
1171 	}
1172 Exit_ReadLBA:
1173 	if (pComm) {
1174 		delete pComm;
1175 		pComm = NULL;
1176 	}
1177 	if (file)
1178 		fclose(file);
1179 	return bSuccess;
1180 }
1181 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
1182 {
1183 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
1184 		return false;
1185 	CRKUsbComm *pComm = NULL;
1186 	FILE *file = NULL;
1187 	bool bRet, bFirst = true, bSuccess = false;
1188 	int iRet;
1189 	long long iTotalWrite = 0, iFileSize = 0;
1190 	UINT iWrite = 0, iRead = 0;
1191 	UINT uiLen;
1192 	int nSectorSize = 512;
1193 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
1194 
1195 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
1196 	if (bRet) {
1197 		file = fopen(szFile, "rb");
1198 		if( !file ) {
1199 			printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
1200 			goto Exit_WriteLBA;
1201 		}
1202 
1203 		iRet = fseeko(file, 0, SEEK_END);
1204 		iFileSize = ftello(file);
1205 		fseeko(file, 0, SEEK_SET);
1206 		while(iTotalWrite < iFileSize) {
1207 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
1208 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
1209 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
1210 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
1211 			if(ERR_SUCCESS == iRet) {
1212 				uiBegin += uiLen;
1213 				iTotalWrite += iWrite;
1214 				if (bFirst) {
1215 					if (iTotalWrite >= 1024)
1216 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
1217 					else
1218 						printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize);
1219 					bFirst = false;
1220 				} else {
1221 					CURSOR_MOVEUP_LINE(1);
1222 					CURSOR_DEL_LINE;
1223 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
1224 				}
1225 			} else {
1226 				if (g_pLogObject)
1227 					g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet);
1228 
1229 				printf("Write LBA failed!\r\n");
1230 				goto Exit_WriteLBA;
1231 			}
1232 		}
1233 		bSuccess = true;
1234 	} else {
1235 		printf("Write LBA quit,Creating comm object failed!\r\n");
1236 	}
1237 Exit_WriteLBA:
1238 	if (pComm) {
1239 		delete pComm;
1240 		pComm = NULL;
1241 	}
1242 	if (file)
1243 		fclose(file);
1244 	return bSuccess;
1245 }
1246 
1247 void split_item(STRING_VECTOR &vecItems, char *pszItems)
1248 {
1249 	string strItem;
1250 	char szItem[100];
1251 	char *pos = NULL, *pStart;
1252 	pStart = pszItems;
1253 	pos = strchr(pStart, ',');
1254 	while(pos != NULL) {
1255 		memset(szItem, 0, 100);
1256 		strncpy(szItem, pStart, pos - pStart);
1257 		strItem = szItem;
1258 		vecItems.push_back(strItem);
1259 		pStart = pos + 1;
1260 		if (*pStart == 0)
1261 			break;
1262 		pos = strchr(pStart, ',');
1263 	}
1264 	if (strlen(pStart) > 0) {
1265 		memset(szItem, 0, 100);
1266 		strncpy(szItem, pStart, strlen(pStart));
1267 		strItem = szItem;
1268 		vecItems.push_back(strItem);
1269 	}
1270 }
1271 
1272 bool handle_command(int argc, char* argv[], CRKScan *pScan)
1273 {
1274 	string strCmd;
1275 	strCmd = argv[1];
1276 	ssize_t cnt;
1277 	bool bRet,bSuccess = false;
1278 	char *s;
1279 	int i, ret;
1280 	STRUCT_RKDEVICE_DESC dev;
1281 
1282 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
1283 	s = (char*)strCmd.c_str();
1284 	for(i = 0; i < (int)strlen(s); i++)
1285 	        s[i] = toupper(s[i]);
1286 	printf("handle_command: %s\n", strCmd.c_str());
1287 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
1288 		usage();
1289 		return true;
1290 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
1291 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
1292 		return true;
1293 	}
1294 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
1295 	if (cnt < 1) {
1296 		ERROR_COLOR_ATTR;
1297 		printf("No found any rockusb device,please plug device in!");
1298 		NORMAL_COLOR_ATTR;
1299 		printf("\r\n");
1300 		return bSuccess;
1301 	} else if (cnt > 1) {
1302 		ERROR_COLOR_ATTR;
1303 		printf("Found many rockusb devices,please plug device out!");
1304 		NORMAL_COLOR_ATTR;
1305 		printf("\r\n");
1306 		return bSuccess;
1307 	}
1308 
1309 	bRet = pScan->GetDevice(dev, 0);
1310 	if (!bRet) {
1311 		ERROR_COLOR_ATTR;
1312 		printf("Getting information of rockusb device failed!");
1313 		NORMAL_COLOR_ATTR;
1314 		printf("\r\n");
1315 		return bSuccess;
1316 	}
1317 
1318 	if(strcmp(strCmd.c_str(), "RD") == 0) {
1319 		if ((argc != 2) && (argc != 3))
1320 			printf("Parameter of [RD] command is invalid,please check help!\r\n");
1321 		else {
1322 			if (argc == 2)
1323 				bSuccess = reset_device(dev);
1324 			else {
1325 				UINT uiSubCode;
1326 				char *pszEnd;
1327 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
1328 				if (*pszEnd)
1329 					printf("Subcode is invalid,please check!\r\n");
1330 				else {
1331 					if (uiSubCode <= 5)
1332 						bSuccess = reset_device(dev, uiSubCode);
1333 					else
1334 						printf("Subcode is invalid,please check!\r\n");
1335 				}
1336 			}
1337 		}
1338 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
1339 		bSuccess = test_device(dev);
1340 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
1341 		bSuccess = read_flash_id(dev);
1342 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
1343 		bSuccess = read_flash_info(dev);
1344 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
1345 		bSuccess = read_chip_info(dev);
1346 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
1347 		if (argc > 2) {
1348 			string strLoader;
1349 			strLoader = argv[2];
1350 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
1351 		} else if (argc == 2) {
1352 			ret = find_config_item("loader");
1353 			if (ret == -1)
1354 				printf("No found loader item from config!\r\n");
1355 			else
1356 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
1357 		} else
1358 			printf("Parameter of [DB] command is invalid,please check help!\r\n");
1359 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
1360 		if (argc > 2) {
1361 			string strParameter;
1362 			strParameter = argv[2];
1363 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
1364 		} else
1365 			printf("Parameter of [GPT] command is invalid,please check help!\r\n");
1366 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
1367 		if (argc > 2) {
1368 			string strLoader;
1369 			strLoader = argv[2];
1370 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
1371 		} else
1372 			printf("Parameter of [UL] command is invalid,please check help!\r\n");
1373 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
1374 		if (argc == 2) {
1375 			bSuccess = erase_flash(dev);
1376 		} else
1377 			printf("Parameter of [EF] command is invalid,please check help!\r\n");
1378 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
1379 		if (argc == 4) {
1380 			UINT uiBegin;
1381 			char *pszEnd;
1382 			uiBegin = strtoul(argv[2], &pszEnd, 0);
1383 			if (*pszEnd)
1384 				printf("Begin is invalid,please check!\r\n");
1385 			else
1386 				bSuccess = write_lba(dev, uiBegin, argv[3]);
1387 		} else
1388 			printf("Parameter of [WL] command is invalid,please check help!\r\n");
1389 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
1390 		char *pszEnd;
1391 		UINT uiBegin, uiLen;
1392 		if (argc != 5)
1393 			printf("Parameter of [RL] command is invalid,please check help!\r\n");
1394 		else {
1395 			uiBegin = strtoul(argv[2], &pszEnd, 0);
1396 			if (*pszEnd)
1397 				printf("Begin is invalid,please check!\r\n");
1398 			else {
1399 				uiLen = strtoul(argv[3], &pszEnd, 0);
1400 				if (*pszEnd)
1401 					printf("Len is invalid,please check!\r\n");
1402 				else {
1403 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
1404 				}
1405 			}
1406 		}
1407 	} else {
1408 		printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n");
1409 	}
1410 	return bSuccess;
1411 }
1412 
1413 
1414 int main(int argc, char* argv[])
1415 {
1416 	CRKScan *pScan = NULL;
1417 	int ret;
1418 	char szProgramProcPath[100];
1419 	char szProgramDir[256];
1420 	string strLogDir,strConfigFile;
1421 	struct stat statBuf;
1422 
1423 	g_ConfigItemVec.clear();
1424 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
1425 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
1426 		strcpy(szProgramDir, ".");
1427 	else {
1428 		char *pSlash;
1429 		pSlash = strrchr(szProgramDir, '/');
1430 		if (pSlash)
1431 			*pSlash = '\0';
1432 	}
1433 	strLogDir = szProgramDir;
1434 	strLogDir +=  "/log/";
1435 	strConfigFile = szProgramDir;
1436 	strConfigFile += "/config.ini";
1437 	if (opendir(strLogDir.c_str()) == NULL)
1438 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
1439 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log");
1440 
1441 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
1442 		if (g_pLogObject) {
1443 			g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno);
1444 		}
1445 	} else if (S_ISREG(statBuf.st_mode)) {
1446 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
1447 	}
1448 
1449 	ret = libusb_init(NULL);
1450 	if (ret < 0) {
1451 		if (g_pLogObject) {
1452 			g_pLogObject->Record("Error:libusb_init failed,err=%d", ret);
1453 			delete g_pLogObject;
1454 		}
1455 		return -1;
1456 	}
1457 
1458 	pScan = new CRKScan();
1459 	if (!pScan) {
1460 		if (g_pLogObject) {
1461 			g_pLogObject->Record("Error:failed to Create object for searching device");
1462 			delete g_pLogObject;
1463 		}
1464 		libusb_exit(NULL);
1465 		return -2;
1466 	}
1467 	pScan->SetVidPid();
1468 
1469 	if (argc == 1)
1470 		usage();
1471 	else if (!handle_command(argc, argv, pScan))
1472 			return -0xFF;
1473 	if (pScan)
1474 		delete pScan;
1475 	if (g_pLogObject)
1476 		delete g_pLogObject;
1477 	libusb_exit(NULL);
1478 	return 0;
1479 }
1480