xref: /rkdeveloptool/main.cpp (revision 46bb4c073624226c3f05b37b9ecc50bbcf543f5a)
176af099aSliuyi /*
276af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi  * Seth Liu 2017.03.01
476af099aSliuyi  *
576af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
676af099aSliuyi  */
776af099aSliuyi 
876af099aSliuyi #include   <unistd.h>
976af099aSliuyi #include   <dirent.h>
10c30d921cSKever Yang #include "config.h"
1176af099aSliuyi #include "DefineHeader.h"
12c30d921cSKever Yang #include "gpt.h"
1376af099aSliuyi #include "RKLog.h"
1476af099aSliuyi #include "RKScan.h"
1576af099aSliuyi #include "RKComm.h"
1676af099aSliuyi #include "RKDevice.h"
1776af099aSliuyi #include "RKImage.h"
1876af099aSliuyi extern const char *szManufName[];
1976af099aSliuyi CRKLog *g_pLogObject=NULL;
2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec;
2176af099aSliuyi #define DEFAULT_RW_LBA 128
2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
2676af099aSliuyi #define ERROR_COLOR_ATTR  printf("%c[30;41m", 0x1B);
273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR  printf("%c[0m", 0x1B);
28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize);
29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize);
30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len);
31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len);
32c30d921cSKever Yang /*
33c30d921cSKever Yang u8 test_gpt_head[] = {
34c30d921cSKever Yang 	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00,
35c30d921cSKever Yang 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36c30d921cSKever Yang 	0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37c30d921cSKever Yang 	0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B,
38c30d921cSKever Yang 	0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39c30d921cSKever Yang 	0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08};
40c30d921cSKever Yang */
41c30d921cSKever Yang 
4276af099aSliuyi void usage()
4376af099aSliuyi {
4476af099aSliuyi 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
45ae4252f0Sliuyi 	printf("Help:\t\t\t-h or --help\r\n");
46154ee062SEddie Cai 	printf("Version:\t\t-v or --version\r\n");
47081d237aSliuyi 	printf("ListDevice:\t\tld\r\n");
48154ee062SEddie Cai 	printf("DownloadBoot:\t\tdb <Loader>\r\n");
49154ee062SEddie Cai 	printf("UpgradeLoader:\t\tul <Loader>\r\n");
50154ee062SEddie Cai 	printf("ReadLBA:\t\trl  <BeginSec> <SectorLen> <File>\r\n");
51154ee062SEddie Cai 	printf("WriteLBA:\t\twl  <BeginSec> <File>\r\n");
526ae612beSliuyi 	printf("WriteLBA:\t\twlx  <PartitionName> <File>\r\n");
53154ee062SEddie Cai 	printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
54081d237aSliuyi 	printf("WriteParameter:\t\tprm <parameter>\r\n");
55081d237aSliuyi 	printf("PrintPartition:\t\tppt \r\n");
56154ee062SEddie Cai 	printf("EraseFlash:\t\tef \r\n");
57154ee062SEddie Cai 	printf("TestDevice:\t\ttd\r\n");
58154ee062SEddie Cai 	printf("ResetDevice:\t\trd [subcode]\r\n");
59154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
60154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
61154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
62081d237aSliuyi 	printf("ReadCapability:\t\trcb\r\n");
6378884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
6478884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
65d71e8c20SEddie Cai 	printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
6676af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6776af099aSliuyi }
6876af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6976af099aSliuyi {
7076af099aSliuyi 	string strInfoText="";
7176af099aSliuyi 	char szText[256];
7276af099aSliuyi 	switch (promptID) {
7376af099aSliuyi 	case TESTDEVICE_PROGRESS:
7432268622SAndreas Färber 		sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue);
7576af099aSliuyi 		strInfoText = szText;
7676af099aSliuyi 		break;
7776af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7832268622SAndreas Färber 		sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue);
7976af099aSliuyi 		strInfoText = szText;
8076af099aSliuyi 		break;
8176af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
8232268622SAndreas Färber 		sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8376af099aSliuyi 		strInfoText = szText;
8476af099aSliuyi 		break;
8576af099aSliuyi 	case CHECKIMAGE_PROGRESS:
8632268622SAndreas Färber 		sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8776af099aSliuyi 		strInfoText = szText;
8876af099aSliuyi 		break;
8976af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
9032268622SAndreas Färber 		sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue);
9176af099aSliuyi 		strInfoText = szText;
9276af099aSliuyi 		break;
9376af099aSliuyi 	case TESTBLOCK_PROGRESS:
9432268622SAndreas Färber 		sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue);
9576af099aSliuyi 		strInfoText = szText;
9676af099aSliuyi 		break;
9776af099aSliuyi 	case ERASEFLASH_PROGRESS:
9832268622SAndreas Färber 		sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue);
9976af099aSliuyi 		strInfoText = szText;
10076af099aSliuyi 		break;
10176af099aSliuyi 	case ERASESYSTEM_PROGRESS:
10232268622SAndreas Färber 		sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue);
10376af099aSliuyi 		strInfoText = szText;
10476af099aSliuyi 		break;
10576af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
10632268622SAndreas Färber 		sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue);
10776af099aSliuyi 		strInfoText = szText;
10876af099aSliuyi 		break;
10976af099aSliuyi 	}
11076af099aSliuyi 	if (strInfoText.size() > 0){
11176af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
11276af099aSliuyi 		CURSOR_DEL_LINE;
11376af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
11476af099aSliuyi 	}
11576af099aSliuyi 	if (emCall == CALL_LAST)
11676af099aSliuyi 		deviceLayer = 0;
11776af099aSliuyi }
11876af099aSliuyi 
11976af099aSliuyi char *strupr(char *szSrc)
12076af099aSliuyi {
12176af099aSliuyi 	char *p = szSrc;
12276af099aSliuyi 	while(*p){
12376af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
12476af099aSliuyi 			*p = *p - 'a' + 'A';
12576af099aSliuyi 		p++;
12676af099aSliuyi 	}
12776af099aSliuyi 	return szSrc;
12876af099aSliuyi }
12976af099aSliuyi void PrintData(PBYTE pData, int nSize)
13076af099aSliuyi {
13176af099aSliuyi 	char szPrint[17] = "\0";
13276af099aSliuyi 	int i;
13376af099aSliuyi 	for( i = 0; i < nSize; i++){
13476af099aSliuyi 		if(i % 16 == 0){
13576af099aSliuyi 			if(i / 16 > 0)
13676af099aSliuyi 				printf("     %s\r\n", szPrint);
13776af099aSliuyi 			printf("%08d ", i / 16);
13876af099aSliuyi 		}
13976af099aSliuyi 		printf("%02X ", pData[i]);
14076af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
14176af099aSliuyi 	}
14276af099aSliuyi 	if(i / 16 > 0)
14376af099aSliuyi 		printf("     %s\r\n", szPrint);
14476af099aSliuyi }
14576af099aSliuyi 
146c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName)
14776af099aSliuyi {
14876af099aSliuyi 	unsigned int i;
149c29e5f0fSliuyi 	for(i = 0; i < vecItems.size(); i++){
150c29e5f0fSliuyi 		if (strcasecmp(pszName, vecItems[i].szItemName) == 0){
15176af099aSliuyi 			return i;
15276af099aSliuyi 		}
15376af099aSliuyi 	}
15476af099aSliuyi 	return -1;
15576af099aSliuyi }
156c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid)
157c29e5f0fSliuyi {
158c29e5f0fSliuyi 	unsigned int i;
159c29e5f0fSliuyi 	char value;
160c29e5f0fSliuyi 	memset(uuid, 0, 16);
161c29e5f0fSliuyi 	for (i =0; i < strUUid.size(); i++) {
162c29e5f0fSliuyi 		value = 0;
163c29e5f0fSliuyi 		if ((strUUid[i] >= '0')&&(strUUid[i] <= '9'))
164c29e5f0fSliuyi 			value = strUUid[i] - '0';
165c29e5f0fSliuyi 		if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f'))
166c29e5f0fSliuyi 			value = strUUid[i] - 'a' + 10;
167c29e5f0fSliuyi 		if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F'))
168c29e5f0fSliuyi 			value = strUUid[i] - 'A' + 10;
169c29e5f0fSliuyi 		if ((i % 2) == 0)
170c29e5f0fSliuyi 			uuid[i / 2] += (value << 4);
171c29e5f0fSliuyi 		else
172c29e5f0fSliuyi 			uuid[i / 2] += value;
173c29e5f0fSliuyi 	}
174c29e5f0fSliuyi 	unsigned int *p32;
175c29e5f0fSliuyi 	unsigned short *p16;
176c29e5f0fSliuyi 	p32 = (unsigned int*)uuid;
177c29e5f0fSliuyi 	*p32 = cpu_to_be32(*p32);
178c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 4);
179c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
180c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 6);
181c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
182c29e5f0fSliuyi }
18376af099aSliuyi 
18476af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
18576af099aSliuyi {
18676af099aSliuyi 
18776af099aSliuyi 	stringstream configStream(pConfig);
18876af099aSliuyi 	string strLine, strItemName, strItemValue;
18976af099aSliuyi 	string::size_type line_size,pos;
19076af099aSliuyi 	STRUCT_CONFIG_ITEM item;
19176af099aSliuyi 	vecItem.clear();
19276af099aSliuyi 	while (!configStream.eof()){
19376af099aSliuyi 		getline(configStream, strLine);
19476af099aSliuyi 		line_size = strLine.size();
19576af099aSliuyi 		if (line_size == 0)
19676af099aSliuyi 			continue;
19776af099aSliuyi 		if (strLine[line_size-1] == '\r'){
19876af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
19976af099aSliuyi 		}
200c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
201c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
202c30d921cSKever Yang 		if (strLine.size()==0 )
203c30d921cSKever Yang 			continue;
204c30d921cSKever Yang 		if (strLine[0] == '#')
205c30d921cSKever Yang 			continue;
20676af099aSliuyi 		pos = strLine.find("=");
20776af099aSliuyi 		if (pos == string::npos){
20876af099aSliuyi 			continue;
20976af099aSliuyi 		}
21076af099aSliuyi 		strItemName = strLine.substr(0, pos);
21176af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
21276af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
21376af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
21476af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
21576af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
21676af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
21776af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
21876af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
21976af099aSliuyi 			vecItem.push_back(item);
22076af099aSliuyi 		}
22176af099aSliuyi 	}
22276af099aSliuyi 	return true;
22376af099aSliuyi 
22476af099aSliuyi }
22576af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
22676af099aSliuyi {
22776af099aSliuyi 	FILE *file = NULL;
22876af099aSliuyi 	file = fopen(pConfigFile, "rb");
22976af099aSliuyi 	if( !file ){
23076af099aSliuyi 		if (g_pLogObject)
23132268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile);
23276af099aSliuyi 		return false;
23376af099aSliuyi 	}
23476af099aSliuyi 	int iFileSize;
23576af099aSliuyi 	fseek(file, 0, SEEK_END);
23676af099aSliuyi 	iFileSize = ftell(file);
23776af099aSliuyi 	fseek(file, 0, SEEK_SET);
23876af099aSliuyi 	char *pConfigBuf = NULL;
23976af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
24076af099aSliuyi 	if (!pConfigBuf){
24176af099aSliuyi 		fclose(file);
24276af099aSliuyi 		return false;
24376af099aSliuyi 	}
24476af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
24576af099aSliuyi 	int iRead;
24676af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
24776af099aSliuyi 	if (iRead != iFileSize){
24876af099aSliuyi 		if (g_pLogObject)
24932268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize);
25076af099aSliuyi 		fclose(file);
25176af099aSliuyi 		delete []pConfigBuf;
25276af099aSliuyi 		return false;
25376af099aSliuyi 	}
25476af099aSliuyi 	fclose(file);
25576af099aSliuyi 	bool bRet;
25676af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
25776af099aSliuyi 	delete []pConfigBuf;
25876af099aSliuyi 	return bRet;
25976af099aSliuyi }
260c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
261c30d921cSKever Yang {
262c30d921cSKever Yang 	string::size_type pos,prevPos;
263c30d921cSKever Yang 	string strOffset,strLen;
264c30d921cSKever Yang 	int iCount;
265c30d921cSKever Yang 	prevPos = pos = 0;
266c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
267c30d921cSKever Yang 		return false;
268c30d921cSKever Yang 	}
269c30d921cSKever Yang 	pos = strPartInfo.find('@');
270c30d921cSKever Yang 	if (pos == string::npos) {
271c30d921cSKever Yang 		return false;
272c30d921cSKever Yang 	}
273c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
274c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
275c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
276c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
277c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
278c30d921cSKever Yang 	} else {
279c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
280c30d921cSKever Yang 		if (iCount != 1) {
281c30d921cSKever Yang 			return false;
282c30d921cSKever Yang 		}
283c30d921cSKever Yang 	}
284c30d921cSKever Yang 
285c30d921cSKever Yang 	prevPos = pos + 1;
286c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
287c30d921cSKever Yang 	if (pos == string::npos) {
288c30d921cSKever Yang 		return false;
289c30d921cSKever Yang 	}
290c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
291c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
292c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
293c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
294c30d921cSKever Yang 	if (iCount != 1) {
295c30d921cSKever Yang 		return false;
296c30d921cSKever Yang 	}
297c30d921cSKever Yang 	prevPos = pos + 1;
298c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
299c30d921cSKever Yang 	if (pos == string::npos) {
300c30d921cSKever Yang 		return false;
301c30d921cSKever Yang 	}
302c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
303c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
304c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
305c30d921cSKever Yang 
306c30d921cSKever Yang 	return true;
307c30d921cSKever Yang }
308c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid)
309c29e5f0fSliuyi {
310c29e5f0fSliuyi 	string::size_type pos(0);
311c30d921cSKever Yang 
312c29e5f0fSliuyi 	if (strUuidInfo.size() <= 0) {
313c29e5f0fSliuyi 		return false;
314c29e5f0fSliuyi 	}
315c29e5f0fSliuyi 	pos = strUuidInfo.find('=');
316c29e5f0fSliuyi 	if (pos == string::npos) {
317c29e5f0fSliuyi 		return false;
318c29e5f0fSliuyi 	}
319c29e5f0fSliuyi 	strName = strUuidInfo.substr(0, pos);
320c29e5f0fSliuyi 	strName.erase(0, strName.find_first_not_of(" "));
321c29e5f0fSliuyi 	strName.erase(strName.find_last_not_of(" ") + 1);
322c29e5f0fSliuyi 
323c29e5f0fSliuyi 	strUUid = strUuidInfo.substr(pos+1);
324c29e5f0fSliuyi 	strUUid.erase(0, strUUid.find_first_not_of(" "));
325c29e5f0fSliuyi 	strUUid.erase(strUUid.find_last_not_of(" ") + 1);
326c29e5f0fSliuyi 
327c29e5f0fSliuyi 	while(true) {
328c29e5f0fSliuyi 		pos = 0;
329c29e5f0fSliuyi 		if( (pos = strUUid.find("-")) != string::npos)
330c29e5f0fSliuyi 			strUUid.replace(pos,1,"");
331c29e5f0fSliuyi 		else
332c29e5f0fSliuyi 			break;
333c29e5f0fSliuyi 	}
334c29e5f0fSliuyi 	if (strUUid.size() != 32)
335c29e5f0fSliuyi 		return false;
336c29e5f0fSliuyi 	return true;
337c29e5f0fSliuyi }
338c29e5f0fSliuyi 
339c29e5f0fSliuyi 
340c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
341c30d921cSKever Yang {
342c30d921cSKever Yang 	stringstream paramStream(pParameter);
343c30d921cSKever Yang 	bool bRet,bFind = false;
344c29e5f0fSliuyi 	string strLine, strPartition, strPartInfo, strPartName, strUUid;
345c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
346c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
347c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
348c29e5f0fSliuyi 	STRUCT_CONFIG_ITEM uuid_item;
349c30d921cSKever Yang 	vecItem.clear();
350c29e5f0fSliuyi 	vecUuidItem.clear();
351c30d921cSKever Yang 	while (!paramStream.eof()) {
352c30d921cSKever Yang 		getline(paramStream,strLine);
353c30d921cSKever Yang 		line_size = strLine.size();
354c30d921cSKever Yang 		if (line_size == 0)
355c30d921cSKever Yang 			continue;
356c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
357c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
358c30d921cSKever Yang 		}
359c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
360c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
361c30d921cSKever Yang 		if (strLine.size()==0 )
362c30d921cSKever Yang 			continue;
363c30d921cSKever Yang 		if (strLine[0] == '#')
364c30d921cSKever Yang 			continue;
365c29e5f0fSliuyi 		pos = strLine.find("uuid:");
366c29e5f0fSliuyi 		if (pos != string::npos) {
367c29e5f0fSliuyi 			strPartInfo = strLine.substr(pos+5);
368c29e5f0fSliuyi 			bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid);
369c29e5f0fSliuyi 			if (bRet) {
370c29e5f0fSliuyi 				strcpy(uuid_item.szItemName, strPartName.c_str());
371c29e5f0fSliuyi 				string_to_uuid(strUUid,uuid_item.szItemValue);
372c29e5f0fSliuyi 				vecUuidItem.push_back(uuid_item);
373c29e5f0fSliuyi 			}
374c29e5f0fSliuyi 			continue;
375c29e5f0fSliuyi 		}
376c29e5f0fSliuyi 
377c30d921cSKever Yang 		pos = strLine.find("mtdparts");
378c30d921cSKever Yang 		if (pos == string::npos) {
379c30d921cSKever Yang 			continue;
380c30d921cSKever Yang 		}
381c30d921cSKever Yang 		bFind = true;
382c30d921cSKever Yang 		posColon = strLine.find(':', pos);
383c30d921cSKever Yang 		if (posColon == string::npos) {
384c30d921cSKever Yang 			continue;
385c30d921cSKever Yang 		}
386c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
387c30d921cSKever Yang 		pos = 0;
388c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
389c30d921cSKever Yang 		while (posComma != string::npos) {
390c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
391c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
392c30d921cSKever Yang 			if (bRet) {
393c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
394c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
395c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
396c30d921cSKever Yang 				vecItem.push_back(item);
397c30d921cSKever Yang 			}
398c30d921cSKever Yang 			pos = posComma + 1;
399c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
400c30d921cSKever Yang 		}
401c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
402c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
403c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
404c30d921cSKever Yang 			if (bRet) {
405c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
406c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
407c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
408c30d921cSKever Yang 				vecItem.push_back(item);
409c30d921cSKever Yang 			}
410c30d921cSKever Yang 		}
411c30d921cSKever Yang 	}
412c30d921cSKever Yang 	return bFind;
413c30d921cSKever Yang 
414c30d921cSKever Yang }
415c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
416c30d921cSKever Yang {
417c30d921cSKever Yang 	FILE *file = NULL;
418c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
419c30d921cSKever Yang 	if( !file ) {
420c30d921cSKever Yang 		if (g_pLogObject)
42132268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
422c30d921cSKever Yang 		return false;
423c30d921cSKever Yang 	}
424c30d921cSKever Yang 	int iFileSize;
425c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
426c30d921cSKever Yang 	iFileSize = ftell(file);
427c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
428c30d921cSKever Yang 	char *pParamBuf = NULL;
429c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
430c30d921cSKever Yang 	if (!pParamBuf) {
431c30d921cSKever Yang 		fclose(file);
432c30d921cSKever Yang 		return false;
433c30d921cSKever Yang 	}
434c30d921cSKever Yang 	int iRead;
435c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
436c30d921cSKever Yang 	if (iRead != iFileSize) {
437c30d921cSKever Yang 		if (g_pLogObject)
43832268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
439c30d921cSKever Yang 		fclose(file);
440c30d921cSKever Yang 		delete []pParamBuf;
441c30d921cSKever Yang 		return false;
442c30d921cSKever Yang 	}
443c30d921cSKever Yang 	fclose(file);
444c30d921cSKever Yang 	bool bRet;
445c29e5f0fSliuyi 	bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem);
446c30d921cSKever Yang 	delete []pParamBuf;
447c30d921cSKever Yang 	return bRet;
448c30d921cSKever Yang }
4496ae612beSliuyi bool is_sparse_image(char *szImage)
4506ae612beSliuyi {
4516ae612beSliuyi 	FILE *file = NULL;
4526ae612beSliuyi 	sparse_header head;
4536ae612beSliuyi 	u32 uiRead;
4546ae612beSliuyi 	file = fopen(szImage, "rb");
4556ae612beSliuyi 	if( !file ) {
4566ae612beSliuyi 		if (g_pLogObject)
4576ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
4586ae612beSliuyi 		return false;
4596ae612beSliuyi 	}
4606ae612beSliuyi 	uiRead = fread(&head, 1, sizeof(head), file);
4616ae612beSliuyi 	if (uiRead != sizeof(head)) {
4626ae612beSliuyi 		if (g_pLogObject)
4636ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head));
4646ae612beSliuyi 		fclose(file);
4656ae612beSliuyi 		return false;
4666ae612beSliuyi 	}
4676ae612beSliuyi 	fclose(file);
4686ae612beSliuyi 	if (head.magic!=SPARSE_HEADER_MAGIC)
4696ae612beSliuyi 	{
4706ae612beSliuyi 		return false;
4716ae612beSliuyi 	}
4726ae612beSliuyi 	return true;
4736ae612beSliuyi 
4746ae612beSliuyi }
4750dcb0a4cSliuyi bool is_ubifs_image(char *szImage)
4760dcb0a4cSliuyi {
4770dcb0a4cSliuyi 	FILE *file = NULL;
4780dcb0a4cSliuyi 	u32 magic;
4790dcb0a4cSliuyi 	u32 uiRead;
4800dcb0a4cSliuyi 	file = fopen(szImage, "rb");
4810dcb0a4cSliuyi 	if( !file ) {
4820dcb0a4cSliuyi 		if (g_pLogObject)
4830dcb0a4cSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
4840dcb0a4cSliuyi 		return false;
4850dcb0a4cSliuyi 	}
4860dcb0a4cSliuyi 	uiRead = fread(&magic, 1, sizeof(magic), file);
4870dcb0a4cSliuyi 	if (uiRead != sizeof(magic)) {
4880dcb0a4cSliuyi 		if (g_pLogObject)
4890dcb0a4cSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(magic));
4900dcb0a4cSliuyi 		fclose(file);
4910dcb0a4cSliuyi 		return false;
4920dcb0a4cSliuyi 	}
4930dcb0a4cSliuyi 	fclose(file);
4940dcb0a4cSliuyi 	if (magic!=UBI_HEADER_MAGIC)
4950dcb0a4cSliuyi 	{
4960dcb0a4cSliuyi 		return false;
4970dcb0a4cSliuyi 	}
4980dcb0a4cSliuyi 	return true;
4990dcb0a4cSliuyi }
500c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
501c30d921cSKever Yang {
502c30d921cSKever Yang 	efi_guid_t id;
503c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
504c30d921cSKever Yang 	unsigned int i;
505c30d921cSKever Yang 
506c30d921cSKever Yang 	/* Set all fields randomly */
507c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
508c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
509c30d921cSKever Yang 
510c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
511c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
512c30d921cSKever Yang 
513c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
514c30d921cSKever Yang }
515c30d921cSKever Yang 
516c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup)
517c29e5f0fSliuyi {
518c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
519c29e5f0fSliuyi 	gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
520c29e5f0fSliuyi 	u32 calc_crc32;
521c29e5f0fSliuyi 	u64 val;
522c29e5f0fSliuyi 
523c29e5f0fSliuyi 	/* recalculate the values for the Backup GPT Header */
524c29e5f0fSliuyi 	val = le64_to_cpu(gptMasterHead->my_lba);
525c29e5f0fSliuyi 	gptBackupHead->my_lba = gptMasterHead->alternate_lba;
526c29e5f0fSliuyi 	gptBackupHead->alternate_lba = cpu_to_le64(val);
527c29e5f0fSliuyi 	gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
528c29e5f0fSliuyi 	gptBackupHead->header_crc32 = 0;
529c29e5f0fSliuyi 
530c29e5f0fSliuyi 	calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
531c29e5f0fSliuyi 	gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
532c29e5f0fSliuyi }
5336ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end)
5346ae612beSliuyi {
5356ae612beSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
5366ae612beSliuyi 	gpt_entry  *gptEntry  = NULL;
5376ae612beSliuyi 	u32 i,j;
5386ae612beSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
5396ae612beSliuyi 	bool bFound = false;
5406ae612beSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
5416ae612beSliuyi 
5426ae612beSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
5436ae612beSliuyi 		gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
5446ae612beSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
5456ae612beSliuyi 			break;
5466ae612beSliuyi 		for (j = 0; j < strlen(pszName); j++)
5476ae612beSliuyi 			if (gptEntry->partition_name[j] != pszName[j])
5486ae612beSliuyi 				break;
5496ae612beSliuyi 		if (gptEntry->partition_name[j] != 0)
5506ae612beSliuyi 			continue;
5516ae612beSliuyi 		if (j == strlen(pszName)) {
5526ae612beSliuyi 			bFound = true;
5536ae612beSliuyi 			break;
5546ae612beSliuyi 		}
5556ae612beSliuyi 	}
5566ae612beSliuyi 	if (bFound) {
5576ae612beSliuyi 		*lba = le64_to_cpu(gptEntry->starting_lba);
558e541b7bbSliuyi 		if (gptMasterHead->last_usable_lba == gptEntry->ending_lba)
559e541b7bbSliuyi 			*lba_end = 0xFFFFFFFF;
560e541b7bbSliuyi 		else
5616ae612beSliuyi 			*lba_end =  le64_to_cpu(gptEntry->ending_lba);
5626ae612beSliuyi 		return true;
5636ae612beSliuyi 	}
5646ae612beSliuyi 	return false;
5656ae612beSliuyi }
566081d237aSliuyi bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size)
567081d237aSliuyi {
568081d237aSliuyi 	u32 i;
569081d237aSliuyi 	bool bFound = false, bRet;
570081d237aSliuyi 	PARAM_ITEM_VECTOR vecItem;
571081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
572081d237aSliuyi 
573081d237aSliuyi 	bRet = parse_parameter((char *)param, vecItem, vecUuid);
574081d237aSliuyi 	if (!bRet)
575081d237aSliuyi 		return false;
576081d237aSliuyi 
577081d237aSliuyi 	for (i = 0; i < vecItem.size(); i++) {
578081d237aSliuyi 		if (strcasecmp(pszName, vecItem[i].szItemName)==0) {
579081d237aSliuyi 			bFound = true;
580081d237aSliuyi 			break;
581081d237aSliuyi 		}
582081d237aSliuyi 	}
583081d237aSliuyi 	if (bFound) {
584081d237aSliuyi 		*part_offset = vecItem[i].uiItemOffset;
585081d237aSliuyi 		*part_size =  vecItem[i].uiItemSize;
586081d237aSliuyi 		return true;
587081d237aSliuyi 	}
588081d237aSliuyi 	return false;
589081d237aSliuyi }
590081d237aSliuyi 
591c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector)
592c29e5f0fSliuyi {
593c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
594c29e5f0fSliuyi 	gpt_entry  *gptLastPartEntry  = NULL;
595c29e5f0fSliuyi 	u32 i;
596c29e5f0fSliuyi 	u64 old_disksize;
597c29e5f0fSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
598c29e5f0fSliuyi 
599c29e5f0fSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
600c29e5f0fSliuyi 	old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1;
601c29e5f0fSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
602c29e5f0fSliuyi 		gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
603c29e5f0fSliuyi 		if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0)
604c29e5f0fSliuyi 			break;
605c29e5f0fSliuyi 	}
606c29e5f0fSliuyi 	i--;
607c29e5f0fSliuyi 	gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry));
608c29e5f0fSliuyi 
609c29e5f0fSliuyi 	gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1);
610c29e5f0fSliuyi 	gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34);
611c29e5f0fSliuyi 
612c29e5f0fSliuyi 	if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition
613c29e5f0fSliuyi 		gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34);
614c29e5f0fSliuyi 		gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
615c29e5f0fSliuyi 	}
616c29e5f0fSliuyi 	gptMasterHead->header_crc32 = 0;
617c29e5f0fSliuyi 	gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header)));
618c29e5f0fSliuyi 	memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS);
619c29e5f0fSliuyi 	memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE);
620c29e5f0fSliuyi 	prepare_gpt_backup(master, backup);
621c29e5f0fSliuyi 
622c29e5f0fSliuyi }
623c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup)
624c29e5f0fSliuyi {
625c29e5f0fSliuyi 	FILE *file = NULL;
626c29e5f0fSliuyi 	file = fopen(pParamFile, "rb");
627c29e5f0fSliuyi 	if( !file ) {
628c29e5f0fSliuyi 		if (g_pLogObject)
629c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
630c29e5f0fSliuyi 		return false;
631c29e5f0fSliuyi 	}
632c29e5f0fSliuyi 	int iFileSize;
633c29e5f0fSliuyi 	fseek(file, 0, SEEK_END);
634c29e5f0fSliuyi 	iFileSize = ftell(file);
635c29e5f0fSliuyi 	fseek(file, 0, SEEK_SET);
636c29e5f0fSliuyi 	if (iFileSize != 67 * SECTOR_SIZE) {
637c29e5f0fSliuyi 		if (g_pLogObject)
638c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile);
639c29e5f0fSliuyi 		fclose(file);
640c29e5f0fSliuyi 		return false;
641c29e5f0fSliuyi 	}
642c29e5f0fSliuyi 
643c29e5f0fSliuyi 	int iRead;
644c29e5f0fSliuyi 	iRead = fread(master, 1, 34 * SECTOR_SIZE, file);
645c29e5f0fSliuyi 	if (iRead != 34 * SECTOR_SIZE) {
646c29e5f0fSliuyi 		if (g_pLogObject)
647c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE);
648c29e5f0fSliuyi 		fclose(file);
649c29e5f0fSliuyi 		return false;
650c29e5f0fSliuyi 	}
651c29e5f0fSliuyi 	iRead = fread(backup, 1, 33 * SECTOR_SIZE, file);
652c29e5f0fSliuyi 	if (iRead != 33 * SECTOR_SIZE) {
653c29e5f0fSliuyi 		if (g_pLogObject)
654c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE);
655c29e5f0fSliuyi 		fclose(file);
656c29e5f0fSliuyi 		return false;
657c29e5f0fSliuyi 	}
658c29e5f0fSliuyi 	fclose(file);
659c29e5f0fSliuyi 	return true;
660c29e5f0fSliuyi }
661c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
662c30d921cSKever Yang {
663c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
664c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
665c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
666c30d921cSKever Yang 	u32 i,j;
667c29e5f0fSliuyi 	int pos;
668c30d921cSKever Yang 	string strPartName;
669c30d921cSKever Yang 	string::size_type colonPos;
670c30d921cSKever Yang 	/*1.protective mbr*/
671c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
672c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
673c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
674c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
675c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
676c30d921cSKever Yang 	/*2.gpt header*/
677c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
678c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
679c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
680c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
681c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
682c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
683c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
684c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
685c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
686c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
687c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
688c30d921cSKever Yang 	gptHead->header_crc32 = 0;
689c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
690c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
691c30d921cSKever Yang 
692c30d921cSKever Yang 	/*3.gpt partition entry*/
693c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
694c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
695c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
696c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
697c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
698c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
699c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
700c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
701c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
702c30d921cSKever Yang 		if (colonPos != string::npos) {
703c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
704c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
705c29e5f0fSliuyi 			if (strPartName.find("grow") != string::npos)
706c29e5f0fSliuyi 				gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
707c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
708c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
709c30d921cSKever Yang 		}
710c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
711c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
712c29e5f0fSliuyi 		if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1)
713c29e5f0fSliuyi 			memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
714c30d921cSKever Yang 		gptEntry++;
715c30d921cSKever Yang 	}
716c30d921cSKever Yang 
717c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
718c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
719c30d921cSKever Yang 
720c30d921cSKever Yang }
721b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
722c30d921cSKever Yang {
723c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
724c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
725c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
726c30d921cSKever Yang 
727c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
728b38fe5fcSliuyi 	pSec0->uiRc4Flag = rc4Flag;
729c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
730c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
731c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
732c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
733c30d921cSKever Yang 	return true;
734c30d921cSKever Yang }
735c30d921cSKever Yang 
736c30d921cSKever Yang 
737c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
738c30d921cSKever Yang {
739c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
740c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
741c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
742c30d921cSKever Yang 
743c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
744c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
745c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
746c30d921cSKever Yang 	return true;
747c30d921cSKever Yang }
748c30d921cSKever Yang 
749c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
750c30d921cSKever Yang {
751c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
752c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
753c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
754c30d921cSKever Yang 
755c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
756c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
757c30d921cSKever Yang 	return true;
758c30d921cSKever Yang }
759c30d921cSKever Yang 
760c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
761c30d921cSKever Yang {
762c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
763c30d921cSKever Yang 	return true;
764c30d921cSKever Yang }
765c30d921cSKever Yang 
766b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
767c30d921cSKever Yang {
768c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
769c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
770c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
771c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
772c30d921cSKever Yang 	UINT i;
773b38fe5fcSliuyi 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
774c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
775c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
776c30d921cSKever Yang 		return -6;
777c30d921cSKever Yang 	}
778c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
779c30d921cSKever Yang 		return -7;
780c30d921cSKever Yang 	}
781c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
782c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
783c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
784c30d921cSKever Yang 
785c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
786c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
787c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
788b38fe5fcSliuyi 
789b38fe5fcSliuyi 	if (rc4Flag) {
790b38fe5fcSliuyi 		for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
791b38fe5fcSliuyi 			P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
792b38fe5fcSliuyi 		for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
793b38fe5fcSliuyi 			P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
794b38fe5fcSliuyi 	}
795b38fe5fcSliuyi 
796c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
797c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
798c30d921cSKever Yang 
799c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
800c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
801c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
802c30d921cSKever Yang 		if(i == 1) {
803c30d921cSKever Yang 			continue;
804c30d921cSKever Yang 		} else {
805c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
806c30d921cSKever Yang 		}
807c30d921cSKever Yang 	}
808c30d921cSKever Yang 	return 0;
809c30d921cSKever Yang }
810c30d921cSKever Yang 
811c30d921cSKever Yang 
81276af099aSliuyi 
81376af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
81476af099aSliuyi {
81506ea143eSKlaus Goger 	if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType)
81676af099aSliuyi 		return true;
81776af099aSliuyi 	else
81876af099aSliuyi 	{
81976af099aSliuyi 		ERROR_COLOR_ATTR;
82032268622SAndreas Färber 		printf("The device does not support this operation!");
82176af099aSliuyi 		NORMAL_COLOR_ATTR;
82276af099aSliuyi 		printf("\r\n");
82376af099aSliuyi 		return false;
82476af099aSliuyi 	}
82576af099aSliuyi }
826081d237aSliuyi bool MakeParamBuffer(char *pParamFile, char* &pParamData)
827081d237aSliuyi {
828081d237aSliuyi 	FILE *file=NULL;
829081d237aSliuyi 	file = fopen(pParamFile, "rb");
830081d237aSliuyi 	if( !file )
831081d237aSliuyi 	{
832081d237aSliuyi 		if (g_pLogObject)
833081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile);
834081d237aSliuyi 		return false;
835081d237aSliuyi 	}
836081d237aSliuyi 	int iFileSize;
837081d237aSliuyi 	fseek(file,0,SEEK_END);
838081d237aSliuyi 	iFileSize = ftell(file);
839081d237aSliuyi 	fseek(file,0,SEEK_SET);
840081d237aSliuyi 	char *pParamBuf=NULL;
841081d237aSliuyi 	pParamBuf = new char[iFileSize + 12];
842081d237aSliuyi 	if (!pParamBuf)
843081d237aSliuyi 	{
844081d237aSliuyi 		fclose(file);
845081d237aSliuyi 		return false;
846081d237aSliuyi 	}
847081d237aSliuyi 	memset(pParamBuf,0,iFileSize+12);
848081d237aSliuyi 	*(UINT *)(pParamBuf) = 0x4D524150;
849081d237aSliuyi 
850081d237aSliuyi 	int iRead;
851081d237aSliuyi 	iRead = fread(pParamBuf+8,1,iFileSize,file);
852081d237aSliuyi 	if (iRead!=iFileSize)
853081d237aSliuyi 	{
854081d237aSliuyi 		if (g_pLogObject)
855081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize);
856081d237aSliuyi 		fclose(file);
857081d237aSliuyi 		delete []pParamBuf;
858081d237aSliuyi 		return false;
859081d237aSliuyi 	}
860081d237aSliuyi 	fclose(file);
861081d237aSliuyi 
862081d237aSliuyi 	*(UINT *)(pParamBuf+4) = iFileSize;
863081d237aSliuyi 	*(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize);
864081d237aSliuyi 	pParamData = pParamBuf;
865081d237aSliuyi 	return true;
866081d237aSliuyi }
867081d237aSliuyi 
868081d237aSliuyi bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
869081d237aSliuyi {
870081d237aSliuyi 	CRKComm *pComm = NULL;
871081d237aSliuyi 	char *pParamBuf = NULL, writeBuf[512*1024];
872081d237aSliuyi 	int iRet, nParamSec, nParamSize;
873081d237aSliuyi 	bool bRet, bSuccess = false;
874081d237aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER))
875081d237aSliuyi 		return false;
876081d237aSliuyi 
877081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
878081d237aSliuyi 	if (!bRet) {
879081d237aSliuyi 		ERROR_COLOR_ATTR;
880081d237aSliuyi 		printf("Creating Comm Object failed!");
881081d237aSliuyi 		NORMAL_COLOR_ATTR;
882081d237aSliuyi 		printf("\r\n");
883081d237aSliuyi 		return bSuccess;
884081d237aSliuyi 	}
885081d237aSliuyi 	if (!MakeParamBuffer(szParameter, pParamBuf)) {
886081d237aSliuyi 		ERROR_COLOR_ATTR;
887081d237aSliuyi 		printf("Generating parameter failed!");
888081d237aSliuyi 		NORMAL_COLOR_ATTR;
889081d237aSliuyi 		printf("\r\n");
890081d237aSliuyi 		return bSuccess;
891081d237aSliuyi 	}
892081d237aSliuyi 	printf("Writing parameter...\r\n");
893081d237aSliuyi 	nParamSize = *(UINT *)(pParamBuf+4) + 12;
894081d237aSliuyi 	nParamSec = BYTE2SECTOR(nParamSize);
895081d237aSliuyi 	if (nParamSec > 1024) {
896081d237aSliuyi 		ERROR_COLOR_ATTR;
897081d237aSliuyi 		printf("parameter is too large!");
898081d237aSliuyi 		NORMAL_COLOR_ATTR;
899081d237aSliuyi 		printf("\r\n");
900081d237aSliuyi 		return bSuccess;
901081d237aSliuyi 	}
902081d237aSliuyi 	memset(writeBuf, 0, nParamSec*512);
903081d237aSliuyi 	memcpy(writeBuf, pParamBuf, nParamSize);
904081d237aSliuyi 	iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf);
905081d237aSliuyi 	if (iRet != ERR_SUCCESS) {
906081d237aSliuyi 		ERROR_COLOR_ATTR;
907081d237aSliuyi 		printf("Writing parameter failed!");
908081d237aSliuyi 		NORMAL_COLOR_ATTR;
909081d237aSliuyi 		printf("\r\n");
910081d237aSliuyi 		return bSuccess;
911081d237aSliuyi 	}
912081d237aSliuyi 
913081d237aSliuyi 	bSuccess = true;
914081d237aSliuyi 	CURSOR_MOVEUP_LINE(1);
915081d237aSliuyi 	CURSOR_DEL_LINE;
916081d237aSliuyi 	printf("Writing parameter succeeded.\r\n");
917081d237aSliuyi 	return bSuccess;
918081d237aSliuyi }
919081d237aSliuyi 
920c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
921c30d921cSKever Yang {
922c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
923c30d921cSKever Yang 	u32 total_size_sector;
924c30d921cSKever Yang 	CRKComm *pComm = NULL;
925c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
926c29e5f0fSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
927c30d921cSKever Yang 	int iRet;
928c30d921cSKever Yang 	bool bRet, bSuccess = false;
929c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
930c30d921cSKever Yang 		return false;
931c30d921cSKever Yang 
932c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
933c30d921cSKever Yang 	if (!bRet) {
934c30d921cSKever Yang 		ERROR_COLOR_ATTR;
935c30d921cSKever Yang 		printf("Creating Comm Object failed!");
936c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
937c30d921cSKever Yang 		printf("\r\n");
938c30d921cSKever Yang 		return bSuccess;
939c30d921cSKever Yang 	}
94032268622SAndreas Färber 	printf("Writing gpt...\r\n");
941c30d921cSKever Yang 	//1.get flash info
942c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
943c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
944c30d921cSKever Yang 		ERROR_COLOR_ATTR;
945c30d921cSKever Yang 		printf("Reading Flash Info failed!");
946c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
947c30d921cSKever Yang 		printf("\r\n");
948c30d921cSKever Yang 		return bSuccess;
949c30d921cSKever Yang 	}
950c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
951c29e5f0fSliuyi 	if (strstr(szParameter, ".img")) {
952c29e5f0fSliuyi 		if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) {
953c29e5f0fSliuyi 			ERROR_COLOR_ATTR;
954c29e5f0fSliuyi 			printf("Loading partition image failed!");
955c29e5f0fSliuyi 			NORMAL_COLOR_ATTR;
956c29e5f0fSliuyi 			printf("\r\n");
957c29e5f0fSliuyi 			return bSuccess;
958c29e5f0fSliuyi 		}
959c29e5f0fSliuyi 		update_gpt_disksize(master_gpt, backup_gpt, total_size_sector);
960c29e5f0fSliuyi 	} else {
961c30d921cSKever Yang 		//2.get partition from parameter
962c29e5f0fSliuyi 		bRet = parse_parameter_file(szParameter, vecItems, vecUuid);
963c30d921cSKever Yang 		if (!bRet) {
964c30d921cSKever Yang 			ERROR_COLOR_ATTR;
965c30d921cSKever Yang 			printf("Parsing parameter failed!");
966c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
967c30d921cSKever Yang 			printf("\r\n");
968c30d921cSKever Yang 			return bSuccess;
969c30d921cSKever Yang 		}
970c30d921cSKever Yang 		//3.generate gpt info
971c29e5f0fSliuyi 		create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector);
972c30d921cSKever Yang 		memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
973c30d921cSKever Yang 		memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
974c29e5f0fSliuyi 		prepare_gpt_backup(master_gpt, backup_gpt);
975c29e5f0fSliuyi 	}
976c29e5f0fSliuyi 
977c30d921cSKever Yang 	//4. write gpt
978c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
979c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
980c30d921cSKever Yang 		ERROR_COLOR_ATTR;
981c30d921cSKever Yang 		printf("Writing master gpt failed!");
982c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
983c30d921cSKever Yang 		printf("\r\n");
984c30d921cSKever Yang 		return bSuccess;
985c30d921cSKever Yang 	}
986c29e5f0fSliuyi 	iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt);
987c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
988c30d921cSKever Yang 		ERROR_COLOR_ATTR;
989c30d921cSKever Yang 		printf("Writing backup gpt failed!");
990c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
991c30d921cSKever Yang 		printf("\r\n");
992c30d921cSKever Yang 		return bSuccess;
993c30d921cSKever Yang 	}
994c29e5f0fSliuyi 
995c30d921cSKever Yang 	bSuccess = true;
996c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
997c30d921cSKever Yang 	CURSOR_DEL_LINE;
99832268622SAndreas Färber 	printf("Writing gpt succeeded.\r\n");
999c30d921cSKever Yang 	return bSuccess;
1000c30d921cSKever Yang }
100176af099aSliuyi 
100278884ef4SEddie Cai #include "boot_merger.h"
100378884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
100478884ef4SEddie Cai options gOpts;
100578884ef4SEddie Cai 
100678884ef4SEddie Cai 
100778884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
100878884ef4SEddie Cai char* gConfigPath;
100978884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
101078884ef4SEddie Cai 
101178884ef4SEddie Cai static inline void fixPath(char* path) {
101278884ef4SEddie Cai 	int i, len = strlen(path);
101378884ef4SEddie Cai 	for(i=0; i<len; i++) {
101478884ef4SEddie Cai 		if (path[i] == '\\')
101578884ef4SEddie Cai 			path[i] = '/';
101678884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
101778884ef4SEddie Cai 			path[i] = '\0';
101878884ef4SEddie Cai 	}
101978884ef4SEddie Cai }
102078884ef4SEddie Cai 
102178884ef4SEddie Cai static bool parseChip(FILE* file) {
102278884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
102378884ef4SEddie Cai 		return false;
102478884ef4SEddie Cai 	}
102578884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
102678884ef4SEddie Cai 		return false;
102778884ef4SEddie Cai 	}
102878884ef4SEddie Cai 	printf("chip: %s\n", gOpts.chip);
102978884ef4SEddie Cai 	return true;
103078884ef4SEddie Cai }
103178884ef4SEddie Cai 
103278884ef4SEddie Cai static bool parseVersion(FILE* file) {
103378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
103478884ef4SEddie Cai 		return false;
103578884ef4SEddie Cai 	}
103678884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
103778884ef4SEddie Cai 		return false;
103878884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
103978884ef4SEddie Cai 		return false;
104078884ef4SEddie Cai 	}
104178884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
104278884ef4SEddie Cai 		return false;
104378884ef4SEddie Cai 	printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
104478884ef4SEddie Cai 	return true;
104578884ef4SEddie Cai }
104678884ef4SEddie Cai 
104778884ef4SEddie Cai static bool parse471(FILE* file) {
104878884ef4SEddie Cai 	int i, index, pos;
104978884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
105078884ef4SEddie Cai 
105178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
105278884ef4SEddie Cai 		return false;
105378884ef4SEddie Cai 	}
105478884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
105578884ef4SEddie Cai 		return false;
105678884ef4SEddie Cai 	printf("num: %d\n", gOpts.code471Num);
105778884ef4SEddie Cai 	if (!gOpts.code471Num)
105878884ef4SEddie Cai 		return true;
105978884ef4SEddie Cai 	if (gOpts.code471Num < 0)
106078884ef4SEddie Cai 		return false;
106178884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
106278884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
106378884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
106478884ef4SEddie Cai 			return false;
106578884ef4SEddie Cai 		}
106678884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
106778884ef4SEddie Cai 				!= 2)
106878884ef4SEddie Cai 			return false;
106978884ef4SEddie Cai 		index--;
107078884ef4SEddie Cai 		fixPath(buf);
107178884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
107278884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code471Path[index]);
107378884ef4SEddie Cai 	}
107478884ef4SEddie Cai 	pos = ftell(file);
107578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
107678884ef4SEddie Cai 		return false;
107778884ef4SEddie Cai 	}
107878884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
107978884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
108078884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code471Sleep);
108178884ef4SEddie Cai 	return true;
108278884ef4SEddie Cai }
108378884ef4SEddie Cai 
108478884ef4SEddie Cai static bool parse472(FILE* file) {
108578884ef4SEddie Cai 	int i, index, pos;
108678884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
108778884ef4SEddie Cai 
108878884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
108978884ef4SEddie Cai 		return false;
109078884ef4SEddie Cai 	}
109178884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
109278884ef4SEddie Cai 		return false;
109378884ef4SEddie Cai 	printf("num: %d\n", gOpts.code472Num);
109478884ef4SEddie Cai 	if (!gOpts.code472Num)
109578884ef4SEddie Cai 		return true;
109678884ef4SEddie Cai 	if (gOpts.code472Num < 0)
109778884ef4SEddie Cai 		return false;
109878884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
109978884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
110078884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
110178884ef4SEddie Cai 			return false;
110278884ef4SEddie Cai 		}
110378884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
110478884ef4SEddie Cai 				!= 2)
110578884ef4SEddie Cai 			return false;
110678884ef4SEddie Cai 		fixPath(buf);
110778884ef4SEddie Cai 		index--;
110878884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
110978884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code472Path[index]);
111078884ef4SEddie Cai 	}
111178884ef4SEddie Cai 	pos = ftell(file);
111278884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
111378884ef4SEddie Cai 		return false;
111478884ef4SEddie Cai 	}
111578884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
111678884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
111778884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code472Sleep);
111878884ef4SEddie Cai 	return true;
111978884ef4SEddie Cai }
112078884ef4SEddie Cai 
112178884ef4SEddie Cai static bool parseLoader(FILE* file) {
112278884ef4SEddie Cai 	int i, j, index, pos;
112378884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
112478884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
112578884ef4SEddie Cai 
112678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
112778884ef4SEddie Cai 		return false;
112878884ef4SEddie Cai 	}
112978884ef4SEddie Cai 	pos = ftell(file);
113078884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
113178884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
113278884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
113378884ef4SEddie Cai 			return false;
113478884ef4SEddie Cai 		}
113578884ef4SEddie Cai 	}
113678884ef4SEddie Cai 	printf("num: %d\n", gOpts.loaderNum);
113778884ef4SEddie Cai 	if (!gOpts.loaderNum)
113878884ef4SEddie Cai 		return false;
113978884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
114078884ef4SEddie Cai 		return false;
114178884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
114278884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
114378884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
114478884ef4SEddie Cai 			return false;
114578884ef4SEddie Cai 		}
114678884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
114778884ef4SEddie Cai 				!= 2)
114878884ef4SEddie Cai 			return false;
114978884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
115078884ef4SEddie Cai 		printf("name%d: %s\n", index, gOpts.loader[index].name);
1151544ec1d4SKlaus Goger 		index++;
115278884ef4SEddie Cai 	}
115378884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
115478884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
115578884ef4SEddie Cai 			return false;
115678884ef4SEddie Cai 		}
115778884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
115878884ef4SEddie Cai 				!= 2)
115978884ef4SEddie Cai 			return false;
116078884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
116178884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
116278884ef4SEddie Cai 				fixPath(buf2);
116378884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
116478884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
116578884ef4SEddie Cai 				break;
116678884ef4SEddie Cai 			}
116778884ef4SEddie Cai 		}
116878884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
116978884ef4SEddie Cai 			return false;
117078884ef4SEddie Cai 		}
117178884ef4SEddie Cai 	}
117278884ef4SEddie Cai 	return true;
117378884ef4SEddie Cai }
117478884ef4SEddie Cai 
117578884ef4SEddie Cai static bool parseOut(FILE* file) {
117678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
117778884ef4SEddie Cai 		return false;
117878884ef4SEddie Cai 	}
117978884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
118078884ef4SEddie Cai 		return false;
118178884ef4SEddie Cai 	fixPath(gOpts.outPath);
118278884ef4SEddie Cai 	printf("out: %s\n", gOpts.outPath);
118378884ef4SEddie Cai 	return true;
118478884ef4SEddie Cai }
118578884ef4SEddie Cai 
118678884ef4SEddie Cai 
118778884ef4SEddie Cai void printOpts(FILE* out) {
118878884ef4SEddie Cai 	int i;
118978884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
119078884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
119178884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
119278884ef4SEddie Cai 
119378884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
119478884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
119578884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
119678884ef4SEddie Cai 	}
119778884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
119878884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
119978884ef4SEddie Cai 
120078884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
120178884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
120278884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
120378884ef4SEddie Cai 	}
120478884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
120578884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
120678884ef4SEddie Cai 
120778884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
120878884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
120978884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
121078884ef4SEddie Cai 	}
121178884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
121278884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
121378884ef4SEddie Cai 	}
121478884ef4SEddie Cai 
121578884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
121678884ef4SEddie Cai }
121778884ef4SEddie Cai 
121878884ef4SEddie Cai static bool parseOpts(void) {
121978884ef4SEddie Cai 	bool ret = false;
122078884ef4SEddie Cai 	bool chipOk = false;
122178884ef4SEddie Cai 	bool versionOk = false;
122278884ef4SEddie Cai 	bool code471Ok = true;
122378884ef4SEddie Cai 	bool code472Ok = true;
122478884ef4SEddie Cai 	bool loaderOk = false;
122578884ef4SEddie Cai 	bool outOk = false;
122678884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
122778884ef4SEddie Cai 
122878884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
122978884ef4SEddie Cai 	FILE* file;
123078884ef4SEddie Cai 	file = fopen(configPath, "r");
123178884ef4SEddie Cai 	if (!file) {
123278884ef4SEddie Cai 		fprintf(stderr, "config (%s) not found!\n", configPath);
123308c0d218SKlaus Goger 		if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) {
123478884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
123578884ef4SEddie Cai 			if (file) {
123632268622SAndreas Färber 				fprintf(stderr, "creating defconfig\n");
123778884ef4SEddie Cai 				printOpts(file);
123878884ef4SEddie Cai 			}
123978884ef4SEddie Cai 		}
124078884ef4SEddie Cai 		goto end;
124178884ef4SEddie Cai 	}
124278884ef4SEddie Cai 
124332268622SAndreas Färber 	printf("Starting to parse...\n");
124478884ef4SEddie Cai 
124578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
124678884ef4SEddie Cai 		goto end;
124778884ef4SEddie Cai 	}
124878884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
124978884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
125078884ef4SEddie Cai 			chipOk = parseChip(file);
125178884ef4SEddie Cai 			if (!chipOk) {
125278884ef4SEddie Cai 				printf("parseChip failed!\n");
125378884ef4SEddie Cai 				goto end;
125478884ef4SEddie Cai 			}
125578884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
125678884ef4SEddie Cai 			versionOk = parseVersion(file);
125778884ef4SEddie Cai 			if (!versionOk) {
125878884ef4SEddie Cai 				printf("parseVersion failed!\n");
125978884ef4SEddie Cai 				goto end;
126078884ef4SEddie Cai 			}
126178884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
126278884ef4SEddie Cai 			code471Ok = parse471(file);
126378884ef4SEddie Cai 			if (!code471Ok) {
126478884ef4SEddie Cai 				printf("parse471 failed!\n");
126578884ef4SEddie Cai 				goto end;
126678884ef4SEddie Cai 			}
126778884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
126878884ef4SEddie Cai 			code472Ok = parse472(file);
126978884ef4SEddie Cai 			if (!code472Ok) {
127078884ef4SEddie Cai 				printf("parse472 failed!\n");
127178884ef4SEddie Cai 				goto end;
127278884ef4SEddie Cai 			}
127378884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
127478884ef4SEddie Cai 			loaderOk = parseLoader(file);
127578884ef4SEddie Cai 			if (!loaderOk) {
127678884ef4SEddie Cai 				printf("parseLoader failed!\n");
127778884ef4SEddie Cai 				goto end;
127878884ef4SEddie Cai 			}
127978884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
128078884ef4SEddie Cai 			outOk = parseOut(file);
128178884ef4SEddie Cai 			if (!outOk) {
128278884ef4SEddie Cai 				printf("parseOut failed!\n");
128378884ef4SEddie Cai 				goto end;
128478884ef4SEddie Cai 			}
128578884ef4SEddie Cai 		} else if (buf[0] == '#') {
128678884ef4SEddie Cai 			continue;
128778884ef4SEddie Cai 		} else {
128878884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
128978884ef4SEddie Cai 			goto end;
129078884ef4SEddie Cai 		}
129178884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
129278884ef4SEddie Cai 			goto end;
129378884ef4SEddie Cai 		}
129478884ef4SEddie Cai 	}
129578884ef4SEddie Cai 
129678884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
129778884ef4SEddie Cai 			&& loaderOk && outOk)
129878884ef4SEddie Cai 		ret = true;
129978884ef4SEddie Cai end:
130078884ef4SEddie Cai 	if (file)
130178884ef4SEddie Cai 		fclose(file);
130278884ef4SEddie Cai 	return ret;
130378884ef4SEddie Cai }
130478884ef4SEddie Cai 
130578884ef4SEddie Cai bool initOpts(void) {
130678884ef4SEddie Cai 	//set default opts
130778884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
130878884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
130978884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
131078884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
131178884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
131278884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
131378884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
131478884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
131578884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
131678884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
131778884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
131878884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
131978884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
132078884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
132178884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
132278884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
132378884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
132478884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
132578884ef4SEddie Cai 
132678884ef4SEddie Cai 	return parseOpts();
132778884ef4SEddie Cai }
132878884ef4SEddie Cai 
132978884ef4SEddie Cai /************merge code****************/
133078884ef4SEddie Cai 
133178884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
133278884ef4SEddie Cai 	uint8_t tmp[2] = {0};
133378884ef4SEddie Cai 	int i;
133478884ef4SEddie Cai 	uint32_t ret;
133578884ef4SEddie Cai 	//if (value > 0xFFFF) {
133678884ef4SEddie Cai 	//	return 0;
133778884ef4SEddie Cai 	//}
133878884ef4SEddie Cai 	for(i=0; i < 2; i++) {
133978884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
134078884ef4SEddie Cai 		value /= 100;
134178884ef4SEddie Cai 	}
134278884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
134378884ef4SEddie Cai 
134478884ef4SEddie Cai 	printf("ret: %x\n",ret);
134578884ef4SEddie Cai 	return ret&0xFF;
134678884ef4SEddie Cai }
134778884ef4SEddie Cai 
134878884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
134978884ef4SEddie Cai {
135078884ef4SEddie Cai 	int i;
135178884ef4SEddie Cai 	for (i = 0; i < len; i++) {
135278884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
135378884ef4SEddie Cai 	}
135478884ef4SEddie Cai 	wide[len] = 0;
135578884ef4SEddie Cai }
135678884ef4SEddie Cai 
135778884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
135878884ef4SEddie Cai 	char* end;
135978884ef4SEddie Cai 	char* start;
136078884ef4SEddie Cai 	int len;
136178884ef4SEddie Cai 	if (!path || !dst)
136278884ef4SEddie Cai 		return;
136378884ef4SEddie Cai 	start = strrchr(path, '/');
136478884ef4SEddie Cai 	if (!start)
136578884ef4SEddie Cai 		start = path;
136678884ef4SEddie Cai 	else
136778884ef4SEddie Cai 		start++;
136878884ef4SEddie Cai 	end = strrchr(path, '.');
1369641cfa16SEddie Cai 	if (!end || (end < start))
137078884ef4SEddie Cai 		end = path + strlen(path);
137178884ef4SEddie Cai 	len = end - start;
137278884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
137378884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
137478884ef4SEddie Cai 	str2wide(start, dst, len);
137578884ef4SEddie Cai 
137678884ef4SEddie Cai 
137778884ef4SEddie Cai 		char name[MAX_NAME_LEN];
137878884ef4SEddie Cai 		memset(name, 0, sizeof(name));
137978884ef4SEddie Cai 		memcpy(name, start, len);
138078884ef4SEddie Cai 		printf("path: %s, name: %s\n", path, name);
138178884ef4SEddie Cai 
138278884ef4SEddie Cai }
138378884ef4SEddie Cai 
138478884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
138578884ef4SEddie Cai 	struct stat st;
138678884ef4SEddie Cai 	if(stat(path, &st) < 0)
138778884ef4SEddie Cai 		return false;
138878884ef4SEddie Cai 	*size = st.st_size;
138978884ef4SEddie Cai 	printf("path: %s, size: %d\n", path, *size);
139078884ef4SEddie Cai 	return true;
139178884ef4SEddie Cai }
139278884ef4SEddie Cai 
139378884ef4SEddie Cai static inline rk_time getTime(void) {
139478884ef4SEddie Cai 	rk_time rkTime;
139578884ef4SEddie Cai 
139678884ef4SEddie Cai 	struct tm *tm;
139778884ef4SEddie Cai 	time_t tt = time(NULL);
139878884ef4SEddie Cai 	tm = localtime(&tt);
139978884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
140078884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
140178884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
140278884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
140378884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
140478884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
140578884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
140678884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
140778884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
140878884ef4SEddie Cai 	return rkTime;
140978884ef4SEddie Cai }
141078884ef4SEddie Cai 
141178884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
141278884ef4SEddie Cai 	bool ret = false;
141378884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
141478884ef4SEddie Cai 	uint8_t* buf;
141578884ef4SEddie Cai 
141678884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
141778884ef4SEddie Cai 	if (!inFile)
141878884ef4SEddie Cai 		goto end;
141978884ef4SEddie Cai 
142078884ef4SEddie Cai 	if (!getFileSize(path, &size))
142178884ef4SEddie Cai 		goto end;
142278884ef4SEddie Cai 	if (fix) {
142378884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
142478884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
142578884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
142678884ef4SEddie Cai 		fixSize +=tmp;
142778884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
142878884ef4SEddie Cai 	} else {
142978884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
143078884ef4SEddie Cai 	}
143178884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
143278884ef4SEddie Cai 		goto end;
143378884ef4SEddie Cai 
143478884ef4SEddie Cai 	if (fix) {
143578884ef4SEddie Cai 
143678884ef4SEddie Cai 		buf = gBuf;
143778884ef4SEddie Cai 		size = fixSize;
143878884ef4SEddie Cai 		while(1) {
143978884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
144078884ef4SEddie Cai 			buf += SMALL_PACKET;
144178884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
144278884ef4SEddie Cai 				break;
144378884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
144478884ef4SEddie Cai 		}
144578884ef4SEddie Cai 	} else {
144678884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
144778884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
144878884ef4SEddie Cai 		size +=tmp;
144978884ef4SEddie Cai 		P_RC4(gBuf, size);
145078884ef4SEddie Cai 	}
145178884ef4SEddie Cai 
145278884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
145378884ef4SEddie Cai 		goto end;
145478884ef4SEddie Cai 	ret = true;
145578884ef4SEddie Cai end:
145678884ef4SEddie Cai 	if (inFile)
145778884ef4SEddie Cai 		fclose(inFile);
145878884ef4SEddie Cai 	if (!ret)
145932268622SAndreas Färber 		printf("writing entry (%s) failed\n", path);
146078884ef4SEddie Cai 	return ret;
146178884ef4SEddie Cai }
146278884ef4SEddie Cai 
146378884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
146478884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
146578884ef4SEddie Cai 	uint32_t size;
146678884ef4SEddie Cai 	rk_boot_entry entry;
146778884ef4SEddie Cai 
146832268622SAndreas Färber 	printf("writing: %s\n", path);
1469641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
147078884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
147178884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
147278884ef4SEddie Cai 	entry.type = type;
147378884ef4SEddie Cai 	entry.dataOffset = *offset;
147478884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
147532268622SAndreas Färber 		printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
147678884ef4SEddie Cai 		return false;
147778884ef4SEddie Cai 	}
147878884ef4SEddie Cai 	if (fix)
147978884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
148078884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
148178884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
148232268622SAndreas Färber 	printf("alignment size: %d\n", size);
148378884ef4SEddie Cai 	entry.dataSize = size;
148478884ef4SEddie Cai 	entry.dataDelay = delay;
148578884ef4SEddie Cai 	*offset += size;
148678884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
148778884ef4SEddie Cai 	return true;
148878884ef4SEddie Cai }
148978884ef4SEddie Cai 
149078884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
149178884ef4SEddie Cai 	char buffer[5];
149278884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
149378884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
149478884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
149578884ef4SEddie Cai }
149678884ef4SEddie Cai 
149778884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
149878884ef4SEddie Cai 	printf("chip: %s\n", chip);
149978884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
150078884ef4SEddie Cai 	if(!chip) {
150178884ef4SEddie Cai 		goto end;
150278884ef4SEddie Cai 	}
150378884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
150478884ef4SEddie Cai 		chipType = RK28_DEVICE;
150578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
150678884ef4SEddie Cai 		chipType = RK28_DEVICE;
150778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
150878884ef4SEddie Cai 		chipType = RK281X_DEVICE;
150978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
151078884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
151178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
151278884ef4SEddie Cai 		chipType = RK27_DEVICE;
151378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
151478884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
151578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
151678884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
151778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
151878884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
151978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
152078884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
152178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
152278884ef4SEddie Cai 		chipType = RK29_DEVICE;
152378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
152478884ef4SEddie Cai 		chipType = RK292X_DEVICE;
152578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
152678884ef4SEddie Cai 		chipType = RK30_DEVICE;
152778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
152878884ef4SEddie Cai 		chipType = RK30B_DEVICE;
152978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
153078884ef4SEddie Cai 		chipType = RK31_DEVICE;
153178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
153278884ef4SEddie Cai 		chipType = RK32_DEVICE;
153378884ef4SEddie Cai 	} else {
153478884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
153578884ef4SEddie Cai 	}
153678884ef4SEddie Cai 
153778884ef4SEddie Cai end:
153878884ef4SEddie Cai 	printf("type: 0x%x\n", chipType);
153978884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
154032268622SAndreas Färber 		printf("chip type not supported!\n");
154178884ef4SEddie Cai 	}
154278884ef4SEddie Cai 	return chipType;
154378884ef4SEddie Cai }
154478884ef4SEddie Cai 
154578884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
154678884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
154778884ef4SEddie Cai 	hdr->tag = TAG;
154878884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
154978884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
155078884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
155178884ef4SEddie Cai 	hdr->releaseTime = getTime();
155278884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
155378884ef4SEddie Cai 
155478884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
155578884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
155678884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
155778884ef4SEddie Cai 
155878884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
155978884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
156078884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
156178884ef4SEddie Cai 
156278884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
156378884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
156478884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
156578884ef4SEddie Cai #ifndef USE_P_RC4
156678884ef4SEddie Cai 	hdr->rc4Flag = 1;
156778884ef4SEddie Cai #endif
156878884ef4SEddie Cai }
156978884ef4SEddie Cai 
157078884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
157178884ef4SEddie Cai 	uint32_t size = 0;
157278884ef4SEddie Cai 	uint32_t crc = 0;
157378884ef4SEddie Cai 
157478884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
157578884ef4SEddie Cai 	getFileSize(path, &size);
157678884ef4SEddie Cai 	if (!file)
157778884ef4SEddie Cai 		goto end;
157878884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
157978884ef4SEddie Cai 		goto end;
158078884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
158178884ef4SEddie Cai 	printf("crc: 0x%08x\n", crc);
158278884ef4SEddie Cai end:
158378884ef4SEddie Cai 	if (file)
158478884ef4SEddie Cai 		fclose(file);
158578884ef4SEddie Cai 	return crc;
158678884ef4SEddie Cai }
158778884ef4SEddie Cai 
158878884ef4SEddie Cai bool mergeBoot(void) {
158978884ef4SEddie Cai 	uint32_t dataOffset;
159078884ef4SEddie Cai 	bool ret = false;
159178884ef4SEddie Cai 	int i;
159278884ef4SEddie Cai 	FILE* outFile;
159378884ef4SEddie Cai 	uint32_t crc;
159478884ef4SEddie Cai 	rk_boot_header hdr;
159578884ef4SEddie Cai 
159678884ef4SEddie Cai 	if (!initOpts())
159778884ef4SEddie Cai 		return false;
159878884ef4SEddie Cai 	{
159978884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
160078884ef4SEddie Cai 		char version[MAX_LINE_LEN];
160178884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
160278884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
160378884ef4SEddie Cai 			subfix[0] = '\0';
160478884ef4SEddie Cai 		}
160578884ef4SEddie Cai 		strcat(gOpts.outPath, version);
160678884ef4SEddie Cai 		printf("fix opt: %s\n", gOpts.outPath);
160778884ef4SEddie Cai 	}
160878884ef4SEddie Cai 
160978884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
161078884ef4SEddie Cai 	printOpts(stdout);
161178884ef4SEddie Cai 	printf("---------------\n\n");
161278884ef4SEddie Cai 
161378884ef4SEddie Cai 
161478884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
161578884ef4SEddie Cai 	if (!outFile) {
161632268622SAndreas Färber 		printf("Opening output file (%s) failed\n", gOpts.outPath);
161778884ef4SEddie Cai 		goto end;
161878884ef4SEddie Cai 	}
161978884ef4SEddie Cai 
162078884ef4SEddie Cai 	getBoothdr(&hdr);
162132268622SAndreas Färber 	printf("Writing header...\n");
162278884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
162378884ef4SEddie Cai 
162478884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
162578884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
162678884ef4SEddie Cai 		sizeof(rk_boot_entry);
162778884ef4SEddie Cai 
162832268622SAndreas Färber 	printf("Writing code 471 entry...\n");
162978884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
163078884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
163178884ef4SEddie Cai 					&dataOffset, NULL, false))
163278884ef4SEddie Cai 			goto end;
163378884ef4SEddie Cai 	}
163432268622SAndreas Färber 	printf("Writing code 472 entry...\n");
163578884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
163678884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
163778884ef4SEddie Cai 					&dataOffset, NULL, false))
163878884ef4SEddie Cai 			goto end;
163978884ef4SEddie Cai 	}
164032268622SAndreas Färber 	printf("Writing loader entry...\n");
164178884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
164278884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
164378884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
164478884ef4SEddie Cai 			goto end;
164578884ef4SEddie Cai 	}
164678884ef4SEddie Cai 
164732268622SAndreas Färber 	printf("Writing code 471...\n");
164878884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
164978884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
165078884ef4SEddie Cai 			goto end;
165178884ef4SEddie Cai 	}
165232268622SAndreas Färber 	printf("Writing code 472...\n");
165378884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
165478884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
165578884ef4SEddie Cai 			goto end;
165678884ef4SEddie Cai 	}
165732268622SAndreas Färber 	printf("Writing loader...\n");
165878884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
165978884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
166078884ef4SEddie Cai 			goto end;
166178884ef4SEddie Cai 	}
166278884ef4SEddie Cai 	fflush(outFile);
166378884ef4SEddie Cai 
166432268622SAndreas Färber 	printf("Writing crc...\n");
166578884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
166678884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
166778884ef4SEddie Cai 		goto end;
166832268622SAndreas Färber 	printf("Done.\n");
166978884ef4SEddie Cai 	ret = true;
167078884ef4SEddie Cai end:
167178884ef4SEddie Cai 	if (outFile)
167278884ef4SEddie Cai 		fclose(outFile);
167378884ef4SEddie Cai 	return ret;
167478884ef4SEddie Cai }
167578884ef4SEddie Cai 
167678884ef4SEddie Cai /************merge code end************/
167778884ef4SEddie Cai /************unpack code***************/
167878884ef4SEddie Cai 
167978884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
168078884ef4SEddie Cai {
168178884ef4SEddie Cai 	int i;
168278884ef4SEddie Cai 	for (i = 0; i < len; i++) {
168378884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
168478884ef4SEddie Cai 	}
168578884ef4SEddie Cai }
168678884ef4SEddie Cai 
168778884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
168878884ef4SEddie Cai 		FILE* inFile) {
168978884ef4SEddie Cai 	bool ret = false;
169078884ef4SEddie Cai 	int size, i;
169178884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
169278884ef4SEddie Cai 	if (!outFile)
169378884ef4SEddie Cai 		goto end;
169432268622SAndreas Färber 	printf("unpacking entry (%s)\n", name);
169578884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
169678884ef4SEddie Cai 	size = entry->dataSize;
169778884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
169878884ef4SEddie Cai 		goto end;
169978884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
170078884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
170178884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
170278884ef4SEddie Cai 		if (size % SMALL_PACKET)
170378884ef4SEddie Cai 		{
170478884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
170578884ef4SEddie Cai 		}
170678884ef4SEddie Cai 	} else {
170778884ef4SEddie Cai 		P_RC4(gBuf, size);
170878884ef4SEddie Cai 	}
170978884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
171078884ef4SEddie Cai 		goto end;
171178884ef4SEddie Cai 	ret = true;
171278884ef4SEddie Cai end:
171378884ef4SEddie Cai 	if (outFile)
171478884ef4SEddie Cai 		fclose(outFile);
171578884ef4SEddie Cai 	return ret;
171678884ef4SEddie Cai }
171778884ef4SEddie Cai 
171878884ef4SEddie Cai bool unpackBoot(char* path) {
171978884ef4SEddie Cai 	bool ret = false;
172078884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
172178884ef4SEddie Cai 	int entryNum, i;
172278884ef4SEddie Cai 	char name[MAX_NAME_LEN];
172378884ef4SEddie Cai 	rk_boot_entry* entrys;
172478884ef4SEddie Cai 	if (!inFile) {
172578884ef4SEddie Cai 		fprintf(stderr, "loader (%s) not found\n", path);
172678884ef4SEddie Cai 		goto end;
172778884ef4SEddie Cai 	}
172878884ef4SEddie Cai 
172978884ef4SEddie Cai 	rk_boot_header hdr;
173078884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
173132268622SAndreas Färber 		fprintf(stderr, "reading header failed\n");
173278884ef4SEddie Cai 		goto end;
173378884ef4SEddie Cai 	}
173478884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
173578884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
173678884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
173778884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
173832268622SAndreas Färber 		fprintf(stderr, "reading data failed\n");
173978884ef4SEddie Cai 		goto end;
174078884ef4SEddie Cai 	}
174178884ef4SEddie Cai 
174278884ef4SEddie Cai 	printf("entry num: %d\n", entryNum);
174378884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
174478884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
174578884ef4SEddie Cai 
174678884ef4SEddie Cai 		printf("entry: t=%d, name=%s, off=%d, size=%d\n",
174778884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
174878884ef4SEddie Cai 				entrys[i].dataSize);
174978884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
175032268622SAndreas Färber 			fprintf(stderr, "unpacking entry (%s) failed\n", name);
175178884ef4SEddie Cai 			goto end;
175278884ef4SEddie Cai 		}
175378884ef4SEddie Cai 	}
175478884ef4SEddie Cai 	printf("done\n");
175578884ef4SEddie Cai 	ret = true;
175678884ef4SEddie Cai end:
175778884ef4SEddie Cai 	if (inFile)
175878884ef4SEddie Cai 		fclose(inFile);
175978884ef4SEddie Cai 	return ret;
176078884ef4SEddie Cai }
176178884ef4SEddie Cai 
176276af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
176376af099aSliuyi {
176476af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
176576af099aSliuyi 		return false;
176676af099aSliuyi 	CRKImage *pImage = NULL;
176776af099aSliuyi 	CRKBoot *pBoot = NULL;
176876af099aSliuyi 	bool bRet, bSuccess = false;
176976af099aSliuyi 	int iRet;
177076af099aSliuyi 
177176af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
177276af099aSliuyi 	if (!bRet){
177376af099aSliuyi 		ERROR_COLOR_ATTR;
177432268622SAndreas Färber 		printf("Opening loader failed, exiting download boot!");
177576af099aSliuyi 		NORMAL_COLOR_ATTR;
177676af099aSliuyi 		printf("\r\n");
177776af099aSliuyi 		return bSuccess;
177876af099aSliuyi 	} else {
177976af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
178076af099aSliuyi 		CRKComm *pComm = NULL;
178176af099aSliuyi 		CRKDevice *pDevice = NULL;
178276af099aSliuyi 
178376af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
178476af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
178576af099aSliuyi 		if (!bRet) {
178676af099aSliuyi 			if (pImage)
178776af099aSliuyi 				delete pImage;
178876af099aSliuyi 			ERROR_COLOR_ATTR;
178976af099aSliuyi 			printf("Creating Comm Object failed!");
179076af099aSliuyi 			NORMAL_COLOR_ATTR;
179176af099aSliuyi 			printf("\r\n");
179276af099aSliuyi 			return bSuccess;
179376af099aSliuyi 		}
179476af099aSliuyi 
179576af099aSliuyi 		pDevice = new CRKDevice(dev);
179676af099aSliuyi 		if (!pDevice) {
179776af099aSliuyi 			if (pImage)
179876af099aSliuyi 				delete pImage;
179976af099aSliuyi 			if (pComm)
180076af099aSliuyi 				delete pComm;
180176af099aSliuyi 			ERROR_COLOR_ATTR;
180276af099aSliuyi 			printf("Creating device object failed!");
180376af099aSliuyi 			NORMAL_COLOR_ATTR;
180476af099aSliuyi 			printf("\r\n");
180576af099aSliuyi 			return bSuccess;
180676af099aSliuyi 		}
180776af099aSliuyi 
180876af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
180932268622SAndreas Färber 		printf("Downloading bootloader...\r\n");
181076af099aSliuyi 		iRet = pDevice->DownloadBoot();
181176af099aSliuyi 
181276af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
181376af099aSliuyi 		CURSOR_DEL_LINE;
181476af099aSliuyi 		if (iRet == 0) {
181576af099aSliuyi 			bSuccess = true;
181632268622SAndreas Färber 			printf("Downloading bootloader succeeded.\r\n");
181776af099aSliuyi 		}
181876af099aSliuyi 		else
181932268622SAndreas Färber 			printf("Downloading bootloader failed!\r\n");
182076af099aSliuyi 
182176af099aSliuyi 		if (pImage)
182276af099aSliuyi 			delete pImage;
182376af099aSliuyi 		if(pDevice)
182476af099aSliuyi 			delete pDevice;
182576af099aSliuyi 	}
182676af099aSliuyi 	return bSuccess;
182776af099aSliuyi }
1828c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1829c30d921cSKever Yang {
1830c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1831c30d921cSKever Yang 		return false;
1832c30d921cSKever Yang 	CRKImage *pImage = NULL;
1833c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1834c30d921cSKever Yang 	CRKComm *pComm = NULL;
1835*46bb4c07Sliuyi 	bool bRet,bNewIDBlock=false, bSuccess = false;
1836c30d921cSKever Yang 	int iRet;
1837*46bb4c07Sliuyi 	unsigned int i;
1838aca206f7SPeter Robinson 	signed char index;
1839*46bb4c07Sliuyi 	USHORT usFlashDataSec, usFlashBootSec, usFlashHeadSec;
1840*46bb4c07Sliuyi 	DWORD dwLoaderSize, dwLoaderDataSize, dwLoaderHeadSize, dwDelay, dwSectorNum;
1841c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1842c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1843*46bb4c07Sliuyi 	char loaderHeadName[] = "FlashHead";
1844c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1845c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1846*46bb4c07Sliuyi 	PBYTE loaderHeadBuffer = NULL;
1847c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1848*46bb4c07Sliuyi 	BYTE capability[8];
1849c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1850c30d921cSKever Yang 	if (!bRet){
1851c30d921cSKever Yang 		ERROR_COLOR_ATTR;
185232268622SAndreas Färber 		printf("Opening loader failed, exiting upgrade loader!");
1853c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1854c30d921cSKever Yang 		printf("\r\n");
1855c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1856c30d921cSKever Yang 	} else {
1857c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1858c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1859c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1860c30d921cSKever Yang 		if (!bRet) {
1861c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1862c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1863c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1864c30d921cSKever Yang 			printf("\r\n");
1865c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1866c30d921cSKever Yang 		}
1867c30d921cSKever Yang 
186832268622SAndreas Färber 		printf("Upgrading loader...\r\n");
1869c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1870c30d921cSKever Yang 		if (index == -1) {
1871c30d921cSKever Yang 			if (g_pLogObject) {
187232268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1873c30d921cSKever Yang 			}
1874c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1875c30d921cSKever Yang 		}
1876c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1877c30d921cSKever Yang 		if (!bRet) {
1878c30d921cSKever Yang 			if (g_pLogObject) {
187932268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1880c30d921cSKever Yang 			}
1881c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1882c30d921cSKever Yang 		}
1883c30d921cSKever Yang 
1884c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1885c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1886c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1887c30d921cSKever Yang 			if (g_pLogObject) {
188832268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1889c30d921cSKever Yang 			}
1890c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1891c30d921cSKever Yang 		}
1892c30d921cSKever Yang 
1893c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1894c30d921cSKever Yang 		if (index == -1) {
1895c30d921cSKever Yang 			if (g_pLogObject) {
189632268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1897c30d921cSKever Yang 			}
1898c30d921cSKever Yang 			delete []loaderCodeBuffer;
1899c30d921cSKever Yang 			return -4;
1900c30d921cSKever Yang 		}
1901c30d921cSKever Yang 
1902c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1903c30d921cSKever Yang 		if (!bRet) {
1904c30d921cSKever Yang 			if (g_pLogObject) {
190532268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1906c30d921cSKever Yang 			}
1907c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1908c30d921cSKever Yang 		}
1909c30d921cSKever Yang 
1910c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1911c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1912c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1913c30d921cSKever Yang 			if (g_pLogObject) {
191432268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1915c30d921cSKever Yang 			}
1916c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1917c30d921cSKever Yang 		}
1918c30d921cSKever Yang 
1919*46bb4c07Sliuyi 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderHeadName);
1920*46bb4c07Sliuyi 		if (index != -1) {
1921*46bb4c07Sliuyi 			bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderHeadSize, dwDelay);
1922*46bb4c07Sliuyi 			if (!bRet) {
1923*46bb4c07Sliuyi 				if (g_pLogObject) {
1924*46bb4c07Sliuyi 					g_pLogObject->Record("ERROR: %s --> Get LoaderHead Entry Size failed", __func__);
1925*46bb4c07Sliuyi 				}
1926*46bb4c07Sliuyi 				goto Exit_UpgradeLoader;
1927*46bb4c07Sliuyi 			}
1928*46bb4c07Sliuyi 
1929*46bb4c07Sliuyi 			loaderHeadBuffer= new BYTE[dwLoaderHeadSize];
1930*46bb4c07Sliuyi 			memset(loaderHeadBuffer, 0, dwLoaderHeadSize);
1931*46bb4c07Sliuyi 			if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderHeadBuffer)) {
1932*46bb4c07Sliuyi 				if (g_pLogObject) {
1933*46bb4c07Sliuyi 					g_pLogObject->Record("ERROR: %s --> Get LoaderHead Data failed", __func__);
1934*46bb4c07Sliuyi 				}
1935*46bb4c07Sliuyi 				goto Exit_UpgradeLoader;
1936*46bb4c07Sliuyi 			}
1937*46bb4c07Sliuyi 
1938*46bb4c07Sliuyi 			iRet = pComm->RKU_ReadCapability(capability);
1939*46bb4c07Sliuyi 			if (iRet != ERR_SUCCESS)
1940*46bb4c07Sliuyi 			{
1941*46bb4c07Sliuyi 				if (g_pLogObject)
1942*46bb4c07Sliuyi 					g_pLogObject->Record("ERROR: %s --> read capability failed", __func__);
1943*46bb4c07Sliuyi 				goto Exit_UpgradeLoader;
1944*46bb4c07Sliuyi 			}
1945*46bb4c07Sliuyi 			if ((capability[1] & 1) == 0) {
1946*46bb4c07Sliuyi 				if (g_pLogObject)
1947*46bb4c07Sliuyi 					g_pLogObject->Record("ERROR: %s --> device did not support to upgrade the loader", __func__);
1948*46bb4c07Sliuyi 				ERROR_COLOR_ATTR;
1949*46bb4c07Sliuyi 				printf("Device not support to upgrade the loader!");
1950*46bb4c07Sliuyi 				NORMAL_COLOR_ATTR;
1951*46bb4c07Sliuyi 				printf("\r\n");
1952*46bb4c07Sliuyi 				goto Exit_UpgradeLoader;
1953*46bb4c07Sliuyi 			}
1954*46bb4c07Sliuyi 			bNewIDBlock = true;
1955*46bb4c07Sliuyi 		}
1956*46bb4c07Sliuyi 
1957c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1958c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1959*46bb4c07Sliuyi 		if (bNewIDBlock) {
1960*46bb4c07Sliuyi 			usFlashHeadSec = (ALIGN(dwLoaderHeadSize, 2048)) / SECTOR_SIZE;
1961*46bb4c07Sliuyi 			dwSectorNum = usFlashHeadSec + usFlashDataSec + usFlashBootSec;
1962*46bb4c07Sliuyi 		} else
1963c30d921cSKever Yang 			dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1964c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1965c30d921cSKever Yang 		if (!pIDBData) {
1966c30d921cSKever Yang 			ERROR_COLOR_ATTR;
196732268622SAndreas Färber 			printf("Allocating memory failed!");
1968c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1969c30d921cSKever Yang 			printf("\r\n");
1970c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1971c30d921cSKever Yang 		}
1972c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1973*46bb4c07Sliuyi 		if (bNewIDBlock) {
1974*46bb4c07Sliuyi 			if (pBoot->Rc4DisableFlag)
1975*46bb4c07Sliuyi 			{//close rc4 encryption
1976*46bb4c07Sliuyi 				for (i=0;i<dwLoaderHeadSize/SECTOR_SIZE;i++)
1977*46bb4c07Sliuyi 				{
1978*46bb4c07Sliuyi 					P_RC4(loaderHeadBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
1979*46bb4c07Sliuyi 				}
1980*46bb4c07Sliuyi 				for (i=0;i<dwLoaderDataSize/SECTOR_SIZE;i++)
1981*46bb4c07Sliuyi 				{
1982*46bb4c07Sliuyi 					P_RC4(loaderDataBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
1983*46bb4c07Sliuyi 				}
1984*46bb4c07Sliuyi 				for (i=0;i<dwLoaderSize/SECTOR_SIZE;i++)
1985*46bb4c07Sliuyi 				{
1986*46bb4c07Sliuyi 					P_RC4(loaderCodeBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
1987*46bb4c07Sliuyi 				}
1988*46bb4c07Sliuyi 			}
1989*46bb4c07Sliuyi 			memcpy(pIDBData, loaderHeadBuffer, dwLoaderHeadSize);
1990*46bb4c07Sliuyi 			memcpy(pIDBData+SECTOR_SIZE*usFlashHeadSec, loaderDataBuffer, dwLoaderDataSize);
1991*46bb4c07Sliuyi 			memcpy(pIDBData+SECTOR_SIZE*(usFlashHeadSec+usFlashDataSec), loaderCodeBuffer, dwLoaderSize);
1992*46bb4c07Sliuyi 		} else {
1993b38fe5fcSliuyi 			iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
1994c30d921cSKever Yang 			if (iRet != 0) {
1995c30d921cSKever Yang 				ERROR_COLOR_ATTR;
199632268622SAndreas Färber 				printf("Making idblock failed!");
1997c30d921cSKever Yang 				NORMAL_COLOR_ATTR;
1998c30d921cSKever Yang 				printf("\r\n");
1999c30d921cSKever Yang 				goto Exit_UpgradeLoader;
2000c30d921cSKever Yang 			}
2001*46bb4c07Sliuyi 		}
2002*46bb4c07Sliuyi 
2003c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
2004c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
2005c30d921cSKever Yang 		CURSOR_DEL_LINE;
2006c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
2007b38fe5fcSliuyi 			//pComm->Reset_Usb_Device();
2008c30d921cSKever Yang 			bSuccess = true;
200932268622SAndreas Färber 			printf("Upgrading loader succeeded.\r\n");
2010c30d921cSKever Yang 		} else {
201132268622SAndreas Färber 			printf("Upgrading loader failed!\r\n");
2012c30d921cSKever Yang 			goto Exit_UpgradeLoader;
2013c30d921cSKever Yang 		}
2014c30d921cSKever Yang 	}
2015c30d921cSKever Yang Exit_UpgradeLoader:
2016c30d921cSKever Yang 	if (pImage)
2017c30d921cSKever Yang 		delete pImage;
2018c30d921cSKever Yang 	if (pComm)
2019c30d921cSKever Yang 		delete pComm;
2020c30d921cSKever Yang 	if (loaderCodeBuffer)
2021c30d921cSKever Yang 		delete []loaderCodeBuffer;
2022c30d921cSKever Yang 	if (loaderDataBuffer)
2023c30d921cSKever Yang 		delete []loaderDataBuffer;
2024*46bb4c07Sliuyi 	if (loaderHeadBuffer)
2025*46bb4c07Sliuyi 		delete []loaderHeadBuffer;
2026c30d921cSKever Yang 	if (pIDBData)
2027c30d921cSKever Yang 		delete []pIDBData;
2028c30d921cSKever Yang 	return bSuccess;
2029c30d921cSKever Yang }
20303dc7e3ceSliuyi bool print_gpt(STRUCT_RKDEVICE_DESC &dev)
20313dc7e3ceSliuyi {
20323dc7e3ceSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
20333dc7e3ceSliuyi 		return false;
20343dc7e3ceSliuyi 	u8 master_gpt[34 * SECTOR_SIZE];
20353dc7e3ceSliuyi 	gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE);
20363dc7e3ceSliuyi 	bool bRet, bSuccess = false;
20373dc7e3ceSliuyi 	int iRet;
20383dc7e3ceSliuyi 	gpt_entry  *gptEntry  = NULL;
20393dc7e3ceSliuyi 	u32 i,j;
20403dc7e3ceSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
20413dc7e3ceSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
20423dc7e3ceSliuyi 	CRKComm *pComm = NULL;
20433dc7e3ceSliuyi 	char partName[36];
20443dc7e3ceSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
20453dc7e3ceSliuyi 	if (!bRet) {
20463dc7e3ceSliuyi 		ERROR_COLOR_ATTR;
20473dc7e3ceSliuyi 		printf("Creating Comm Object failed!");
20483dc7e3ceSliuyi 		NORMAL_COLOR_ATTR;
20493dc7e3ceSliuyi 		printf("\r\n");
20503dc7e3ceSliuyi 		return bSuccess;
20513dc7e3ceSliuyi 	}
20523dc7e3ceSliuyi 	iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt);
20533dc7e3ceSliuyi 	if(ERR_SUCCESS == iRet) {
20543dc7e3ceSliuyi 		if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
20553dc7e3ceSliuyi 			goto Exit_PrintGpt;
20563dc7e3ceSliuyi 		}
20573dc7e3ceSliuyi 
20583dc7e3ceSliuyi 	} else {
20593dc7e3ceSliuyi 		if (g_pLogObject)
20603dc7e3ceSliuyi 				g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
20613dc7e3ceSliuyi 		printf("Read GPT failed!\r\n");
20623dc7e3ceSliuyi 		goto Exit_PrintGpt;
20633dc7e3ceSliuyi 	}
20643dc7e3ceSliuyi 
2065081d237aSliuyi 	printf("**********Partition Info(GPT)**********\r\n");
20663dc7e3ceSliuyi 	printf("NO  LBA       Name                \r\n");
20673dc7e3ceSliuyi 	for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) {
20683dc7e3ceSliuyi 		gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
20693dc7e3ceSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
20703dc7e3ceSliuyi 			break;
20713dc7e3ceSliuyi 		memset(partName, 0 , 36);
20723dc7e3ceSliuyi 		j = 0;
20733dc7e3ceSliuyi 		while (gptEntry->partition_name[j]) {
20743dc7e3ceSliuyi 			partName[j] = (char)gptEntry->partition_name[j];
20753dc7e3ceSliuyi 			j++;
20763dc7e3ceSliuyi 		}
20773dc7e3ceSliuyi 		printf("%02d  %08X  %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName);
20783dc7e3ceSliuyi 	}
20793dc7e3ceSliuyi 	bSuccess = true;
20803dc7e3ceSliuyi Exit_PrintGpt:
20813dc7e3ceSliuyi 	if (pComm)
20823dc7e3ceSliuyi 		delete pComm;
20833dc7e3ceSliuyi 	return bSuccess;
20843dc7e3ceSliuyi }
2085081d237aSliuyi bool print_parameter(STRUCT_RKDEVICE_DESC &dev)
2086081d237aSliuyi {
2087081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2088081d237aSliuyi 		return false;
2089081d237aSliuyi 	u8 param_buf[512 * SECTOR_SIZE];
2090081d237aSliuyi 	bool bRet, bSuccess = false;
2091081d237aSliuyi 	int iRet;
2092081d237aSliuyi 	u32 i, nParamSize;
2093081d237aSliuyi 	CRKComm *pComm = NULL;
2094081d237aSliuyi 	PARAM_ITEM_VECTOR vecParamItem;
2095081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuidItem;
2096081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2097081d237aSliuyi 	if (!bRet) {
2098081d237aSliuyi 		ERROR_COLOR_ATTR;
2099081d237aSliuyi 		printf("Creating Comm Object failed!");
2100081d237aSliuyi 		NORMAL_COLOR_ATTR;
2101081d237aSliuyi 		printf("\r\n");
2102081d237aSliuyi 		return bSuccess;
2103081d237aSliuyi 	}
2104081d237aSliuyi 	iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf);
2105081d237aSliuyi 	if(ERR_SUCCESS == iRet) {
2106081d237aSliuyi 		if (*(u32 *)param_buf != 0x4D524150) {
2107081d237aSliuyi 			goto Exit_PrintParam;
2108081d237aSliuyi 		}
2109081d237aSliuyi 
2110081d237aSliuyi 	} else {
2111081d237aSliuyi 		if (g_pLogObject)
2112081d237aSliuyi 				g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2113081d237aSliuyi 		printf("Read parameter failed!\r\n");
2114081d237aSliuyi 		goto Exit_PrintParam;
2115081d237aSliuyi 	}
2116081d237aSliuyi 	nParamSize = *(u32 *)(param_buf + 4);
2117081d237aSliuyi 	memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8);
2118081d237aSliuyi 
2119081d237aSliuyi 	bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem);
2120081d237aSliuyi 	if (!bRet) {
2121081d237aSliuyi 		if (g_pLogObject)
2122081d237aSliuyi 				g_pLogObject->Record("Error: parse parameter failed");
2123081d237aSliuyi 		printf("Parse parameter failed!\r\n");
2124081d237aSliuyi 		goto Exit_PrintParam;
2125081d237aSliuyi 	}
2126081d237aSliuyi 	printf("**********Partition Info(parameter)**********\r\n");
2127081d237aSliuyi 	printf("NO  LBA       Name                \r\n");
2128081d237aSliuyi 	for (i = 0; i < vecParamItem.size(); i++) {
2129081d237aSliuyi 		printf("%02d  %08X  %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName);
2130081d237aSliuyi 	}
2131081d237aSliuyi 	bSuccess = true;
2132081d237aSliuyi Exit_PrintParam:
2133081d237aSliuyi 	if (pComm)
2134081d237aSliuyi 		delete pComm;
2135081d237aSliuyi 	return bSuccess;
2136081d237aSliuyi }
2137c30d921cSKever Yang 
213876af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
213976af099aSliuyi {
214076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
214176af099aSliuyi 		return false;
214276af099aSliuyi 	CRKImage *pImage = NULL;
214376af099aSliuyi 	bool bRet, bSuccess = false;
214476af099aSliuyi 	int iRet;
214576af099aSliuyi 	CRKScan *pScan = NULL;
214676af099aSliuyi 	pScan = new CRKScan();
214776af099aSliuyi 	pScan->SetVidPid();
214876af099aSliuyi 
214976af099aSliuyi 	CRKComm *pComm = NULL;
215076af099aSliuyi 	CRKDevice *pDevice = NULL;
215176af099aSliuyi 
215276af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
215376af099aSliuyi 	if (!bRet) {
215476af099aSliuyi 		if (pScan)
215576af099aSliuyi 			delete pScan;
215676af099aSliuyi 		ERROR_COLOR_ATTR;
215776af099aSliuyi 		printf("Creating Comm Object failed!");
215876af099aSliuyi 		NORMAL_COLOR_ATTR;
215976af099aSliuyi 		printf("\r\n");
216076af099aSliuyi 		return bSuccess;
216176af099aSliuyi 	}
216276af099aSliuyi 
216376af099aSliuyi 	pDevice = new CRKDevice(dev);
216476af099aSliuyi 	if (!pDevice) {
216576af099aSliuyi 		if (pComm)
216676af099aSliuyi 			delete pComm;
216776af099aSliuyi 		if (pScan)
216876af099aSliuyi 			delete pScan;
216976af099aSliuyi 		ERROR_COLOR_ATTR;
217076af099aSliuyi 		printf("Creating device object failed!");
217176af099aSliuyi 		NORMAL_COLOR_ATTR;
217276af099aSliuyi 		printf("\r\n");
217376af099aSliuyi 		return bSuccess;
217476af099aSliuyi 	}
217576af099aSliuyi 
217676af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
217776af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
217876af099aSliuyi 
217932268622SAndreas Färber 	printf("Starting to erase flash...\r\n");
21806502326dSliuyi 	bRet = pDevice->GetFlashInfo();
21816502326dSliuyi 	if (!bRet) {
21826502326dSliuyi 		if (pDevice)
21836502326dSliuyi 			delete pDevice;
21846502326dSliuyi 		if (pScan)
21856502326dSliuyi 			delete pScan;
21866502326dSliuyi 		ERROR_COLOR_ATTR;
21876502326dSliuyi 		printf("Getting flash info from device failed!");
21886502326dSliuyi 		NORMAL_COLOR_ATTR;
21896502326dSliuyi 		printf("\r\n");
21906502326dSliuyi 		return bSuccess;
21916502326dSliuyi 	}
219276af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
219376af099aSliuyi 	if (pDevice)
219476af099aSliuyi 		delete pDevice;
219576af099aSliuyi 
219676af099aSliuyi 	if (iRet == 0) {
219776af099aSliuyi 		if (pScan) {
219876af099aSliuyi 			pScan->SetVidPid();
219976af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
220076af099aSliuyi 			delete pScan;
220176af099aSliuyi 		}
220276af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
220376af099aSliuyi 		CURSOR_DEL_LINE;
220476af099aSliuyi 		bSuccess = true;
220532268622SAndreas Färber 		printf("Erasing flash complete.\r\n");
220676af099aSliuyi 	}
220776af099aSliuyi 
220876af099aSliuyi 	return bSuccess;
220976af099aSliuyi }
221076af099aSliuyi 
221176af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
221276af099aSliuyi {
221376af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
221476af099aSliuyi 		return false;
221576af099aSliuyi 	CRKUsbComm *pComm = NULL;
221676af099aSliuyi 	bool bRet, bSuccess = false;
221776af099aSliuyi 	int iRet;
221876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
221976af099aSliuyi 	if (bRet) {
222076af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
222176af099aSliuyi 		if (iRet != ERR_SUCCESS) {
222276af099aSliuyi 			if (g_pLogObject)
222376af099aSliuyi 				g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
222432268622SAndreas Färber 			printf("Test Device failed!\r\n");
222576af099aSliuyi 		} else {
222676af099aSliuyi 			bSuccess = true;
222776af099aSliuyi 			printf("Test Device OK.\r\n");
222876af099aSliuyi 		}
222976af099aSliuyi 	} else {
223032268622SAndreas Färber 		printf("Test Device quit, creating comm object failed!\r\n");
223176af099aSliuyi 	}
223276af099aSliuyi 	if (pComm) {
223376af099aSliuyi 		delete pComm;
223476af099aSliuyi 		pComm = NULL;
223576af099aSliuyi 	}
223676af099aSliuyi 	return bSuccess;
223776af099aSliuyi }
223876af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
223976af099aSliuyi {
224076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
224176af099aSliuyi 		return false;
224276af099aSliuyi 	CRKUsbComm *pComm = NULL;
224376af099aSliuyi 	bool bRet, bSuccess = false;
224476af099aSliuyi 	int iRet;
224576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
224676af099aSliuyi 	if (bRet) {
224776af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
224876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
224976af099aSliuyi 			if (g_pLogObject)
225076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
225132268622SAndreas Färber 			printf("Reset Device failed!\r\n");
225276af099aSliuyi 		} else {
225376af099aSliuyi 			bSuccess = true;
225476af099aSliuyi 			printf("Reset Device OK.\r\n");
225576af099aSliuyi 		}
225676af099aSliuyi 	} else {
225732268622SAndreas Färber 		printf("Reset Device quit, creating comm object failed!\r\n");
225876af099aSliuyi 	}
225976af099aSliuyi 	if (pComm) {
226076af099aSliuyi 		delete pComm;
226176af099aSliuyi 		pComm = NULL;
226276af099aSliuyi 	}
226376af099aSliuyi 	return bSuccess;
226476af099aSliuyi }
226576af099aSliuyi 
226676af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
226776af099aSliuyi {
226876af099aSliuyi 	CRKUsbComm *pComm = NULL;
226976af099aSliuyi 	bool bRet, bSuccess = false;
227076af099aSliuyi 	int iRet;
227176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
227276af099aSliuyi 		return bSuccess;
227376af099aSliuyi 
227476af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
227576af099aSliuyi 	if (bRet) {
227676af099aSliuyi 		BYTE flashID[5];
227776af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
227876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
227976af099aSliuyi 			if (g_pLogObject)
228076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
228132268622SAndreas Färber 			printf("Reading flash ID failed!\r\n");
228276af099aSliuyi 		} else {
228376af099aSliuyi 			printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
228476af099aSliuyi 			bSuccess = true;
228576af099aSliuyi 		}
228676af099aSliuyi 	} else {
228732268622SAndreas Färber 		printf("Read Flash ID quit, creating comm object failed!\r\n");
228876af099aSliuyi 	}
228976af099aSliuyi 	if (pComm) {
229076af099aSliuyi 		delete pComm;
229176af099aSliuyi 		pComm = NULL;
229276af099aSliuyi 	}
229376af099aSliuyi 	return bSuccess;
229476af099aSliuyi }
229576af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
229676af099aSliuyi {
229776af099aSliuyi 	CRKUsbComm *pComm = NULL;
229876af099aSliuyi 	bool bRet, bSuccess = false;
229976af099aSliuyi 	int iRet;
230076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
230176af099aSliuyi 		return bSuccess;
230276af099aSliuyi 
230376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
230476af099aSliuyi 	if (bRet) {
230576af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
230676af099aSliuyi 		UINT uiRead;
230776af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
230876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
230976af099aSliuyi 			if (g_pLogObject)
231076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
231132268622SAndreas Färber 			printf("Read Flash Info failed!\r\n");
231276af099aSliuyi 		} else {
231376af099aSliuyi 			printf("Flash Info:\r\n");
231476af099aSliuyi 			if (info.bManufCode <= 7) {
231576af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
231676af099aSliuyi 			}
231776af099aSliuyi 			else
231876af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
231976af099aSliuyi 
232076af099aSliuyi 			printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
23210dcb0a4cSliuyi 			printf("\tFlash Size: %d Sectors\r\n", info.uiFlashSize);
232276af099aSliuyi 			printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
232376af099aSliuyi 			printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
232476af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
232576af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
232676af099aSliuyi 			printf("\tFlash CS: ");
232776af099aSliuyi 			for(int i = 0; i < 8; i++) {
232876af099aSliuyi 				if( info.bFlashCS & (1 << i) )
232976af099aSliuyi 					printf("Flash<%d> ", i);
233076af099aSliuyi 			}
233176af099aSliuyi 			printf("\r\n");
233276af099aSliuyi 			bSuccess = true;
233376af099aSliuyi 		}
233476af099aSliuyi 	}else {
233532268622SAndreas Färber 		printf("Read Flash Info quit, creating comm object failed!\r\n");
233676af099aSliuyi 	}
233776af099aSliuyi 	if (pComm) {
233876af099aSliuyi 		delete pComm;
233976af099aSliuyi 		pComm = NULL;
234076af099aSliuyi 	}
234176af099aSliuyi 	return bSuccess;
234276af099aSliuyi }
234376af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
234476af099aSliuyi {
234576af099aSliuyi 	CRKUsbComm *pComm = NULL;
234676af099aSliuyi 	bool bRet, bSuccess = false;
234776af099aSliuyi 	int iRet;
234876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
234976af099aSliuyi 		return bSuccess;
235076af099aSliuyi 
235176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
235276af099aSliuyi 	if (bRet) {
235376af099aSliuyi 		BYTE chipInfo[16];
235476af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
235576af099aSliuyi 		if (iRet != ERR_SUCCESS) {
235676af099aSliuyi 			if (g_pLogObject)
235776af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
235832268622SAndreas Färber 			printf("Read Chip Info failed!\r\n");
235976af099aSliuyi 		} else {
236076af099aSliuyi 			string strChipInfo;
236176af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
236276af099aSliuyi 			printf("Chip Info: %s\r\n", strChipInfo.c_str());
236376af099aSliuyi 			bSuccess = true;
236476af099aSliuyi 		}
236576af099aSliuyi 	} else {
236632268622SAndreas Färber 		printf("Read Chip Info quit, creating comm object failed!\r\n");
236776af099aSliuyi 	}
236876af099aSliuyi 	if (pComm) {
236976af099aSliuyi 		delete pComm;
237076af099aSliuyi 		pComm = NULL;
237176af099aSliuyi 	}
237276af099aSliuyi 	return bSuccess;
237376af099aSliuyi }
2374081d237aSliuyi bool read_capability(STRUCT_RKDEVICE_DESC &dev)
2375081d237aSliuyi {
2376081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2377081d237aSliuyi 	bool bRet, bSuccess = false;
2378081d237aSliuyi 	int iRet;
2379081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2380081d237aSliuyi 		return bSuccess;
2381081d237aSliuyi 
2382081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2383081d237aSliuyi 	if (bRet) {
2384081d237aSliuyi 
2385081d237aSliuyi 		BYTE capability[8];
2386081d237aSliuyi 		iRet = pComm->RKU_ReadCapability(capability);
2387081d237aSliuyi 		if (iRet != ERR_SUCCESS)
2388081d237aSliuyi 		{
2389081d237aSliuyi 			if (g_pLogObject)
2390081d237aSliuyi 				g_pLogObject->Record("Error:read_capability failed,err=%d", iRet);
2391081d237aSliuyi 			printf("Read capability Fail!\r\n");
2392081d237aSliuyi 		} else {
2393081d237aSliuyi 			printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n",
2394081d237aSliuyi 			capability[0], capability[1], capability[2], capability[3],
2395081d237aSliuyi 			capability[4], capability[5], capability[6], capability[7]);
2396081d237aSliuyi 			if (capability[0] & 1)
2397081d237aSliuyi 			{
2398081d237aSliuyi 				printf("Direct LBA:\tenabled\r\n");
2399081d237aSliuyi 			}
2400081d237aSliuyi 
2401081d237aSliuyi 			if (capability[0] & 2)
2402081d237aSliuyi 			{
2403081d237aSliuyi 				printf("Vendor Storage:\tenabled\r\n");
2404081d237aSliuyi 			}
2405081d237aSliuyi 
2406081d237aSliuyi 			if (capability[0] & 4)
2407081d237aSliuyi 			{
2408081d237aSliuyi 				printf("First 4m Access:\tenabled\r\n");
2409081d237aSliuyi 			}
2410*46bb4c07Sliuyi 			if (capability[0] & 8)
2411*46bb4c07Sliuyi 			{
2412*46bb4c07Sliuyi 				printf("Read LBA:\tenabled\r\n");
2413*46bb4c07Sliuyi 			}
2414*46bb4c07Sliuyi 
2415*46bb4c07Sliuyi 			if (capability[0] & 20)
2416*46bb4c07Sliuyi 			{
2417*46bb4c07Sliuyi 				printf("Read Com Log:\tenabled\r\n");
2418*46bb4c07Sliuyi 			}
2419*46bb4c07Sliuyi 
2420*46bb4c07Sliuyi 			if (capability[0] & 40)
2421*46bb4c07Sliuyi 			{
2422*46bb4c07Sliuyi 				printf("Read IDB Config:\tenabled\r\n");
2423*46bb4c07Sliuyi 			}
2424*46bb4c07Sliuyi 
2425*46bb4c07Sliuyi 			if (capability[0] & 80)
2426*46bb4c07Sliuyi 			{
2427*46bb4c07Sliuyi 				printf("Read Secure Mode:\tenabled\r\n");
2428*46bb4c07Sliuyi 			}
2429*46bb4c07Sliuyi 
2430*46bb4c07Sliuyi 			if (capability[1] & 1)
2431*46bb4c07Sliuyi 			{
2432*46bb4c07Sliuyi 				printf("New IDB:\tenabled\r\n");
2433*46bb4c07Sliuyi 			}
2434081d237aSliuyi 			bSuccess = true;
2435081d237aSliuyi 		}
2436081d237aSliuyi 	} else {
2437081d237aSliuyi 		printf("Read capability quit, creating comm object failed!\r\n");
2438081d237aSliuyi 	}
2439081d237aSliuyi 	if (pComm) {
2440081d237aSliuyi 		delete pComm;
2441081d237aSliuyi 		pComm = NULL;
2442081d237aSliuyi 	}
2443081d237aSliuyi 	return bSuccess;
2444081d237aSliuyi }
2445081d237aSliuyi bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam)
2446081d237aSliuyi {
2447081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2448081d237aSliuyi 		return false;
2449081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2450081d237aSliuyi 	bool bRet, bSuccess = false;
2451081d237aSliuyi 	int iRet;
2452081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2453081d237aSliuyi 	if (bRet) {
2454081d237aSliuyi 		iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam);
2455081d237aSliuyi 		if(ERR_SUCCESS == iRet) {
2456081d237aSliuyi 			if (*(u32 *)pParam != 0x4D524150) {
2457081d237aSliuyi 				goto Exit_ReadParam;
2458081d237aSliuyi 			}
2459081d237aSliuyi 		} else {
2460081d237aSliuyi 			if (g_pLogObject)
2461081d237aSliuyi 					g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2462081d237aSliuyi 			printf("Read parameter failed!\r\n");
2463081d237aSliuyi 			goto Exit_ReadParam;
2464081d237aSliuyi 		}
2465081d237aSliuyi 		bSuccess = true;
2466081d237aSliuyi 	}
2467081d237aSliuyi Exit_ReadParam:
2468081d237aSliuyi 	if (pComm) {
2469081d237aSliuyi 		delete pComm;
2470081d237aSliuyi 		pComm = NULL;
2471081d237aSliuyi 	}
2472081d237aSliuyi 	return bSuccess;
2473081d237aSliuyi }
2474081d237aSliuyi 
2475081d237aSliuyi 
24766ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt)
24776ae612beSliuyi {
24786ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
24796ae612beSliuyi 		return false;
24806ae612beSliuyi 	gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE);
24816ae612beSliuyi 	CRKUsbComm *pComm = NULL;
24826ae612beSliuyi 	bool bRet, bSuccess = false;
24836ae612beSliuyi 	int iRet;
24846ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
24856ae612beSliuyi 	if (bRet) {
24866ae612beSliuyi 		iRet = pComm->RKU_ReadLBA( 0, 34, pGpt);
24876ae612beSliuyi 		if(ERR_SUCCESS == iRet) {
24886ae612beSliuyi 			if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
24896ae612beSliuyi 				goto Exit_ReadGPT;
24906ae612beSliuyi 			}
24916ae612beSliuyi 		} else {
24926ae612beSliuyi 			if (g_pLogObject)
24936ae612beSliuyi 					g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
24946ae612beSliuyi 			printf("Read GPT failed!\r\n");
24956ae612beSliuyi 			goto Exit_ReadGPT;
24966ae612beSliuyi 		}
24976ae612beSliuyi 		bSuccess = true;
24986ae612beSliuyi 	}
24996ae612beSliuyi Exit_ReadGPT:
25006ae612beSliuyi 	if (pComm) {
25016ae612beSliuyi 		delete pComm;
25026ae612beSliuyi 		pComm = NULL;
25036ae612beSliuyi 	}
25046ae612beSliuyi 	return bSuccess;
25056ae612beSliuyi }
250676af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
250776af099aSliuyi {
250876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
250976af099aSliuyi 		return false;
251076af099aSliuyi 	CRKUsbComm *pComm = NULL;
251176af099aSliuyi 	FILE *file = NULL;
251276af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
251376af099aSliuyi 	int iRet;
251476af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
251576af099aSliuyi 	int nSectorSize = 512;
251676af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
251776af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
251876af099aSliuyi 	if (bRet) {
251976af099aSliuyi 		if(szFile) {
252076af099aSliuyi 			file = fopen(szFile, "wb+");
252176af099aSliuyi 			if( !file ) {
252276af099aSliuyi 				printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
252376af099aSliuyi 				goto Exit_ReadLBA;
252476af099aSliuyi 			}
252576af099aSliuyi 		}
252676af099aSliuyi 
252776af099aSliuyi 		while(uiLen > 0) {
252876af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
252976af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
253076af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
253176af099aSliuyi 			if(ERR_SUCCESS == iRet) {
253276af099aSliuyi 				uiLen -= iRead;
253376af099aSliuyi 				iTotalRead += iRead;
253476af099aSliuyi 
253576af099aSliuyi 				if(szFile) {
253676af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
253776af099aSliuyi 					if (bFirst){
253876af099aSliuyi 						if (iTotalRead >= 1024)
253932268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
254076af099aSliuyi 						else
254132268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
254276af099aSliuyi 						bFirst = false;
254376af099aSliuyi 					} else {
254476af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
254576af099aSliuyi 						CURSOR_DEL_LINE;
254676af099aSliuyi 						if (iTotalRead >= 1024)
254732268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
254876af099aSliuyi 						else
254932268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
255076af099aSliuyi 					}
255176af099aSliuyi 				}
255276af099aSliuyi 				else
255376af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
255476af099aSliuyi 			} else {
255576af099aSliuyi 				if (g_pLogObject)
255676af099aSliuyi 					g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
255776af099aSliuyi 
255876af099aSliuyi 				printf("Read LBA failed!\r\n");
255976af099aSliuyi 				goto Exit_ReadLBA;
256076af099aSliuyi 			}
256176af099aSliuyi 		}
256276af099aSliuyi 		bSuccess = true;
256376af099aSliuyi 	} else {
256432268622SAndreas Färber 		printf("Read LBA quit, creating comm object failed!\r\n");
256576af099aSliuyi 	}
256676af099aSliuyi Exit_ReadLBA:
256776af099aSliuyi 	if (pComm) {
256876af099aSliuyi 		delete pComm;
256976af099aSliuyi 		pComm = NULL;
257076af099aSliuyi 	}
257176af099aSliuyi 	if (file)
257276af099aSliuyi 		fclose(file);
257376af099aSliuyi 	return bSuccess;
257476af099aSliuyi }
25750dcb0a4cSliuyi bool erase_ubi_block(STRUCT_RKDEVICE_DESC &dev, u32 uiOffset, u32 uiPartSize)
25760dcb0a4cSliuyi {
25770dcb0a4cSliuyi 	STRUCT_FLASHINFO_CMD info;
25780dcb0a4cSliuyi 	CRKComm *pComm = NULL;
25790dcb0a4cSliuyi 	BYTE flashID[5];
25800dcb0a4cSliuyi 	bool bRet,bSuccess=false;
25810dcb0a4cSliuyi 	UINT uiReadCount,uiStartBlock,uiEraseBlock,uiBlockCount,uiErasePos;
25820dcb0a4cSliuyi 	int iRet;
25830dcb0a4cSliuyi 	DWORD *pID=NULL;
25841e890c4fSliuyi 
2585e541b7bbSliuyi 	printf("Erase ubi in, offset=0x%08x,size=0x%08x!\r\n",uiOffset,uiPartSize);
25860dcb0a4cSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
25870dcb0a4cSliuyi 		return false;
25880dcb0a4cSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
25890dcb0a4cSliuyi 	if (!bRet)
25900dcb0a4cSliuyi 	{
25910dcb0a4cSliuyi 		printf("Erase ubi quit, creating comm object failed!\r\n");
25920dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
25930dcb0a4cSliuyi 	}
25940dcb0a4cSliuyi 	iRet = pComm->RKU_ReadFlashID(flashID);
25950dcb0a4cSliuyi 	if(iRet!=ERR_SUCCESS)
25960dcb0a4cSliuyi 	{
25970dcb0a4cSliuyi 		if (g_pLogObject)
25980dcb0a4cSliuyi 		{
25990dcb0a4cSliuyi 			g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashID failed,RetCode(%d)",iRet);
26000dcb0a4cSliuyi 		}
26010dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
26020dcb0a4cSliuyi 	}
26030dcb0a4cSliuyi 	pID = (DWORD *)flashID;
26041e890c4fSliuyi 
26050dcb0a4cSliuyi 	if (*pID==0x434d4d45)//emmc
26060dcb0a4cSliuyi 	{
26070dcb0a4cSliuyi 		bSuccess = true;
26080dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
26090dcb0a4cSliuyi 	}
26100dcb0a4cSliuyi 
26110dcb0a4cSliuyi 	iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info,&uiReadCount);
26120dcb0a4cSliuyi 	if (iRet!=ERR_SUCCESS)
26130dcb0a4cSliuyi 	{
26140dcb0a4cSliuyi 		if (g_pLogObject)
26150dcb0a4cSliuyi 			g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashInfo err=%d", iRet);
26160dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
26170dcb0a4cSliuyi 	}
26180dcb0a4cSliuyi 	if (uiPartSize==0xFFFFFFFF)
2619e607a5d6Sliuyi 		uiPartSize = info.uiFlashSize - uiOffset;
26200dcb0a4cSliuyi 
26210dcb0a4cSliuyi 	uiStartBlock = uiOffset / info.usBlockSize;
2622e607a5d6Sliuyi 	uiEraseBlock = (uiPartSize + info.usBlockSize -1) / info.usBlockSize;
2623e607a5d6Sliuyi 
26240dcb0a4cSliuyi 
2625e541b7bbSliuyi 	printf("Erase block start, offset=0x%08x,count=0x%08x!\r\n",uiStartBlock,uiEraseBlock);
26260dcb0a4cSliuyi 	uiErasePos=uiStartBlock;
26270dcb0a4cSliuyi 	while (uiEraseBlock>0)
26280dcb0a4cSliuyi 	{
26290dcb0a4cSliuyi 		uiBlockCount = (uiEraseBlock<MAX_ERASE_BLOCKS)?uiEraseBlock:MAX_ERASE_BLOCKS;
26300dcb0a4cSliuyi 
26310dcb0a4cSliuyi 		iRet = pComm->RKU_EraseBlock(0,uiErasePos,uiBlockCount,ERASE_FORCE);
26320dcb0a4cSliuyi 		if ((iRet!=ERR_SUCCESS)&&(iRet!=ERR_FOUND_BAD_BLOCK))
26330dcb0a4cSliuyi 		{
26340dcb0a4cSliuyi 			if (g_pLogObject)
26350dcb0a4cSliuyi 			{
26360dcb0a4cSliuyi 				g_pLogObject->Record("Error:EraseUBIBlock-->RKU_EraseBlock failed,RetCode(%d)",iRet);
26370dcb0a4cSliuyi 			}
26380dcb0a4cSliuyi 			goto EXIT_UBI_ERASE;
26390dcb0a4cSliuyi 		}
26400dcb0a4cSliuyi 
26410dcb0a4cSliuyi 		uiErasePos += uiBlockCount;
26420dcb0a4cSliuyi 		uiEraseBlock -= uiBlockCount;
26430dcb0a4cSliuyi 	}
26440dcb0a4cSliuyi 	bSuccess = true;
26450dcb0a4cSliuyi EXIT_UBI_ERASE:
26460dcb0a4cSliuyi 	if (pComm)
26470dcb0a4cSliuyi 		delete pComm;
26480dcb0a4cSliuyi 	return bSuccess;
26490dcb0a4cSliuyi }
26506ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize)
26516ae612beSliuyi {
2652ae4252f0Sliuyi 	UINT uiErase=1024*32;
26536ae612beSliuyi 	bool bSuccess = true;
26546ae612beSliuyi 	int iRet;
26556ae612beSliuyi 	while (uiSize)
26566ae612beSliuyi 	{
26576ae612beSliuyi 		if (uiSize>=uiErase)
26586ae612beSliuyi 		{
26596ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiErase);
26606ae612beSliuyi 			uiSize -= uiErase;
26616ae612beSliuyi 			uiOffset += uiErase;
26626ae612beSliuyi 		}
26636ae612beSliuyi 		else
26646ae612beSliuyi 		{
26656ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiSize);
26666ae612beSliuyi 			uiSize = 0;
26676ae612beSliuyi 			uiOffset += uiSize;
26686ae612beSliuyi 		}
26696ae612beSliuyi 		if (iRet!=ERR_SUCCESS)
26706ae612beSliuyi 		{
26716ae612beSliuyi 			if (g_pLogObject)
26726ae612beSliuyi 			{
26736ae612beSliuyi 				g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet);
26746ae612beSliuyi 			}
26756ae612beSliuyi 			bSuccess = false;
26766ae612beSliuyi 			break;
26776ae612beSliuyi 		}
26786ae612beSliuyi 	}
26796ae612beSliuyi 	return bSuccess;
26806ae612beSliuyi 
26816ae612beSliuyi }
26826ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk)
26836ae612beSliuyi {
26846ae612beSliuyi 	UINT uiRead;
26856ae612beSliuyi 	uiRead = fread(&chunk, 1, sizeof(chunk_header), file);
26866ae612beSliuyi 	if (uiRead != sizeof(chunk_header)) {
26876ae612beSliuyi 		if (g_pLogObject)
26886ae612beSliuyi 		{
26896ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno);
26906ae612beSliuyi 		}
26916ae612beSliuyi 		return false;
26926ae612beSliuyi 	}
26936ae612beSliuyi 	return true;
26946ae612beSliuyi }
26956ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize)
26966ae612beSliuyi {
26976ae612beSliuyi 	UINT uiRead;
26986ae612beSliuyi 	uiRead = fread(pBuf, 1, dwSize, file);
26996ae612beSliuyi 	if (uiRead!=dwSize)
27006ae612beSliuyi 	{
27016ae612beSliuyi 		if (g_pLogObject)
27026ae612beSliuyi 		{
27036ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno);
27046ae612beSliuyi 		}
27056ae612beSliuyi 		return false;
27066ae612beSliuyi 	}
27076ae612beSliuyi 	return true;
27086ae612beSliuyi }
27096ae612beSliuyi 
27106ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile)
27116ae612beSliuyi {
27126ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
27136ae612beSliuyi 		return false;
27146ae612beSliuyi 	CRKUsbComm *pComm = NULL;
27156ae612beSliuyi 	FILE *file = NULL;
27166ae612beSliuyi 	bool bRet, bSuccess = false, bFirst = true;
27176ae612beSliuyi 	int iRet;
2718e541b7bbSliuyi 	u64 iTotalWrite = 0, iFileSize = 0,dwChunkDataSize;
27196ae612beSliuyi 	UINT iRead = 0, uiTransferSec, curChunk, i;
2720e541b7bbSliuyi 	UINT dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc;
27216ae612beSliuyi 	BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA];
27226ae612beSliuyi 	sparse_header header;
27236ae612beSliuyi 	chunk_header  chunk;
27246ae612beSliuyi 	dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE;
27256ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
27266ae612beSliuyi 	if (bRet) {
2727ae4252f0Sliuyi 
27286ae612beSliuyi 		file = fopen(szFile, "rb");
27296ae612beSliuyi 		if( !file ) {
27306ae612beSliuyi 			printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile);
27316ae612beSliuyi 			goto Exit_WriteSparseLBA;
27326ae612beSliuyi 		}
27336ae612beSliuyi 		fseeko(file, 0, SEEK_SET);
27346ae612beSliuyi 		iRead = fread(&header, 1, sizeof(header), file);
27356ae612beSliuyi 		if (iRead != sizeof(sparse_header))
27366ae612beSliuyi 		{
27376ae612beSliuyi 			if (g_pLogObject)
27386ae612beSliuyi 			{
27396ae612beSliuyi 				g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno);
27406ae612beSliuyi 			}
27416ae612beSliuyi 			goto Exit_WriteSparseLBA;
27426ae612beSliuyi 		}
27436ae612beSliuyi 		iFileSize = header.blk_sz * (u64)header.total_blks;
27446ae612beSliuyi 		iTotalWrite = 0;
27456ae612beSliuyi 		curChunk = 0;
2746ae4252f0Sliuyi 		if (uiSize==(u32)-1)
2747ae4252f0Sliuyi 			uiSize = ALIGN(iFileSize, SECTOR_SIZE);
2748ae4252f0Sliuyi 		bRet = erase_partition(pComm, uiBegin, uiSize);
2749ae4252f0Sliuyi 		if (!bRet) {
2750ae4252f0Sliuyi 			printf("%s failed, erase partition error\r\n", __func__);
2751ae4252f0Sliuyi 			goto Exit_WriteSparseLBA;
2752ae4252f0Sliuyi 		}
27536ae612beSliuyi 		while(curChunk < header.total_chunks)
27546ae612beSliuyi 		{
27556ae612beSliuyi 			if (!EatSparseChunk(file, chunk)) {
27566ae612beSliuyi 				goto Exit_WriteSparseLBA;
27576ae612beSliuyi 			}
27586ae612beSliuyi 			curChunk++;
27596ae612beSliuyi 			switch (chunk.chunk_type) {
27606ae612beSliuyi 			case CHUNK_TYPE_RAW:
27616ae612beSliuyi 				dwChunkDataSize = chunk.total_sz - sizeof(chunk_header);
27626ae612beSliuyi 				while (dwChunkDataSize) {
27636ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
27646ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
27656ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
27666ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
27676ae612beSliuyi 					} else {
27686ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
27696ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
27706ae612beSliuyi 					}
27716ae612beSliuyi 					if (!EatSparseData(file, pBuf, dwTransferBytes)) {
27726ae612beSliuyi 						goto Exit_WriteSparseLBA;
27736ae612beSliuyi 					}
27746ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
27756ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
27766ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
27776ae612beSliuyi 						iTotalWrite += dwTransferBytes;
27786ae612beSliuyi 						uiBegin += uiTransferSec;
27796ae612beSliuyi 					} else {
27806ae612beSliuyi 						if (g_pLogObject) {
27816ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)",  __func__, iTotalWrite, iRet);
27826ae612beSliuyi 						}
27836ae612beSliuyi 						goto Exit_WriteSparseLBA;
27846ae612beSliuyi 					}
27856ae612beSliuyi 					if (bFirst) {
27866ae612beSliuyi 						if (iTotalWrite >= 1024)
27876ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27886ae612beSliuyi 						else
27896ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
27906ae612beSliuyi 						bFirst = false;
27916ae612beSliuyi 					} else {
27926ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
27936ae612beSliuyi 						CURSOR_DEL_LINE;
27946ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27956ae612beSliuyi 					}
27966ae612beSliuyi 				}
27976ae612beSliuyi 				break;
27986ae612beSliuyi 			case CHUNK_TYPE_FILL:
2799e541b7bbSliuyi 				dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz;
28006ae612beSliuyi 				if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) {
28016ae612beSliuyi 					goto Exit_WriteSparseLBA;
28026ae612beSliuyi 				}
28036ae612beSliuyi 				while (dwChunkDataSize) {
28046ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
28056ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
28066ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
28076ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
28086ae612beSliuyi 					} else {
28096ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
28106ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
28116ae612beSliuyi 					}
28126ae612beSliuyi 					for (i = 0; i < dwTransferBytes / 4; i++) {
28136ae612beSliuyi 						*(DWORD *)(pBuf + i * 4) = dwFillByte;
28146ae612beSliuyi 					}
28156ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
28166ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
28176ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
28186ae612beSliuyi 						iTotalWrite += dwTransferBytes;
28196ae612beSliuyi 						uiBegin += uiTransferSec;
28206ae612beSliuyi 					} else {
28216ae612beSliuyi 						if (g_pLogObject) {
28226ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet);
28236ae612beSliuyi 						}
28246ae612beSliuyi 						goto Exit_WriteSparseLBA;
28256ae612beSliuyi 					}
28266ae612beSliuyi 					if (bFirst) {
28276ae612beSliuyi 						if (iTotalWrite >= 1024)
28286ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28296ae612beSliuyi 						else
28306ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
28316ae612beSliuyi 						bFirst = false;
28326ae612beSliuyi 					} else {
28336ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
28346ae612beSliuyi 						CURSOR_DEL_LINE;
28356ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28366ae612beSliuyi 					}
28376ae612beSliuyi 				}
28386ae612beSliuyi 				break;
28396ae612beSliuyi 			case CHUNK_TYPE_DONT_CARE:
2840e541b7bbSliuyi 				dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz;
28416ae612beSliuyi 				iTotalWrite += dwChunkDataSize;
28426ae612beSliuyi 				uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1));
28436ae612beSliuyi 				uiBegin += uiTransferSec;
28446ae612beSliuyi 				if (bFirst) {
28456ae612beSliuyi 					if (iTotalWrite >= 1024)
28466ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28476ae612beSliuyi 					else
28486ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
28496ae612beSliuyi 					bFirst = false;
28506ae612beSliuyi 				} else {
28516ae612beSliuyi 					CURSOR_MOVEUP_LINE(1);
28526ae612beSliuyi 					CURSOR_DEL_LINE;
28536ae612beSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28546ae612beSliuyi 				}
28556ae612beSliuyi 				break;
28566ae612beSliuyi 			case CHUNK_TYPE_CRC32:
28576ae612beSliuyi 				EatSparseData(file,(PBYTE)&dwCrc,4);
28586ae612beSliuyi 				break;
28596ae612beSliuyi 			}
28606ae612beSliuyi 		}
28616ae612beSliuyi 		bSuccess = true;
28626ae612beSliuyi 	} else {
28636ae612beSliuyi 		printf("Write LBA quit, creating comm object failed!\r\n");
28646ae612beSliuyi 	}
28656ae612beSliuyi Exit_WriteSparseLBA:
28666ae612beSliuyi 	if (pComm) {
28676ae612beSliuyi 		delete pComm;
28686ae612beSliuyi 		pComm = NULL;
28696ae612beSliuyi 	}
28706ae612beSliuyi 	if (file)
28716ae612beSliuyi 		fclose(file);
28726ae612beSliuyi 	return bSuccess;
28736ae612beSliuyi 
28746ae612beSliuyi }
28756ae612beSliuyi 
287676af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
287776af099aSliuyi {
287876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
287976af099aSliuyi 		return false;
288076af099aSliuyi 	CRKUsbComm *pComm = NULL;
288176af099aSliuyi 	FILE *file = NULL;
288276af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
288376af099aSliuyi 	int iRet;
288476af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
288576af099aSliuyi 	UINT iWrite = 0, iRead = 0;
288676af099aSliuyi 	UINT uiLen;
288776af099aSliuyi 	int nSectorSize = 512;
288876af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
288976af099aSliuyi 
28900dcb0a4cSliuyi 
289176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
289276af099aSliuyi 	if (bRet) {
289376af099aSliuyi 		file = fopen(szFile, "rb");
289476af099aSliuyi 		if( !file ) {
289576af099aSliuyi 			printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
289676af099aSliuyi 			goto Exit_WriteLBA;
289776af099aSliuyi 		}
289876af099aSliuyi 
289976af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
290076af099aSliuyi 		iFileSize = ftello(file);
290176af099aSliuyi 		fseeko(file, 0, SEEK_SET);
290276af099aSliuyi 		while(iTotalWrite < iFileSize) {
290376af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
290476af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
290576af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
290676af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
290776af099aSliuyi 			if(ERR_SUCCESS == iRet) {
290876af099aSliuyi 				uiBegin += uiLen;
290976af099aSliuyi 				iTotalWrite += iWrite;
291076af099aSliuyi 				if (bFirst) {
291176af099aSliuyi 					if (iTotalWrite >= 1024)
291276af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
291376af099aSliuyi 					else
291432268622SAndreas Färber 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
291576af099aSliuyi 					bFirst = false;
291676af099aSliuyi 				} else {
291776af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
291876af099aSliuyi 					CURSOR_DEL_LINE;
291976af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
292076af099aSliuyi 				}
292176af099aSliuyi 			} else {
292276af099aSliuyi 				if (g_pLogObject)
292376af099aSliuyi 					g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
292476af099aSliuyi 
292576af099aSliuyi 				printf("Write LBA failed!\r\n");
292676af099aSliuyi 				goto Exit_WriteLBA;
292776af099aSliuyi 			}
292876af099aSliuyi 		}
292976af099aSliuyi 		bSuccess = true;
293076af099aSliuyi 	} else {
293132268622SAndreas Färber 		printf("Write LBA quit, creating comm object failed!\r\n");
293276af099aSliuyi 	}
293376af099aSliuyi Exit_WriteLBA:
293476af099aSliuyi 	if (pComm) {
293576af099aSliuyi 		delete pComm;
293676af099aSliuyi 		pComm = NULL;
293776af099aSliuyi 	}
293876af099aSliuyi 	if (file)
293976af099aSliuyi 		fclose(file);
294076af099aSliuyi 	return bSuccess;
294176af099aSliuyi }
294276af099aSliuyi 
294376af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
294476af099aSliuyi {
294576af099aSliuyi 	string strItem;
294676af099aSliuyi 	char szItem[100];
294776af099aSliuyi 	char *pos = NULL, *pStart;
294876af099aSliuyi 	pStart = pszItems;
294976af099aSliuyi 	pos = strchr(pStart, ',');
295076af099aSliuyi 	while(pos != NULL) {
295102bc7763SChristoph Muellner 		memset(szItem, 0, sizeof(szItem));
295276af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
295376af099aSliuyi 		strItem = szItem;
295476af099aSliuyi 		vecItems.push_back(strItem);
295576af099aSliuyi 		pStart = pos + 1;
295676af099aSliuyi 		if (*pStart == 0)
295776af099aSliuyi 			break;
295876af099aSliuyi 		pos = strchr(pStart, ',');
295976af099aSliuyi 	}
296076af099aSliuyi 	if (strlen(pStart) > 0) {
296102bc7763SChristoph Muellner 		memset(szItem, 0, sizeof(szItem));
296202bc7763SChristoph Muellner 		strncpy(szItem, pStart, sizeof(szItem)-1);
296376af099aSliuyi 		strItem = szItem;
296476af099aSliuyi 		vecItems.push_back(strItem);
296576af099aSliuyi 	}
296676af099aSliuyi }
2967c30d921cSKever Yang 
2968d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
2969d71e8c20SEddie Cai {
2970d71e8c20SEddie Cai 	FILE *file = NULL;
2971d71e8c20SEddie Cai 	int len;
2972d71e8c20SEddie Cai 
2973d71e8c20SEddie Cai 	if(!tag || !spl)
2974d71e8c20SEddie Cai 		return;
2975d71e8c20SEddie Cai 	len = strlen(tag);
2976d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
2977d71e8c20SEddie Cai 	file = fopen(spl, "rb");
2978d71e8c20SEddie Cai 	if( !file ){
2979d71e8c20SEddie Cai 		return;
2980d71e8c20SEddie Cai 	}
2981d71e8c20SEddie Cai 	int iFileSize;
2982d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
2983d71e8c20SEddie Cai 	iFileSize = ftell(file);
2984d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
2985d71e8c20SEddie Cai 	char *Buf = NULL;
2986d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
2987d71e8c20SEddie Cai 	if (!Buf){
2988d71e8c20SEddie Cai 		fclose(file);
2989d71e8c20SEddie Cai 		return;
2990d71e8c20SEddie Cai 	}
2991d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
2992d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
2993d71e8c20SEddie Cai 	int iRead;
2994d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
2995d71e8c20SEddie Cai 	if (iRead != iFileSize){
2996d71e8c20SEddie Cai 		fclose(file);
2997d71e8c20SEddie Cai 		delete []Buf;
2998d71e8c20SEddie Cai 		return;
2999d71e8c20SEddie Cai 	}
3000d71e8c20SEddie Cai 	fclose(file);
3001d71e8c20SEddie Cai 
3002d71e8c20SEddie Cai 	len = strlen(spl);
300332268622SAndreas Färber 	char *taggedspl = new char[len + 5];
300432268622SAndreas Färber 	strcpy(taggedspl, spl);
300532268622SAndreas Färber 	strcpy(taggedspl + len, ".tag");
300632268622SAndreas Färber 	taggedspl[len+4] = 0;
300732268622SAndreas Färber 	printf("Writing tagged spl to %s\n", taggedspl);
3008d71e8c20SEddie Cai 
300932268622SAndreas Färber 	file = fopen(taggedspl, "wb");
3010d71e8c20SEddie Cai 	if( !file ){
301132268622SAndreas Färber 		delete []taggedspl;
3012d71e8c20SEddie Cai 		delete []Buf;
3013d71e8c20SEddie Cai 		return;
3014d71e8c20SEddie Cai 	}
3015d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
3016d71e8c20SEddie Cai 	fclose(file);
301732268622SAndreas Färber 	delete []taggedspl;
3018d71e8c20SEddie Cai 	delete []Buf;
3019d71e8c20SEddie Cai 	printf("done\n");
3020d71e8c20SEddie Cai 	return;
3021d71e8c20SEddie Cai }
3022081d237aSliuyi void list_device(CRKScan *pScan)
3023081d237aSliuyi {
3024081d237aSliuyi 	STRUCT_RKDEVICE_DESC desc;
3025081d237aSliuyi 	string strDevType;
3026081d237aSliuyi 	int i,cnt;
3027081d237aSliuyi 	cnt = pScan->DEVICE_COUNTS;
3028081d237aSliuyi 	if (cnt == 0) {
3029081d237aSliuyi 		printf("not found any devices!\r\n");
3030081d237aSliuyi 		return;
3031081d237aSliuyi 	}
3032081d237aSliuyi 	for (i=0;i<cnt;i++)
3033081d237aSliuyi 	{
3034081d237aSliuyi 		pScan->GetDevice(desc, i);
3035081d237aSliuyi 		if (desc.emUsbType==RKUSB_MASKROM)
3036081d237aSliuyi 			strDevType = "Maskrom";
3037081d237aSliuyi 		else if (desc.emUsbType==RKUSB_LOADER)
3038081d237aSliuyi 			strDevType = "Loader";
3039081d237aSliuyi 		else
3040081d237aSliuyi 			strDevType = "Unknown";
3041081d237aSliuyi 		printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid,
3042081d237aSliuyi 		       desc.usPid,desc.uiLocationID,strDevType.c_str());
3043081d237aSliuyi 	}
3044081d237aSliuyi 
3045081d237aSliuyi }
3046081d237aSliuyi 
3047d71e8c20SEddie Cai 
304876af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
304976af099aSliuyi {
305076af099aSliuyi 	string strCmd;
305176af099aSliuyi 	strCmd = argv[1];
305276af099aSliuyi 	ssize_t cnt;
305376af099aSliuyi 	bool bRet,bSuccess = false;
30548df2d64aSEddie Cai 	char *s;
30558df2d64aSEddie Cai 	int i, ret;
305676af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
3057081d237aSliuyi 	u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE];
30586ae612beSliuyi 	u64 lba, lba_end;
3059081d237aSliuyi 	u32 part_size, part_offset;
306076af099aSliuyi 
306176af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
30628df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
30638df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
30648df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
306578884ef4SEddie Cai 
30668df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
306776af099aSliuyi 		usage();
306876af099aSliuyi 		return true;
30698df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
3070c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
307176af099aSliuyi 		return true;
307278884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
307378884ef4SEddie Cai 		mergeBoot();
307478884ef4SEddie Cai 		return true;
307578884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
307678884ef4SEddie Cai 		string strLoader = argv[2];
307778884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
307878884ef4SEddie Cai 		return true;
3079d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
3080d71e8c20SEddie Cai 		if (argc == 4) {
3081d71e8c20SEddie Cai 			string tag = argv[2];
3082d71e8c20SEddie Cai 			string spl = argv[3];
3083d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
3084d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
3085d71e8c20SEddie Cai 			return true;
3086d71e8c20SEddie Cai 		}
3087d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
3088d71e8c20SEddie Cai 		usage();
308976af099aSliuyi 	}
309076af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
3091081d237aSliuyi 	if(strcmp(strCmd.c_str(), "LD") == 0) {
3092081d237aSliuyi 		list_device(pScan);
30930dcb0a4cSliuyi 		return (cnt>0)?true:false;
3094081d237aSliuyi 	}
3095081d237aSliuyi 
309676af099aSliuyi 	if (cnt < 1) {
309776af099aSliuyi 		ERROR_COLOR_ATTR;
309832268622SAndreas Färber 		printf("Did not find any rockusb device, please plug device in!");
309976af099aSliuyi 		NORMAL_COLOR_ATTR;
310076af099aSliuyi 		printf("\r\n");
310176af099aSliuyi 		return bSuccess;
310276af099aSliuyi 	} else if (cnt > 1) {
310376af099aSliuyi 		ERROR_COLOR_ATTR;
310432268622SAndreas Färber 		printf("Found too many rockusb devices, please plug devices out!");
310576af099aSliuyi 		NORMAL_COLOR_ATTR;
310676af099aSliuyi 		printf("\r\n");
310776af099aSliuyi 		return bSuccess;
310876af099aSliuyi 	}
310976af099aSliuyi 
311076af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
311176af099aSliuyi 	if (!bRet) {
311276af099aSliuyi 		ERROR_COLOR_ATTR;
311332268622SAndreas Färber 		printf("Getting information about rockusb device failed!");
311476af099aSliuyi 		NORMAL_COLOR_ATTR;
311576af099aSliuyi 		printf("\r\n");
311676af099aSliuyi 		return bSuccess;
311776af099aSliuyi 	}
311876af099aSliuyi 
311976af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
312076af099aSliuyi 		if ((argc != 2) && (argc != 3))
312176af099aSliuyi 			printf("Parameter of [RD] command is invalid, please check help!\r\n");
312276af099aSliuyi 		else {
312376af099aSliuyi 			if (argc == 2)
312476af099aSliuyi 				bSuccess = reset_device(dev);
312576af099aSliuyi 			else {
312676af099aSliuyi 				UINT uiSubCode;
312776af099aSliuyi 				char *pszEnd;
312876af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
312976af099aSliuyi 				if (*pszEnd)
313076af099aSliuyi 					printf("Subcode is invalid, please check!\r\n");
313176af099aSliuyi 				else {
313276af099aSliuyi 					if (uiSubCode <= 5)
313376af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
313476af099aSliuyi 					else
313576af099aSliuyi 						printf("Subcode is invalid, please check!\r\n");
313676af099aSliuyi 				}
313776af099aSliuyi 			}
313876af099aSliuyi 		}
313976af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
314076af099aSliuyi 		bSuccess = test_device(dev);
314176af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
314276af099aSliuyi 		bSuccess = read_flash_id(dev);
314376af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
314476af099aSliuyi 		bSuccess = read_flash_info(dev);
314576af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
314676af099aSliuyi 		bSuccess = read_chip_info(dev);
3147081d237aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability
3148081d237aSliuyi 		bSuccess = read_capability(dev);
314976af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
315076af099aSliuyi 		if (argc > 2) {
315176af099aSliuyi 			string strLoader;
315276af099aSliuyi 			strLoader = argv[2];
315376af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
315476af099aSliuyi 		} else if (argc == 2) {
3155c29e5f0fSliuyi 			ret = find_config_item(g_ConfigItemVec, "loader");
315676af099aSliuyi 			if (ret == -1)
315732268622SAndreas Färber 				printf("Did not find loader item in config!\r\n");
315876af099aSliuyi 			else
315976af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
316076af099aSliuyi 		} else
316176af099aSliuyi 			printf("Parameter of [DB] command is invalid, please check help!\r\n");
3162c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
3163c30d921cSKever Yang 		if (argc > 2) {
3164c30d921cSKever Yang 			string strParameter;
3165c30d921cSKever Yang 			strParameter = argv[2];
3166c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
3167c30d921cSKever Yang 		} else
3168c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid, please check help!\r\n");
3169081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PRM") == 0) {
3170081d237aSliuyi 		if (argc > 2) {
3171081d237aSliuyi 			string strParameter;
3172081d237aSliuyi 			strParameter = argv[2];
3173081d237aSliuyi 			bSuccess = write_parameter(dev, (char *)strParameter.c_str());
3174081d237aSliuyi 		} else
3175081d237aSliuyi 			printf("Parameter of [PRM] command is invalid, please check help!\r\n");
3176c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
3177c30d921cSKever Yang 		if (argc > 2) {
3178c30d921cSKever Yang 			string strLoader;
3179c30d921cSKever Yang 			strLoader = argv[2];
3180c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
3181c30d921cSKever Yang 		} else
3182c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid, please check help!\r\n");
318376af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
318476af099aSliuyi 		if (argc == 2) {
318576af099aSliuyi 			bSuccess = erase_flash(dev);
318676af099aSliuyi 		} else
318776af099aSliuyi 			printf("Parameter of [EF] command is invalid, please check help!\r\n");
318876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
318976af099aSliuyi 		if (argc == 4) {
319076af099aSliuyi 			UINT uiBegin;
319176af099aSliuyi 			char *pszEnd;
319276af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
319376af099aSliuyi 			if (*pszEnd)
319476af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
3195ae4252f0Sliuyi 			else {
3196ae4252f0Sliuyi 				if (is_sparse_image(argv[3]))
3197ae4252f0Sliuyi 						bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]);
31980dcb0a4cSliuyi 				else {
31990dcb0a4cSliuyi 					bSuccess = true;
32000dcb0a4cSliuyi 					if (is_ubifs_image(argv[3]))
32010dcb0a4cSliuyi 						bSuccess = erase_ubi_block(dev, (u32)uiBegin, (u32)-1);
32020dcb0a4cSliuyi 					if (bSuccess)
3203ae4252f0Sliuyi 						bSuccess = write_lba(dev, (u32)uiBegin, argv[3]);
32040dcb0a4cSliuyi 					else
32050dcb0a4cSliuyi 						printf("Failure of Erase for writing ubi image!\r\n");
32060dcb0a4cSliuyi 				}
3207ae4252f0Sliuyi 			}
320876af099aSliuyi 		} else
320976af099aSliuyi 			printf("Parameter of [WL] command is invalid, please check help!\r\n");
32106ae612beSliuyi 	} else if(strcmp(strCmd.c_str(), "WLX") == 0) {
32116ae612beSliuyi 		if (argc == 4) {
32126ae612beSliuyi 			bRet = read_gpt(dev, master_gpt);
32136ae612beSliuyi 			if (bRet) {
32146ae612beSliuyi 				bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end);
32156ae612beSliuyi 				if (bRet) {
32166ae612beSliuyi 					if (is_sparse_image(argv[3]))
32176ae612beSliuyi 						bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]);
32180dcb0a4cSliuyi 					else {
32190dcb0a4cSliuyi 						bSuccess = true;
32200dcb0a4cSliuyi 						if (is_ubifs_image(argv[3]))
3221e607a5d6Sliuyi 						{
3222e607a5d6Sliuyi 							if (lba_end == 0xFFFFFFFF)
3223e607a5d6Sliuyi 								bSuccess = erase_ubi_block(dev, (u32)lba, (u32)lba_end);
3224e607a5d6Sliuyi 							else
32250dcb0a4cSliuyi 								bSuccess = erase_ubi_block(dev, (u32)lba, (u32)(lba_end - lba + 1));
3226e607a5d6Sliuyi 						}
32270dcb0a4cSliuyi 						if (bSuccess)
32286ae612beSliuyi 							bSuccess = write_lba(dev, (u32)lba, argv[3]);
32290dcb0a4cSliuyi 						else
32300dcb0a4cSliuyi 							printf("Failure of Erase for writing ubi image!\r\n");
32310dcb0a4cSliuyi 					}
32326ae612beSliuyi 				} else
32336ae612beSliuyi 					printf("No found %s partition\r\n", argv[2]);
3234081d237aSliuyi 			} else {
3235081d237aSliuyi 				bRet = read_param(dev, param_buffer);
3236081d237aSliuyi 				if (bRet) {
3237081d237aSliuyi 					bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size);
3238081d237aSliuyi 					if (bRet) {
3239081d237aSliuyi 						if (is_sparse_image(argv[3]))
3240081d237aSliuyi 							bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]);
32410dcb0a4cSliuyi 						else {
32421e890c4fSliuyi 
32430dcb0a4cSliuyi 							bSuccess = true;
32440dcb0a4cSliuyi 							if (is_ubifs_image(argv[3]))
32450dcb0a4cSliuyi 								bSuccess = erase_ubi_block(dev, part_offset, part_size);
32460dcb0a4cSliuyi 							if (bSuccess)
3247081d237aSliuyi 								bSuccess = write_lba(dev, part_offset, argv[3]);
32480dcb0a4cSliuyi 							else
32490dcb0a4cSliuyi 								printf("Failure of Erase for writing ubi image!\r\n");
32500dcb0a4cSliuyi 						}
3251081d237aSliuyi 					} else
3252081d237aSliuyi 						printf("No found %s partition\r\n", argv[2]);
32536ae612beSliuyi 				}
3254081d237aSliuyi 				else
3255081d237aSliuyi 					printf("Not found any partition table!\r\n");
3256081d237aSliuyi 			}
3257081d237aSliuyi 
32586ae612beSliuyi 		} else
32596ae612beSliuyi 			printf("Parameter of [WLX] command is invalid, please check help!\r\n");
326076af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
326176af099aSliuyi 		char *pszEnd;
326276af099aSliuyi 		UINT uiBegin, uiLen;
326376af099aSliuyi 		if (argc != 5)
326476af099aSliuyi 			printf("Parameter of [RL] command is invalid, please check help!\r\n");
326576af099aSliuyi 		else {
326676af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
326776af099aSliuyi 			if (*pszEnd)
326876af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
326976af099aSliuyi 			else {
327076af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
327176af099aSliuyi 				if (*pszEnd)
327276af099aSliuyi 					printf("Len is invalid, please check!\r\n");
327376af099aSliuyi 				else {
327476af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
327576af099aSliuyi 				}
327676af099aSliuyi 			}
327776af099aSliuyi 		}
3278081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PPT") == 0) {
32793dc7e3ceSliuyi 		if (argc == 2) {
32803dc7e3ceSliuyi 			bSuccess = print_gpt(dev);
3281081d237aSliuyi 			if (!bSuccess) {
3282081d237aSliuyi 				bSuccess = print_parameter(dev);
3283081d237aSliuyi 				if (!bSuccess)
3284081d237aSliuyi 					printf("Not found any partition table!\r\n");
3285081d237aSliuyi 			}
32863dc7e3ceSliuyi 		} else
3287081d237aSliuyi 			printf("Parameter of [PPT] command is invalid, please check help!\r\n");
328876af099aSliuyi 	} else {
32899bc231bdSAndreas Färber 		printf("command is invalid!\r\n");
32909bc231bdSAndreas Färber 		usage();
329176af099aSliuyi 	}
329276af099aSliuyi 	return bSuccess;
329376af099aSliuyi }
329476af099aSliuyi 
329576af099aSliuyi 
329676af099aSliuyi int main(int argc, char* argv[])
329776af099aSliuyi {
329876af099aSliuyi 	CRKScan *pScan = NULL;
329976af099aSliuyi 	int ret;
330076af099aSliuyi 	char szProgramProcPath[100];
330176af099aSliuyi 	char szProgramDir[256];
330276af099aSliuyi 	string strLogDir,strConfigFile;
330376af099aSliuyi 	struct stat statBuf;
330476af099aSliuyi 
330576af099aSliuyi 	g_ConfigItemVec.clear();
330676af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
330776af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
330876af099aSliuyi 		strcpy(szProgramDir, ".");
330976af099aSliuyi 	else {
331076af099aSliuyi 		char *pSlash;
331176af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
331276af099aSliuyi 		if (pSlash)
331376af099aSliuyi 			*pSlash = '\0';
331476af099aSliuyi 	}
331576af099aSliuyi 	strLogDir = szProgramDir;
331676af099aSliuyi 	strLogDir +=  "/log/";
331776af099aSliuyi 	strConfigFile = szProgramDir;
331876af099aSliuyi 	strConfigFile += "/config.ini";
331976af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
332076af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
3321e5ee8cc0Sliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
332276af099aSliuyi 
332376af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
332476af099aSliuyi 		if (g_pLogObject) {
332576af099aSliuyi 			g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
332676af099aSliuyi 		}
332776af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
332876af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
332976af099aSliuyi 	}
333076af099aSliuyi 
333176af099aSliuyi 	ret = libusb_init(NULL);
333276af099aSliuyi 	if (ret < 0) {
333376af099aSliuyi 		if (g_pLogObject) {
333476af099aSliuyi 			g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
333576af099aSliuyi 			delete g_pLogObject;
333676af099aSliuyi 		}
333776af099aSliuyi 		return -1;
333876af099aSliuyi 	}
333976af099aSliuyi 
334076af099aSliuyi 	pScan = new CRKScan();
334176af099aSliuyi 	if (!pScan) {
334276af099aSliuyi 		if (g_pLogObject) {
334332268622SAndreas Färber 			g_pLogObject->Record("Error: failed to create object for searching device");
334476af099aSliuyi 			delete g_pLogObject;
334576af099aSliuyi 		}
334676af099aSliuyi 		libusb_exit(NULL);
334776af099aSliuyi 		return -2;
334876af099aSliuyi 	}
334976af099aSliuyi 	pScan->SetVidPid();
335076af099aSliuyi 
335176af099aSliuyi 	if (argc == 1)
335276af099aSliuyi 		usage();
335376af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
335476af099aSliuyi 			return -0xFF;
335576af099aSliuyi 	if (pScan)
335676af099aSliuyi 		delete pScan;
335776af099aSliuyi 	if (g_pLogObject)
335876af099aSliuyi 		delete g_pLogObject;
335976af099aSliuyi 	libusb_exit(NULL);
336076af099aSliuyi 	return 0;
336176af099aSliuyi }
3362