xref: /rkdeveloptool/main.cpp (revision c29e5f0fb3abaf1286e0478b8fc93c6c4f41dd53)
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");
45154ee062SEddie Cai 	printf("Help:\t\t\t-h or --version\r\n");
46154ee062SEddie Cai 	printf("Version:\t\t-v or --version\r\n");
47154ee062SEddie Cai 	printf("DownloadBoot:\t\tdb <Loader>\r\n");
48154ee062SEddie Cai 	printf("UpgradeLoader:\t\tul <Loader>\r\n");
49154ee062SEddie Cai 	printf("ReadLBA:\t\trl  <BeginSec> <SectorLen> <File>\r\n");
50154ee062SEddie Cai 	printf("WriteLBA:\t\twl  <BeginSec> <File>\r\n");
51154ee062SEddie Cai 	printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
52154ee062SEddie Cai 	printf("EraseFlash:\t\tef \r\n");
53154ee062SEddie Cai 	printf("TestDevice:\t\ttd\r\n");
54154ee062SEddie Cai 	printf("ResetDevice:\t\trd [subcode]\r\n");
55154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
56154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
57154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
5878884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
5978884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
60d71e8c20SEddie Cai 	printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
6176af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6276af099aSliuyi }
6376af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6476af099aSliuyi {
6576af099aSliuyi 	string strInfoText="";
6676af099aSliuyi 	char szText[256];
6776af099aSliuyi 	switch (promptID) {
6876af099aSliuyi 	case TESTDEVICE_PROGRESS:
6932268622SAndreas Färber 		sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue);
7076af099aSliuyi 		strInfoText = szText;
7176af099aSliuyi 		break;
7276af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7332268622SAndreas Färber 		sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue);
7476af099aSliuyi 		strInfoText = szText;
7576af099aSliuyi 		break;
7676af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
7732268622SAndreas Färber 		sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
7876af099aSliuyi 		strInfoText = szText;
7976af099aSliuyi 		break;
8076af099aSliuyi 	case CHECKIMAGE_PROGRESS:
8132268622SAndreas Färber 		sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8276af099aSliuyi 		strInfoText = szText;
8376af099aSliuyi 		break;
8476af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
8532268622SAndreas Färber 		sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue);
8676af099aSliuyi 		strInfoText = szText;
8776af099aSliuyi 		break;
8876af099aSliuyi 	case TESTBLOCK_PROGRESS:
8932268622SAndreas Färber 		sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue);
9076af099aSliuyi 		strInfoText = szText;
9176af099aSliuyi 		break;
9276af099aSliuyi 	case ERASEFLASH_PROGRESS:
9332268622SAndreas Färber 		sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue);
9476af099aSliuyi 		strInfoText = szText;
9576af099aSliuyi 		break;
9676af099aSliuyi 	case ERASESYSTEM_PROGRESS:
9732268622SAndreas Färber 		sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue);
9876af099aSliuyi 		strInfoText = szText;
9976af099aSliuyi 		break;
10076af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
10132268622SAndreas Färber 		sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue);
10276af099aSliuyi 		strInfoText = szText;
10376af099aSliuyi 		break;
10476af099aSliuyi 	}
10576af099aSliuyi 	if (strInfoText.size() > 0){
10676af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
10776af099aSliuyi 		CURSOR_DEL_LINE;
10876af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
10976af099aSliuyi 	}
11076af099aSliuyi 	if (emCall == CALL_LAST)
11176af099aSliuyi 		deviceLayer = 0;
11276af099aSliuyi }
11376af099aSliuyi 
11476af099aSliuyi char *strupr(char *szSrc)
11576af099aSliuyi {
11676af099aSliuyi 	char *p = szSrc;
11776af099aSliuyi 	while(*p){
11876af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
11976af099aSliuyi 			*p = *p - 'a' + 'A';
12076af099aSliuyi 		p++;
12176af099aSliuyi 	}
12276af099aSliuyi 	return szSrc;
12376af099aSliuyi }
12476af099aSliuyi void PrintData(PBYTE pData, int nSize)
12576af099aSliuyi {
12676af099aSliuyi 	char szPrint[17] = "\0";
12776af099aSliuyi 	int i;
12876af099aSliuyi 	for( i = 0; i < nSize; i++){
12976af099aSliuyi 		if(i % 16 == 0){
13076af099aSliuyi 			if(i / 16 > 0)
13176af099aSliuyi 				printf("     %s\r\n", szPrint);
13276af099aSliuyi 			printf("%08d ", i / 16);
13376af099aSliuyi 		}
13476af099aSliuyi 		printf("%02X ", pData[i]);
13576af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
13676af099aSliuyi 	}
13776af099aSliuyi 	if(i / 16 > 0)
13876af099aSliuyi 		printf("     %s\r\n", szPrint);
13976af099aSliuyi }
14076af099aSliuyi 
14176af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
14276af099aSliuyi {
14376af099aSliuyi 	if (!pszSrc)
14476af099aSliuyi 		return false;
14576af099aSliuyi 	int nSrcLen = strlen(pszSrc);
14676af099aSliuyi 	int nDestLen = nSrcLen * 2;
14776af099aSliuyi 
14876af099aSliuyi 	pszDest = NULL;
14976af099aSliuyi 	pszDest = new wchar_t[nDestLen];
15076af099aSliuyi 	if (!pszDest)
15176af099aSliuyi 		return false;
15276af099aSliuyi 	nDestLen = nDestLen * sizeof(wchar_t);
15376af099aSliuyi 	memset(pszDest, 0, nDestLen);
15476af099aSliuyi 	int iRet;
15576af099aSliuyi 	iconv_t cd;
15676af099aSliuyi 	cd = iconv_open("UTF-32", "UTF-8");
15776af099aSliuyi 	if((iconv_t)-1 == cd) {
15876af099aSliuyi 		delete []pszDest;
15976af099aSliuyi 		pszDest = NULL;
16076af099aSliuyi 	      return false;
16176af099aSliuyi 	 }
16276af099aSliuyi 	char *pIn, *pOut;
16376af099aSliuyi 	pIn = (char *)pszSrc;
16476af099aSliuyi 	pOut = (char *)pszDest;
16576af099aSliuyi 
16676af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
16776af099aSliuyi 
16876af099aSliuyi 	if(iRet == -1) {
16976af099aSliuyi 		delete []pszDest;
17076af099aSliuyi 		pszDest = NULL;
17176af099aSliuyi 		iconv_close(cd);
17276af099aSliuyi 		return false;
17376af099aSliuyi 	 }
17476af099aSliuyi 
17576af099aSliuyi 	 iconv_close(cd);
17676af099aSliuyi 
17776af099aSliuyi 	 return true;
17876af099aSliuyi }
17976af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
18076af099aSliuyi {
18176af099aSliuyi 	if (!pszSrc)
18276af099aSliuyi 		return false;
18376af099aSliuyi 	int nSrcLen = wcslen(pszSrc);
18476af099aSliuyi 	int nDestLen = nSrcLen * 2;
18576af099aSliuyi 	nSrcLen = nSrcLen * sizeof(wchar_t);
18676af099aSliuyi 	pszDest = NULL;
18776af099aSliuyi 	pszDest = new char[nDestLen];
18876af099aSliuyi 	if (!pszDest)
18976af099aSliuyi 		return false;
19076af099aSliuyi 	memset(pszDest, 0, nDestLen);
19176af099aSliuyi 	int iRet;
19276af099aSliuyi 	iconv_t cd;
19376af099aSliuyi 	cd = iconv_open("UTF-8", "UTF-32");
19476af099aSliuyi 
19576af099aSliuyi 	if((iconv_t)-1 == cd) {
19676af099aSliuyi 		delete []pszDest;
19776af099aSliuyi 		pszDest = NULL;
19876af099aSliuyi 	      return false;
19976af099aSliuyi 	 }
20076af099aSliuyi 	char *pIn, *pOut;
20176af099aSliuyi 	pIn = (char *)pszSrc;
20276af099aSliuyi 	pOut = (char *)pszDest;
20376af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
20476af099aSliuyi 
20576af099aSliuyi 	if(iRet == -1) {
20676af099aSliuyi 		delete []pszDest;
20776af099aSliuyi 		pszDest = NULL;
20876af099aSliuyi 		iconv_close(cd);
20976af099aSliuyi 		return false;
21076af099aSliuyi 	 }
21176af099aSliuyi 
21276af099aSliuyi 	 iconv_close(cd);
21376af099aSliuyi 
21476af099aSliuyi 	 return true;
21576af099aSliuyi }
216*c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName)
21776af099aSliuyi {
21876af099aSliuyi 	unsigned int i;
219*c29e5f0fSliuyi 	for(i = 0; i < vecItems.size(); i++){
220*c29e5f0fSliuyi 		if (strcasecmp(pszName, vecItems[i].szItemName) == 0){
22176af099aSliuyi 			return i;
22276af099aSliuyi 		}
22376af099aSliuyi 	}
22476af099aSliuyi 	return -1;
22576af099aSliuyi }
226*c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid)
227*c29e5f0fSliuyi {
228*c29e5f0fSliuyi 	unsigned int i;
229*c29e5f0fSliuyi 	char value;
230*c29e5f0fSliuyi 	memset(uuid, 0, 16);
231*c29e5f0fSliuyi 	for (i =0; i < strUUid.size(); i++) {
232*c29e5f0fSliuyi 		value = 0;
233*c29e5f0fSliuyi 		if ((strUUid[i] >= '0')&&(strUUid[i] <= '9'))
234*c29e5f0fSliuyi 			value = strUUid[i] - '0';
235*c29e5f0fSliuyi 		if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f'))
236*c29e5f0fSliuyi 			value = strUUid[i] - 'a' + 10;
237*c29e5f0fSliuyi 		if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F'))
238*c29e5f0fSliuyi 			value = strUUid[i] - 'A' + 10;
239*c29e5f0fSliuyi 		if ((i % 2) == 0)
240*c29e5f0fSliuyi 			uuid[i / 2] += (value << 4);
241*c29e5f0fSliuyi 		else
242*c29e5f0fSliuyi 			uuid[i / 2] += value;
243*c29e5f0fSliuyi 	}
244*c29e5f0fSliuyi 	unsigned int *p32;
245*c29e5f0fSliuyi 	unsigned short *p16;
246*c29e5f0fSliuyi 	p32 = (unsigned int*)uuid;
247*c29e5f0fSliuyi 	*p32 = cpu_to_be32(*p32);
248*c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 4);
249*c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
250*c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 6);
251*c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
252*c29e5f0fSliuyi }
25376af099aSliuyi 
25476af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
25576af099aSliuyi {
25676af099aSliuyi 
25776af099aSliuyi 	stringstream configStream(pConfig);
25876af099aSliuyi 	string strLine, strItemName, strItemValue;
25976af099aSliuyi 	string::size_type line_size,pos;
26076af099aSliuyi 	STRUCT_CONFIG_ITEM item;
26176af099aSliuyi 	vecItem.clear();
26276af099aSliuyi 	while (!configStream.eof()){
26376af099aSliuyi 		getline(configStream, strLine);
26476af099aSliuyi 		line_size = strLine.size();
26576af099aSliuyi 		if (line_size == 0)
26676af099aSliuyi 			continue;
26776af099aSliuyi 		if (strLine[line_size-1] == '\r'){
26876af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
26976af099aSliuyi 		}
270c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
271c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
272c30d921cSKever Yang 		if (strLine.size()==0 )
273c30d921cSKever Yang 			continue;
274c30d921cSKever Yang 		if (strLine[0] == '#')
275c30d921cSKever Yang 			continue;
27676af099aSliuyi 		pos = strLine.find("=");
27776af099aSliuyi 		if (pos == string::npos){
27876af099aSliuyi 			continue;
27976af099aSliuyi 		}
28076af099aSliuyi 		strItemName = strLine.substr(0, pos);
28176af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
28276af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
28376af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
28476af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
28576af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
28676af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
28776af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
28876af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
28976af099aSliuyi 			vecItem.push_back(item);
29076af099aSliuyi 		}
29176af099aSliuyi 	}
29276af099aSliuyi 	return true;
29376af099aSliuyi 
29476af099aSliuyi }
29576af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
29676af099aSliuyi {
29776af099aSliuyi 	FILE *file = NULL;
29876af099aSliuyi 	file = fopen(pConfigFile, "rb");
29976af099aSliuyi 	if( !file ){
30076af099aSliuyi 		if (g_pLogObject)
30132268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile);
30276af099aSliuyi 		return false;
30376af099aSliuyi 	}
30476af099aSliuyi 	int iFileSize;
30576af099aSliuyi 	fseek(file, 0, SEEK_END);
30676af099aSliuyi 	iFileSize = ftell(file);
30776af099aSliuyi 	fseek(file, 0, SEEK_SET);
30876af099aSliuyi 	char *pConfigBuf = NULL;
30976af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
31076af099aSliuyi 	if (!pConfigBuf){
31176af099aSliuyi 		fclose(file);
31276af099aSliuyi 		return false;
31376af099aSliuyi 	}
31476af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
31576af099aSliuyi 	int iRead;
31676af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
31776af099aSliuyi 	if (iRead != iFileSize){
31876af099aSliuyi 		if (g_pLogObject)
31932268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize);
32076af099aSliuyi 		fclose(file);
32176af099aSliuyi 		delete []pConfigBuf;
32276af099aSliuyi 		return false;
32376af099aSliuyi 	}
32476af099aSliuyi 	fclose(file);
32576af099aSliuyi 	bool bRet;
32676af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
32776af099aSliuyi 	delete []pConfigBuf;
32876af099aSliuyi 	return bRet;
32976af099aSliuyi }
330c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
331c30d921cSKever Yang {
332c30d921cSKever Yang 	string::size_type pos,prevPos;
333c30d921cSKever Yang 	string strOffset,strLen;
334c30d921cSKever Yang 	int iCount;
335c30d921cSKever Yang 	prevPos = pos = 0;
336c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
337c30d921cSKever Yang 		return false;
338c30d921cSKever Yang 	}
339c30d921cSKever Yang 	pos = strPartInfo.find('@');
340c30d921cSKever Yang 	if (pos == string::npos) {
341c30d921cSKever Yang 		return false;
342c30d921cSKever Yang 	}
343c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
344c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
345c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
346c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
347c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
348c30d921cSKever Yang 	} else {
349c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
350c30d921cSKever Yang 		if (iCount != 1) {
351c30d921cSKever Yang 			return false;
352c30d921cSKever Yang 		}
353c30d921cSKever Yang 	}
354c30d921cSKever Yang 
355c30d921cSKever Yang 	prevPos = pos + 1;
356c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
357c30d921cSKever Yang 	if (pos == string::npos) {
358c30d921cSKever Yang 		return false;
359c30d921cSKever Yang 	}
360c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
361c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
362c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
363c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
364c30d921cSKever Yang 	if (iCount != 1) {
365c30d921cSKever Yang 		return false;
366c30d921cSKever Yang 	}
367c30d921cSKever Yang 	prevPos = pos + 1;
368c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
369c30d921cSKever Yang 	if (pos == string::npos) {
370c30d921cSKever Yang 		return false;
371c30d921cSKever Yang 	}
372c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
373c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
374c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
375c30d921cSKever Yang 
376c30d921cSKever Yang 	return true;
377c30d921cSKever Yang }
378*c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid)
379*c29e5f0fSliuyi {
380*c29e5f0fSliuyi 	string::size_type pos(0);
381c30d921cSKever Yang 
382*c29e5f0fSliuyi 	if (strUuidInfo.size() <= 0) {
383*c29e5f0fSliuyi 		return false;
384*c29e5f0fSliuyi 	}
385*c29e5f0fSliuyi 	pos = strUuidInfo.find('=');
386*c29e5f0fSliuyi 	if (pos == string::npos) {
387*c29e5f0fSliuyi 		return false;
388*c29e5f0fSliuyi 	}
389*c29e5f0fSliuyi 	strName = strUuidInfo.substr(0, pos);
390*c29e5f0fSliuyi 	strName.erase(0, strName.find_first_not_of(" "));
391*c29e5f0fSliuyi 	strName.erase(strName.find_last_not_of(" ") + 1);
392*c29e5f0fSliuyi 
393*c29e5f0fSliuyi 	strUUid = strUuidInfo.substr(pos+1);
394*c29e5f0fSliuyi 	strUUid.erase(0, strUUid.find_first_not_of(" "));
395*c29e5f0fSliuyi 	strUUid.erase(strUUid.find_last_not_of(" ") + 1);
396*c29e5f0fSliuyi 
397*c29e5f0fSliuyi 	while(true) {
398*c29e5f0fSliuyi 		pos = 0;
399*c29e5f0fSliuyi 		if( (pos = strUUid.find("-")) != string::npos)
400*c29e5f0fSliuyi 			strUUid.replace(pos,1,"");
401*c29e5f0fSliuyi 		else
402*c29e5f0fSliuyi 			break;
403*c29e5f0fSliuyi 	}
404*c29e5f0fSliuyi 	if (strUUid.size() != 32)
405*c29e5f0fSliuyi 		return false;
406*c29e5f0fSliuyi 	return true;
407*c29e5f0fSliuyi }
408*c29e5f0fSliuyi 
409*c29e5f0fSliuyi 
410*c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
411c30d921cSKever Yang {
412c30d921cSKever Yang 	stringstream paramStream(pParameter);
413c30d921cSKever Yang 	bool bRet,bFind = false;
414*c29e5f0fSliuyi 	string strLine, strPartition, strPartInfo, strPartName, strUUid;
415c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
416c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
417c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
418*c29e5f0fSliuyi 	STRUCT_CONFIG_ITEM uuid_item;
419c30d921cSKever Yang 	vecItem.clear();
420*c29e5f0fSliuyi 	vecUuidItem.clear();
421c30d921cSKever Yang 	while (!paramStream.eof()) {
422c30d921cSKever Yang 		getline(paramStream,strLine);
423c30d921cSKever Yang 		line_size = strLine.size();
424c30d921cSKever Yang 		if (line_size == 0)
425c30d921cSKever Yang 			continue;
426c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
427c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
428c30d921cSKever Yang 		}
429c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
430c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
431c30d921cSKever Yang 		if (strLine.size()==0 )
432c30d921cSKever Yang 			continue;
433c30d921cSKever Yang 		if (strLine[0] == '#')
434c30d921cSKever Yang 			continue;
435*c29e5f0fSliuyi 		pos = strLine.find("uuid:");
436*c29e5f0fSliuyi 		if (pos != string::npos) {
437*c29e5f0fSliuyi 			strPartInfo = strLine.substr(pos+5);
438*c29e5f0fSliuyi 			bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid);
439*c29e5f0fSliuyi 			if (bRet) {
440*c29e5f0fSliuyi 				strcpy(uuid_item.szItemName, strPartName.c_str());
441*c29e5f0fSliuyi 				string_to_uuid(strUUid,uuid_item.szItemValue);
442*c29e5f0fSliuyi 				vecUuidItem.push_back(uuid_item);
443*c29e5f0fSliuyi 			}
444*c29e5f0fSliuyi 			continue;
445*c29e5f0fSliuyi 		}
446*c29e5f0fSliuyi 
447c30d921cSKever Yang 		pos = strLine.find("mtdparts");
448c30d921cSKever Yang 		if (pos == string::npos) {
449c30d921cSKever Yang 			continue;
450c30d921cSKever Yang 		}
451c30d921cSKever Yang 		bFind = true;
452c30d921cSKever Yang 		posColon = strLine.find(':', pos);
453c30d921cSKever Yang 		if (posColon == string::npos) {
454c30d921cSKever Yang 			continue;
455c30d921cSKever Yang 		}
456c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
457c30d921cSKever Yang 		pos = 0;
458c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
459c30d921cSKever Yang 		while (posComma != string::npos) {
460c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
461c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
462c30d921cSKever Yang 			if (bRet) {
463c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
464c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
465c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
466c30d921cSKever Yang 				vecItem.push_back(item);
467c30d921cSKever Yang 			}
468c30d921cSKever Yang 			pos = posComma + 1;
469c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
470c30d921cSKever Yang 		}
471c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
472c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
473c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
474c30d921cSKever Yang 			if (bRet) {
475c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
476c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
477c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
478c30d921cSKever Yang 				vecItem.push_back(item);
479c30d921cSKever Yang 			}
480c30d921cSKever Yang 		}
481c30d921cSKever Yang 		break;
482c30d921cSKever Yang 	}
483c30d921cSKever Yang 	return bFind;
484c30d921cSKever Yang 
485c30d921cSKever Yang }
486*c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
487c30d921cSKever Yang {
488c30d921cSKever Yang 	FILE *file = NULL;
489c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
490c30d921cSKever Yang 	if( !file ) {
491c30d921cSKever Yang 		if (g_pLogObject)
49232268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
493c30d921cSKever Yang 		return false;
494c30d921cSKever Yang 	}
495c30d921cSKever Yang 	int iFileSize;
496c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
497c30d921cSKever Yang 	iFileSize = ftell(file);
498c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
499c30d921cSKever Yang 	char *pParamBuf = NULL;
500c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
501c30d921cSKever Yang 	if (!pParamBuf) {
502c30d921cSKever Yang 		fclose(file);
503c30d921cSKever Yang 		return false;
504c30d921cSKever Yang 	}
505c30d921cSKever Yang 	int iRead;
506c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
507c30d921cSKever Yang 	if (iRead != iFileSize) {
508c30d921cSKever Yang 		if (g_pLogObject)
50932268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
510c30d921cSKever Yang 		fclose(file);
511c30d921cSKever Yang 		delete []pParamBuf;
512c30d921cSKever Yang 		return false;
513c30d921cSKever Yang 	}
514c30d921cSKever Yang 	fclose(file);
515c30d921cSKever Yang 	bool bRet;
516*c29e5f0fSliuyi 	bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem);
517c30d921cSKever Yang 	delete []pParamBuf;
518c30d921cSKever Yang 	return bRet;
519c30d921cSKever Yang }
520c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
521c30d921cSKever Yang {
522c30d921cSKever Yang 	efi_guid_t id;
523c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
524c30d921cSKever Yang 	unsigned int i;
525c30d921cSKever Yang 
526c30d921cSKever Yang 	/* Set all fields randomly */
527c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
528c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
529c30d921cSKever Yang 
530c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
531c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
532c30d921cSKever Yang 
533c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
534c30d921cSKever Yang }
535c30d921cSKever Yang 
536*c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup)
537*c29e5f0fSliuyi {
538*c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
539*c29e5f0fSliuyi 	gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
540*c29e5f0fSliuyi 	u32 calc_crc32;
541*c29e5f0fSliuyi 	u64 val;
542*c29e5f0fSliuyi 
543*c29e5f0fSliuyi 	/* recalculate the values for the Backup GPT Header */
544*c29e5f0fSliuyi 	val = le64_to_cpu(gptMasterHead->my_lba);
545*c29e5f0fSliuyi 	gptBackupHead->my_lba = gptMasterHead->alternate_lba;
546*c29e5f0fSliuyi 	gptBackupHead->alternate_lba = cpu_to_le64(val);
547*c29e5f0fSliuyi 	gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
548*c29e5f0fSliuyi 	gptBackupHead->header_crc32 = 0;
549*c29e5f0fSliuyi 
550*c29e5f0fSliuyi 	calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
551*c29e5f0fSliuyi 	gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
552*c29e5f0fSliuyi }
553*c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector)
554*c29e5f0fSliuyi {
555*c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
556*c29e5f0fSliuyi 	gpt_entry  *gptLastPartEntry  = NULL;
557*c29e5f0fSliuyi 	u32 i;
558*c29e5f0fSliuyi 	u64 old_disksize;
559*c29e5f0fSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
560*c29e5f0fSliuyi 
561*c29e5f0fSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
562*c29e5f0fSliuyi 	old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1;
563*c29e5f0fSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
564*c29e5f0fSliuyi 		gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
565*c29e5f0fSliuyi 		if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0)
566*c29e5f0fSliuyi 			break;
567*c29e5f0fSliuyi 	}
568*c29e5f0fSliuyi 	i--;
569*c29e5f0fSliuyi 	gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry));
570*c29e5f0fSliuyi 
571*c29e5f0fSliuyi 	gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1);
572*c29e5f0fSliuyi 	gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34);
573*c29e5f0fSliuyi 
574*c29e5f0fSliuyi 	if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition
575*c29e5f0fSliuyi 		gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34);
576*c29e5f0fSliuyi 		gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
577*c29e5f0fSliuyi 	}
578*c29e5f0fSliuyi 	gptMasterHead->header_crc32 = 0;
579*c29e5f0fSliuyi 	gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header)));
580*c29e5f0fSliuyi 	memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS);
581*c29e5f0fSliuyi 	memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE);
582*c29e5f0fSliuyi 	prepare_gpt_backup(master, backup);
583*c29e5f0fSliuyi 
584*c29e5f0fSliuyi }
585*c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup)
586*c29e5f0fSliuyi {
587*c29e5f0fSliuyi 	FILE *file = NULL;
588*c29e5f0fSliuyi 	file = fopen(pParamFile, "rb");
589*c29e5f0fSliuyi 	if( !file ) {
590*c29e5f0fSliuyi 		if (g_pLogObject)
591*c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
592*c29e5f0fSliuyi 		return false;
593*c29e5f0fSliuyi 	}
594*c29e5f0fSliuyi 	int iFileSize;
595*c29e5f0fSliuyi 	fseek(file, 0, SEEK_END);
596*c29e5f0fSliuyi 	iFileSize = ftell(file);
597*c29e5f0fSliuyi 	fseek(file, 0, SEEK_SET);
598*c29e5f0fSliuyi 	if (iFileSize != 67 * SECTOR_SIZE) {
599*c29e5f0fSliuyi 		if (g_pLogObject)
600*c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile);
601*c29e5f0fSliuyi 		fclose(file);
602*c29e5f0fSliuyi 		return false;
603*c29e5f0fSliuyi 	}
604*c29e5f0fSliuyi 
605*c29e5f0fSliuyi 	int iRead;
606*c29e5f0fSliuyi 	iRead = fread(master, 1, 34 * SECTOR_SIZE, file);
607*c29e5f0fSliuyi 	if (iRead != 34 * SECTOR_SIZE) {
608*c29e5f0fSliuyi 		if (g_pLogObject)
609*c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE);
610*c29e5f0fSliuyi 		fclose(file);
611*c29e5f0fSliuyi 		return false;
612*c29e5f0fSliuyi 	}
613*c29e5f0fSliuyi 	iRead = fread(backup, 1, 33 * SECTOR_SIZE, file);
614*c29e5f0fSliuyi 	if (iRead != 33 * SECTOR_SIZE) {
615*c29e5f0fSliuyi 		if (g_pLogObject)
616*c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE);
617*c29e5f0fSliuyi 		fclose(file);
618*c29e5f0fSliuyi 		return false;
619*c29e5f0fSliuyi 	}
620*c29e5f0fSliuyi 	fclose(file);
621*c29e5f0fSliuyi 	return true;
622*c29e5f0fSliuyi }
623*c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
624c30d921cSKever Yang {
625c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
626c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
627c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
628c30d921cSKever Yang 	u32 i,j;
629*c29e5f0fSliuyi 	int pos;
630c30d921cSKever Yang 	string strPartName;
631c30d921cSKever Yang 	string::size_type colonPos;
632c30d921cSKever Yang 	/*1.protective mbr*/
633c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
634c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
635c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
636c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
637c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
638c30d921cSKever Yang 	/*2.gpt header*/
639c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
640c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
641c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
642c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
643c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
644c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
645c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
646c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
647c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
648c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
649c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
650c30d921cSKever Yang 	gptHead->header_crc32 = 0;
651c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
652c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
653c30d921cSKever Yang 
654c30d921cSKever Yang 	/*3.gpt partition entry*/
655c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
656c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
657c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
658c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
659c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
660c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
661c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
662c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
663c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
664c30d921cSKever Yang 		if (colonPos != string::npos) {
665c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
666c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
667*c29e5f0fSliuyi 			if (strPartName.find("grow") != string::npos)
668*c29e5f0fSliuyi 				gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
669c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
670c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
671c30d921cSKever Yang 		}
672c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
673c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
674*c29e5f0fSliuyi 		if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1)
675*c29e5f0fSliuyi 			memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
676c30d921cSKever Yang 		gptEntry++;
677c30d921cSKever Yang 	}
678c30d921cSKever Yang 
679c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
680c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
681c30d921cSKever Yang 
682c30d921cSKever Yang }
683b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
684c30d921cSKever Yang {
685c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
686c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
687c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
688c30d921cSKever Yang 
689c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
690b38fe5fcSliuyi 	pSec0->uiRc4Flag = rc4Flag;
691c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
692c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
693c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
694c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
695c30d921cSKever Yang 	return true;
696c30d921cSKever Yang }
697c30d921cSKever Yang 
698c30d921cSKever Yang 
699c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
700c30d921cSKever Yang {
701c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
702c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
703c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
704c30d921cSKever Yang 
705c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
706c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
707c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
708c30d921cSKever Yang 	return true;
709c30d921cSKever Yang }
710c30d921cSKever Yang 
711c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
712c30d921cSKever Yang {
713c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
714c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
715c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
716c30d921cSKever Yang 
717c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
718c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
719c30d921cSKever Yang 	return true;
720c30d921cSKever Yang }
721c30d921cSKever Yang 
722c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
723c30d921cSKever Yang {
724c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
725c30d921cSKever Yang 	return true;
726c30d921cSKever Yang }
727c30d921cSKever Yang 
728b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
729c30d921cSKever Yang {
730c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
731c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
732c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
733c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
734c30d921cSKever Yang 	UINT i;
735b38fe5fcSliuyi 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
736c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
737c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
738c30d921cSKever Yang 		return -6;
739c30d921cSKever Yang 	}
740c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
741c30d921cSKever Yang 		return -7;
742c30d921cSKever Yang 	}
743c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
744c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
745c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
746c30d921cSKever Yang 
747c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
748c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
749c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
750b38fe5fcSliuyi 
751b38fe5fcSliuyi 	if (rc4Flag) {
752b38fe5fcSliuyi 		for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
753b38fe5fcSliuyi 			P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
754b38fe5fcSliuyi 		for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
755b38fe5fcSliuyi 			P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
756b38fe5fcSliuyi 	}
757b38fe5fcSliuyi 
758c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
759c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
760c30d921cSKever Yang 
761c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
762c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
763c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
764c30d921cSKever Yang 		if(i == 1) {
765c30d921cSKever Yang 			continue;
766c30d921cSKever Yang 		} else {
767c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
768c30d921cSKever Yang 		}
769c30d921cSKever Yang 	}
770c30d921cSKever Yang 	return 0;
771c30d921cSKever Yang }
772c30d921cSKever Yang 
773c30d921cSKever Yang 
77476af099aSliuyi 
77576af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
77676af099aSliuyi {
77776af099aSliuyi 	if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
77876af099aSliuyi 		return true;
77976af099aSliuyi 	else
78076af099aSliuyi 	{
78176af099aSliuyi 		ERROR_COLOR_ATTR;
78232268622SAndreas Färber 		printf("The device does not support this operation!");
78376af099aSliuyi 		NORMAL_COLOR_ATTR;
78476af099aSliuyi 		printf("\r\n");
78576af099aSliuyi 		return false;
78676af099aSliuyi 	}
78776af099aSliuyi }
788c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
789c30d921cSKever Yang {
790c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
791c30d921cSKever Yang 	u32 total_size_sector;
792c30d921cSKever Yang 	CRKComm *pComm = NULL;
793c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
794*c29e5f0fSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
795c30d921cSKever Yang 	int iRet;
796c30d921cSKever Yang 	bool bRet, bSuccess = false;
797c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
798c30d921cSKever Yang 		return false;
799c30d921cSKever Yang 
800c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
801c30d921cSKever Yang 	if (!bRet) {
802c30d921cSKever Yang 		ERROR_COLOR_ATTR;
803c30d921cSKever Yang 		printf("Creating Comm Object failed!");
804c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
805c30d921cSKever Yang 		printf("\r\n");
806c30d921cSKever Yang 		return bSuccess;
807c30d921cSKever Yang 	}
80832268622SAndreas Färber 	printf("Writing gpt...\r\n");
809c30d921cSKever Yang 	//1.get flash info
810c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
811c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
812c30d921cSKever Yang 		ERROR_COLOR_ATTR;
813c30d921cSKever Yang 		printf("Reading Flash Info failed!");
814c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
815c30d921cSKever Yang 		printf("\r\n");
816c30d921cSKever Yang 		return bSuccess;
817c30d921cSKever Yang 	}
818c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
819*c29e5f0fSliuyi 	if (strstr(szParameter, ".img")) {
820*c29e5f0fSliuyi 		if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) {
821*c29e5f0fSliuyi 			ERROR_COLOR_ATTR;
822*c29e5f0fSliuyi 			printf("Loading partition image failed!");
823*c29e5f0fSliuyi 			NORMAL_COLOR_ATTR;
824*c29e5f0fSliuyi 			printf("\r\n");
825*c29e5f0fSliuyi 			return bSuccess;
826*c29e5f0fSliuyi 		}
827*c29e5f0fSliuyi 		update_gpt_disksize(master_gpt, backup_gpt, total_size_sector);
828*c29e5f0fSliuyi 	} else {
829c30d921cSKever Yang 		//2.get partition from parameter
830*c29e5f0fSliuyi 		bRet = parse_parameter_file(szParameter, vecItems, vecUuid);
831c30d921cSKever Yang 		if (!bRet) {
832c30d921cSKever Yang 			ERROR_COLOR_ATTR;
833c30d921cSKever Yang 			printf("Parsing parameter failed!");
834c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
835c30d921cSKever Yang 			printf("\r\n");
836c30d921cSKever Yang 			return bSuccess;
837c30d921cSKever Yang 		}
838*c29e5f0fSliuyi 		vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33;
839c30d921cSKever Yang 		//3.generate gpt info
840*c29e5f0fSliuyi 		create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector);
841c30d921cSKever Yang 		memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
842c30d921cSKever Yang 		memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
843*c29e5f0fSliuyi 		prepare_gpt_backup(master_gpt, backup_gpt);
844*c29e5f0fSliuyi 	}
845*c29e5f0fSliuyi 
846c30d921cSKever Yang 	//4. write gpt
847c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
848c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
849c30d921cSKever Yang 		ERROR_COLOR_ATTR;
850c30d921cSKever Yang 		printf("Writing master gpt failed!");
851c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
852c30d921cSKever Yang 		printf("\r\n");
853c30d921cSKever Yang 		return bSuccess;
854c30d921cSKever Yang 	}
855*c29e5f0fSliuyi 	iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt);
856c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
857c30d921cSKever Yang 		ERROR_COLOR_ATTR;
858c30d921cSKever Yang 		printf("Writing backup gpt failed!");
859c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
860c30d921cSKever Yang 		printf("\r\n");
861c30d921cSKever Yang 		return bSuccess;
862c30d921cSKever Yang 	}
863*c29e5f0fSliuyi 
864c30d921cSKever Yang 	bSuccess = true;
865c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
866c30d921cSKever Yang 	CURSOR_DEL_LINE;
86732268622SAndreas Färber 	printf("Writing gpt succeeded.\r\n");
868c30d921cSKever Yang 	return bSuccess;
869c30d921cSKever Yang }
87076af099aSliuyi 
87178884ef4SEddie Cai #include "boot_merger.h"
87278884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
87378884ef4SEddie Cai options gOpts;
87478884ef4SEddie Cai 
87578884ef4SEddie Cai 
87678884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
87778884ef4SEddie Cai char* gConfigPath;
87878884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
87978884ef4SEddie Cai 
88078884ef4SEddie Cai static inline void fixPath(char* path) {
88178884ef4SEddie Cai 	int i, len = strlen(path);
88278884ef4SEddie Cai 	for(i=0; i<len; i++) {
88378884ef4SEddie Cai 		if (path[i] == '\\')
88478884ef4SEddie Cai 			path[i] = '/';
88578884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
88678884ef4SEddie Cai 			path[i] = '\0';
88778884ef4SEddie Cai 	}
88878884ef4SEddie Cai }
88978884ef4SEddie Cai 
89078884ef4SEddie Cai static bool parseChip(FILE* file) {
89178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
89278884ef4SEddie Cai 		return false;
89378884ef4SEddie Cai 	}
89478884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
89578884ef4SEddie Cai 		return false;
89678884ef4SEddie Cai 	}
89778884ef4SEddie Cai 	printf("chip: %s\n", gOpts.chip);
89878884ef4SEddie Cai 	return true;
89978884ef4SEddie Cai }
90078884ef4SEddie Cai 
90178884ef4SEddie Cai static bool parseVersion(FILE* file) {
90278884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
90378884ef4SEddie Cai 		return false;
90478884ef4SEddie Cai 	}
90578884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
90678884ef4SEddie Cai 		return false;
90778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
90878884ef4SEddie Cai 		return false;
90978884ef4SEddie Cai 	}
91078884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
91178884ef4SEddie Cai 		return false;
91278884ef4SEddie Cai 	printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
91378884ef4SEddie Cai 	return true;
91478884ef4SEddie Cai }
91578884ef4SEddie Cai 
91678884ef4SEddie Cai static bool parse471(FILE* file) {
91778884ef4SEddie Cai 	int i, index, pos;
91878884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
91978884ef4SEddie Cai 
92078884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
92178884ef4SEddie Cai 		return false;
92278884ef4SEddie Cai 	}
92378884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
92478884ef4SEddie Cai 		return false;
92578884ef4SEddie Cai 	printf("num: %d\n", gOpts.code471Num);
92678884ef4SEddie Cai 	if (!gOpts.code471Num)
92778884ef4SEddie Cai 		return true;
92878884ef4SEddie Cai 	if (gOpts.code471Num < 0)
92978884ef4SEddie Cai 		return false;
93078884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
93178884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
93278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
93378884ef4SEddie Cai 			return false;
93478884ef4SEddie Cai 		}
93578884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
93678884ef4SEddie Cai 				!= 2)
93778884ef4SEddie Cai 			return false;
93878884ef4SEddie Cai 		index--;
93978884ef4SEddie Cai 		fixPath(buf);
94078884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
94178884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code471Path[index]);
94278884ef4SEddie Cai 	}
94378884ef4SEddie Cai 	pos = ftell(file);
94478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
94578884ef4SEddie Cai 		return false;
94678884ef4SEddie Cai 	}
94778884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
94878884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
94978884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code471Sleep);
95078884ef4SEddie Cai 	return true;
95178884ef4SEddie Cai }
95278884ef4SEddie Cai 
95378884ef4SEddie Cai static bool parse472(FILE* file) {
95478884ef4SEddie Cai 	int i, index, pos;
95578884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
95678884ef4SEddie Cai 
95778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
95878884ef4SEddie Cai 		return false;
95978884ef4SEddie Cai 	}
96078884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
96178884ef4SEddie Cai 		return false;
96278884ef4SEddie Cai 	printf("num: %d\n", gOpts.code472Num);
96378884ef4SEddie Cai 	if (!gOpts.code472Num)
96478884ef4SEddie Cai 		return true;
96578884ef4SEddie Cai 	if (gOpts.code472Num < 0)
96678884ef4SEddie Cai 		return false;
96778884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
96878884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
96978884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
97078884ef4SEddie Cai 			return false;
97178884ef4SEddie Cai 		}
97278884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
97378884ef4SEddie Cai 				!= 2)
97478884ef4SEddie Cai 			return false;
97578884ef4SEddie Cai 		fixPath(buf);
97678884ef4SEddie Cai 		index--;
97778884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
97878884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code472Path[index]);
97978884ef4SEddie Cai 	}
98078884ef4SEddie Cai 	pos = ftell(file);
98178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
98278884ef4SEddie Cai 		return false;
98378884ef4SEddie Cai 	}
98478884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
98578884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
98678884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code472Sleep);
98778884ef4SEddie Cai 	return true;
98878884ef4SEddie Cai }
98978884ef4SEddie Cai 
99078884ef4SEddie Cai static bool parseLoader(FILE* file) {
99178884ef4SEddie Cai 	int i, j, index, pos;
99278884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
99378884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
99478884ef4SEddie Cai 
99578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
99678884ef4SEddie Cai 		return false;
99778884ef4SEddie Cai 	}
99878884ef4SEddie Cai 	pos = ftell(file);
99978884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
100078884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
100178884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
100278884ef4SEddie Cai 			return false;
100378884ef4SEddie Cai 		}
100478884ef4SEddie Cai 	}
100578884ef4SEddie Cai 	printf("num: %d\n", gOpts.loaderNum);
100678884ef4SEddie Cai 	if (!gOpts.loaderNum)
100778884ef4SEddie Cai 		return false;
100878884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
100978884ef4SEddie Cai 		return false;
101078884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
101178884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
101278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
101378884ef4SEddie Cai 			return false;
101478884ef4SEddie Cai 		}
101578884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
101678884ef4SEddie Cai 				!= 2)
101778884ef4SEddie Cai 			return false;
101878884ef4SEddie Cai 		index--;
101978884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
102078884ef4SEddie Cai 		printf("name%d: %s\n", index, gOpts.loader[index].name);
102178884ef4SEddie Cai 	}
102278884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
102378884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
102478884ef4SEddie Cai 			return false;
102578884ef4SEddie Cai 		}
102678884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
102778884ef4SEddie Cai 				!= 2)
102878884ef4SEddie Cai 			return false;
102978884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
103078884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
103178884ef4SEddie Cai 				fixPath(buf2);
103278884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
103378884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
103478884ef4SEddie Cai 				break;
103578884ef4SEddie Cai 			}
103678884ef4SEddie Cai 		}
103778884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
103878884ef4SEddie Cai 			return false;
103978884ef4SEddie Cai 		}
104078884ef4SEddie Cai 	}
104178884ef4SEddie Cai 	return true;
104278884ef4SEddie Cai }
104378884ef4SEddie Cai 
104478884ef4SEddie Cai static bool parseOut(FILE* file) {
104578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
104678884ef4SEddie Cai 		return false;
104778884ef4SEddie Cai 	}
104878884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
104978884ef4SEddie Cai 		return false;
105078884ef4SEddie Cai 	fixPath(gOpts.outPath);
105178884ef4SEddie Cai 	printf("out: %s\n", gOpts.outPath);
105278884ef4SEddie Cai 	return true;
105378884ef4SEddie Cai }
105478884ef4SEddie Cai 
105578884ef4SEddie Cai 
105678884ef4SEddie Cai void printOpts(FILE* out) {
105778884ef4SEddie Cai 	int i;
105878884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
105978884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
106078884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
106178884ef4SEddie Cai 
106278884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
106378884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
106478884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
106578884ef4SEddie Cai 	}
106678884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
106778884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
106878884ef4SEddie Cai 
106978884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
107078884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
107178884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
107278884ef4SEddie Cai 	}
107378884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
107478884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
107578884ef4SEddie Cai 
107678884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
107778884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
107878884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
107978884ef4SEddie Cai 	}
108078884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
108178884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
108278884ef4SEddie Cai 	}
108378884ef4SEddie Cai 
108478884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
108578884ef4SEddie Cai }
108678884ef4SEddie Cai 
108778884ef4SEddie Cai static bool parseOpts(void) {
108878884ef4SEddie Cai 	bool ret = false;
108978884ef4SEddie Cai 	bool chipOk = false;
109078884ef4SEddie Cai 	bool versionOk = false;
109178884ef4SEddie Cai 	bool code471Ok = true;
109278884ef4SEddie Cai 	bool code472Ok = true;
109378884ef4SEddie Cai 	bool loaderOk = false;
109478884ef4SEddie Cai 	bool outOk = false;
109578884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
109678884ef4SEddie Cai 
109778884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
109878884ef4SEddie Cai 	FILE* file;
109978884ef4SEddie Cai 	file = fopen(configPath, "r");
110078884ef4SEddie Cai 	if (!file) {
110178884ef4SEddie Cai 		fprintf(stderr, "config (%s) not found!\n", configPath);
110278884ef4SEddie Cai 		if (configPath == (char*)DEF_CONFIG_FILE) {
110378884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
110478884ef4SEddie Cai 			if (file) {
110532268622SAndreas Färber 				fprintf(stderr, "creating defconfig\n");
110678884ef4SEddie Cai 				printOpts(file);
110778884ef4SEddie Cai 			}
110878884ef4SEddie Cai 		}
110978884ef4SEddie Cai 		goto end;
111078884ef4SEddie Cai 	}
111178884ef4SEddie Cai 
111232268622SAndreas Färber 	printf("Starting to parse...\n");
111378884ef4SEddie Cai 
111478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
111578884ef4SEddie Cai 		goto end;
111678884ef4SEddie Cai 	}
111778884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
111878884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
111978884ef4SEddie Cai 			chipOk = parseChip(file);
112078884ef4SEddie Cai 			if (!chipOk) {
112178884ef4SEddie Cai 				printf("parseChip failed!\n");
112278884ef4SEddie Cai 				goto end;
112378884ef4SEddie Cai 			}
112478884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
112578884ef4SEddie Cai 			versionOk = parseVersion(file);
112678884ef4SEddie Cai 			if (!versionOk) {
112778884ef4SEddie Cai 				printf("parseVersion failed!\n");
112878884ef4SEddie Cai 				goto end;
112978884ef4SEddie Cai 			}
113078884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
113178884ef4SEddie Cai 			code471Ok = parse471(file);
113278884ef4SEddie Cai 			if (!code471Ok) {
113378884ef4SEddie Cai 				printf("parse471 failed!\n");
113478884ef4SEddie Cai 				goto end;
113578884ef4SEddie Cai 			}
113678884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
113778884ef4SEddie Cai 			code472Ok = parse472(file);
113878884ef4SEddie Cai 			if (!code472Ok) {
113978884ef4SEddie Cai 				printf("parse472 failed!\n");
114078884ef4SEddie Cai 				goto end;
114178884ef4SEddie Cai 			}
114278884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
114378884ef4SEddie Cai 			loaderOk = parseLoader(file);
114478884ef4SEddie Cai 			if (!loaderOk) {
114578884ef4SEddie Cai 				printf("parseLoader failed!\n");
114678884ef4SEddie Cai 				goto end;
114778884ef4SEddie Cai 			}
114878884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
114978884ef4SEddie Cai 			outOk = parseOut(file);
115078884ef4SEddie Cai 			if (!outOk) {
115178884ef4SEddie Cai 				printf("parseOut failed!\n");
115278884ef4SEddie Cai 				goto end;
115378884ef4SEddie Cai 			}
115478884ef4SEddie Cai 		} else if (buf[0] == '#') {
115578884ef4SEddie Cai 			continue;
115678884ef4SEddie Cai 		} else {
115778884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
115878884ef4SEddie Cai 			goto end;
115978884ef4SEddie Cai 		}
116078884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
116178884ef4SEddie Cai 			goto end;
116278884ef4SEddie Cai 		}
116378884ef4SEddie Cai 	}
116478884ef4SEddie Cai 
116578884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
116678884ef4SEddie Cai 			&& loaderOk && outOk)
116778884ef4SEddie Cai 		ret = true;
116878884ef4SEddie Cai end:
116978884ef4SEddie Cai 	if (file)
117078884ef4SEddie Cai 		fclose(file);
117178884ef4SEddie Cai 	return ret;
117278884ef4SEddie Cai }
117378884ef4SEddie Cai 
117478884ef4SEddie Cai bool initOpts(void) {
117578884ef4SEddie Cai 	//set default opts
117678884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
117778884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
117878884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
117978884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
118078884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
118178884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
118278884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
118378884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
118478884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
118578884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
118678884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
118778884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
118878884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
118978884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
119078884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
119178884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
119278884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
119378884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
119478884ef4SEddie Cai 
119578884ef4SEddie Cai 	return parseOpts();
119678884ef4SEddie Cai }
119778884ef4SEddie Cai 
119878884ef4SEddie Cai /************merge code****************/
119978884ef4SEddie Cai 
120078884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
120178884ef4SEddie Cai 	uint8_t tmp[2] = {0};
120278884ef4SEddie Cai 	int i;
120378884ef4SEddie Cai 	uint32_t ret;
120478884ef4SEddie Cai 	//if (value > 0xFFFF) {
120578884ef4SEddie Cai 	//	return 0;
120678884ef4SEddie Cai 	//}
120778884ef4SEddie Cai 	for(i=0; i < 2; i++) {
120878884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
120978884ef4SEddie Cai 		value /= 100;
121078884ef4SEddie Cai 	}
121178884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
121278884ef4SEddie Cai 
121378884ef4SEddie Cai 	printf("ret: %x\n",ret);
121478884ef4SEddie Cai 	return ret&0xFF;
121578884ef4SEddie Cai }
121678884ef4SEddie Cai 
121778884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
121878884ef4SEddie Cai {
121978884ef4SEddie Cai 	int i;
122078884ef4SEddie Cai 	for (i = 0; i < len; i++) {
122178884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
122278884ef4SEddie Cai 	}
122378884ef4SEddie Cai 	wide[len] = 0;
122478884ef4SEddie Cai }
122578884ef4SEddie Cai 
122678884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
122778884ef4SEddie Cai 	char* end;
122878884ef4SEddie Cai 	char* start;
122978884ef4SEddie Cai 	int len;
123078884ef4SEddie Cai 	if (!path || !dst)
123178884ef4SEddie Cai 		return;
123278884ef4SEddie Cai 	start = strrchr(path, '/');
123378884ef4SEddie Cai 	if (!start)
123478884ef4SEddie Cai 		start = path;
123578884ef4SEddie Cai 	else
123678884ef4SEddie Cai 		start++;
123778884ef4SEddie Cai 	end = strrchr(path, '.');
1238641cfa16SEddie Cai 	if (!end || (end < start))
123978884ef4SEddie Cai 		end = path + strlen(path);
124078884ef4SEddie Cai 	len = end - start;
124178884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
124278884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
124378884ef4SEddie Cai 	str2wide(start, dst, len);
124478884ef4SEddie Cai 
124578884ef4SEddie Cai 
124678884ef4SEddie Cai 		char name[MAX_NAME_LEN];
124778884ef4SEddie Cai 		memset(name, 0, sizeof(name));
124878884ef4SEddie Cai 		memcpy(name, start, len);
124978884ef4SEddie Cai 		printf("path: %s, name: %s\n", path, name);
125078884ef4SEddie Cai 
125178884ef4SEddie Cai }
125278884ef4SEddie Cai 
125378884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
125478884ef4SEddie Cai 	struct stat st;
125578884ef4SEddie Cai 	if(stat(path, &st) < 0)
125678884ef4SEddie Cai 		return false;
125778884ef4SEddie Cai 	*size = st.st_size;
125878884ef4SEddie Cai 	printf("path: %s, size: %d\n", path, *size);
125978884ef4SEddie Cai 	return true;
126078884ef4SEddie Cai }
126178884ef4SEddie Cai 
126278884ef4SEddie Cai static inline rk_time getTime(void) {
126378884ef4SEddie Cai 	rk_time rkTime;
126478884ef4SEddie Cai 
126578884ef4SEddie Cai 	struct tm *tm;
126678884ef4SEddie Cai 	time_t tt = time(NULL);
126778884ef4SEddie Cai 	tm = localtime(&tt);
126878884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
126978884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
127078884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
127178884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
127278884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
127378884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
127478884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
127578884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
127678884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
127778884ef4SEddie Cai 	return rkTime;
127878884ef4SEddie Cai }
127978884ef4SEddie Cai 
128078884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
128178884ef4SEddie Cai 	bool ret = false;
128278884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
128378884ef4SEddie Cai 	uint8_t* buf;
128478884ef4SEddie Cai 
128578884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
128678884ef4SEddie Cai 	if (!inFile)
128778884ef4SEddie Cai 		goto end;
128878884ef4SEddie Cai 
128978884ef4SEddie Cai 	if (!getFileSize(path, &size))
129078884ef4SEddie Cai 		goto end;
129178884ef4SEddie Cai 	if (fix) {
129278884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
129378884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
129478884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
129578884ef4SEddie Cai 		fixSize +=tmp;
129678884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
129778884ef4SEddie Cai 	} else {
129878884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
129978884ef4SEddie Cai 	}
130078884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
130178884ef4SEddie Cai 		goto end;
130278884ef4SEddie Cai 
130378884ef4SEddie Cai 	if (fix) {
130478884ef4SEddie Cai 
130578884ef4SEddie Cai 		buf = gBuf;
130678884ef4SEddie Cai 		size = fixSize;
130778884ef4SEddie Cai 		while(1) {
130878884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
130978884ef4SEddie Cai 			buf += SMALL_PACKET;
131078884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
131178884ef4SEddie Cai 				break;
131278884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
131378884ef4SEddie Cai 		}
131478884ef4SEddie Cai 	} else {
131578884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
131678884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
131778884ef4SEddie Cai 		size +=tmp;
131878884ef4SEddie Cai 		P_RC4(gBuf, size);
131978884ef4SEddie Cai 	}
132078884ef4SEddie Cai 
132178884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
132278884ef4SEddie Cai 		goto end;
132378884ef4SEddie Cai 	ret = true;
132478884ef4SEddie Cai end:
132578884ef4SEddie Cai 	if (inFile)
132678884ef4SEddie Cai 		fclose(inFile);
132778884ef4SEddie Cai 	if (!ret)
132832268622SAndreas Färber 		printf("writing entry (%s) failed\n", path);
132978884ef4SEddie Cai 	return ret;
133078884ef4SEddie Cai }
133178884ef4SEddie Cai 
133278884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
133378884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
133478884ef4SEddie Cai 	uint32_t size;
133578884ef4SEddie Cai 	rk_boot_entry entry;
133678884ef4SEddie Cai 
133732268622SAndreas Färber 	printf("writing: %s\n", path);
1338641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
133978884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
134078884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
134178884ef4SEddie Cai 	entry.type = type;
134278884ef4SEddie Cai 	entry.dataOffset = *offset;
134378884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
134432268622SAndreas Färber 		printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
134578884ef4SEddie Cai 		return false;
134678884ef4SEddie Cai 	}
134778884ef4SEddie Cai 	if (fix)
134878884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
134978884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
135078884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
135132268622SAndreas Färber 	printf("alignment size: %d\n", size);
135278884ef4SEddie Cai 	entry.dataSize = size;
135378884ef4SEddie Cai 	entry.dataDelay = delay;
135478884ef4SEddie Cai 	*offset += size;
135578884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
135678884ef4SEddie Cai 	return true;
135778884ef4SEddie Cai }
135878884ef4SEddie Cai 
135978884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
136078884ef4SEddie Cai 	char buffer[5];
136178884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
136278884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
136378884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
136478884ef4SEddie Cai }
136578884ef4SEddie Cai 
136678884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
136778884ef4SEddie Cai 	printf("chip: %s\n", chip);
136878884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
136978884ef4SEddie Cai 	if(!chip) {
137078884ef4SEddie Cai 		goto end;
137178884ef4SEddie Cai 	}
137278884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
137378884ef4SEddie Cai 		chipType = RK28_DEVICE;
137478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
137578884ef4SEddie Cai 		chipType = RK28_DEVICE;
137678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
137778884ef4SEddie Cai 		chipType = RK281X_DEVICE;
137878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
137978884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
138078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
138178884ef4SEddie Cai 		chipType = RK27_DEVICE;
138278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
138378884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
138478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
138578884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
138678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
138778884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
138878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
138978884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
139078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
139178884ef4SEddie Cai 		chipType = RK29_DEVICE;
139278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
139378884ef4SEddie Cai 		chipType = RK292X_DEVICE;
139478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
139578884ef4SEddie Cai 		chipType = RK30_DEVICE;
139678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
139778884ef4SEddie Cai 		chipType = RK30B_DEVICE;
139878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
139978884ef4SEddie Cai 		chipType = RK31_DEVICE;
140078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
140178884ef4SEddie Cai 		chipType = RK32_DEVICE;
140278884ef4SEddie Cai 	} else {
140378884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
140478884ef4SEddie Cai 	}
140578884ef4SEddie Cai 
140678884ef4SEddie Cai end:
140778884ef4SEddie Cai 	printf("type: 0x%x\n", chipType);
140878884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
140932268622SAndreas Färber 		printf("chip type not supported!\n");
141078884ef4SEddie Cai 	}
141178884ef4SEddie Cai 	return chipType;
141278884ef4SEddie Cai }
141378884ef4SEddie Cai 
141478884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
141578884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
141678884ef4SEddie Cai 	hdr->tag = TAG;
141778884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
141878884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
141978884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
142078884ef4SEddie Cai 	hdr->releaseTime = getTime();
142178884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
142278884ef4SEddie Cai 
142378884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
142478884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
142578884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
142678884ef4SEddie Cai 
142778884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
142878884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
142978884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
143078884ef4SEddie Cai 
143178884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
143278884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
143378884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
143478884ef4SEddie Cai #ifndef USE_P_RC4
143578884ef4SEddie Cai 	hdr->rc4Flag = 1;
143678884ef4SEddie Cai #endif
143778884ef4SEddie Cai }
143878884ef4SEddie Cai 
143978884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
144078884ef4SEddie Cai 	uint32_t size = 0;
144178884ef4SEddie Cai 	uint32_t crc = 0;
144278884ef4SEddie Cai 
144378884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
144478884ef4SEddie Cai 	getFileSize(path, &size);
144578884ef4SEddie Cai 	if (!file)
144678884ef4SEddie Cai 		goto end;
144778884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
144878884ef4SEddie Cai 		goto end;
144978884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
145078884ef4SEddie Cai 	printf("crc: 0x%08x\n", crc);
145178884ef4SEddie Cai end:
145278884ef4SEddie Cai 	if (file)
145378884ef4SEddie Cai 		fclose(file);
145478884ef4SEddie Cai 	return crc;
145578884ef4SEddie Cai }
145678884ef4SEddie Cai 
145778884ef4SEddie Cai bool mergeBoot(void) {
145878884ef4SEddie Cai 	uint32_t dataOffset;
145978884ef4SEddie Cai 	bool ret = false;
146078884ef4SEddie Cai 	int i;
146178884ef4SEddie Cai 	FILE* outFile;
146278884ef4SEddie Cai 	uint32_t crc;
146378884ef4SEddie Cai 	rk_boot_header hdr;
146478884ef4SEddie Cai 
146578884ef4SEddie Cai 	if (!initOpts())
146678884ef4SEddie Cai 		return false;
146778884ef4SEddie Cai 	{
146878884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
146978884ef4SEddie Cai 		char version[MAX_LINE_LEN];
147078884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
147178884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
147278884ef4SEddie Cai 			subfix[0] = '\0';
147378884ef4SEddie Cai 		}
147478884ef4SEddie Cai 		strcat(gOpts.outPath, version);
147578884ef4SEddie Cai 		printf("fix opt: %s\n", gOpts.outPath);
147678884ef4SEddie Cai 	}
147778884ef4SEddie Cai 
147878884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
147978884ef4SEddie Cai 	printOpts(stdout);
148078884ef4SEddie Cai 	printf("---------------\n\n");
148178884ef4SEddie Cai 
148278884ef4SEddie Cai 
148378884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
148478884ef4SEddie Cai 	if (!outFile) {
148532268622SAndreas Färber 		printf("Opening output file (%s) failed\n", gOpts.outPath);
148678884ef4SEddie Cai 		goto end;
148778884ef4SEddie Cai 	}
148878884ef4SEddie Cai 
148978884ef4SEddie Cai 	getBoothdr(&hdr);
149032268622SAndreas Färber 	printf("Writing header...\n");
149178884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
149278884ef4SEddie Cai 
149378884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
149478884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
149578884ef4SEddie Cai 		sizeof(rk_boot_entry);
149678884ef4SEddie Cai 
149732268622SAndreas Färber 	printf("Writing code 471 entry...\n");
149878884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
149978884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
150078884ef4SEddie Cai 					&dataOffset, NULL, false))
150178884ef4SEddie Cai 			goto end;
150278884ef4SEddie Cai 	}
150332268622SAndreas Färber 	printf("Writing code 472 entry...\n");
150478884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
150578884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
150678884ef4SEddie Cai 					&dataOffset, NULL, false))
150778884ef4SEddie Cai 			goto end;
150878884ef4SEddie Cai 	}
150932268622SAndreas Färber 	printf("Writing loader entry...\n");
151078884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
151178884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
151278884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
151378884ef4SEddie Cai 			goto end;
151478884ef4SEddie Cai 	}
151578884ef4SEddie Cai 
151632268622SAndreas Färber 	printf("Writing code 471...\n");
151778884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
151878884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
151978884ef4SEddie Cai 			goto end;
152078884ef4SEddie Cai 	}
152132268622SAndreas Färber 	printf("Writing code 472...\n");
152278884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
152378884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
152478884ef4SEddie Cai 			goto end;
152578884ef4SEddie Cai 	}
152632268622SAndreas Färber 	printf("Writing loader...\n");
152778884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
152878884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
152978884ef4SEddie Cai 			goto end;
153078884ef4SEddie Cai 	}
153178884ef4SEddie Cai 	fflush(outFile);
153278884ef4SEddie Cai 
153332268622SAndreas Färber 	printf("Writing crc...\n");
153478884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
153578884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
153678884ef4SEddie Cai 		goto end;
153732268622SAndreas Färber 	printf("Done.\n");
153878884ef4SEddie Cai 	ret = true;
153978884ef4SEddie Cai end:
154078884ef4SEddie Cai 	if (outFile)
154178884ef4SEddie Cai 		fclose(outFile);
154278884ef4SEddie Cai 	return ret;
154378884ef4SEddie Cai }
154478884ef4SEddie Cai 
154578884ef4SEddie Cai /************merge code end************/
154678884ef4SEddie Cai /************unpack code***************/
154778884ef4SEddie Cai 
154878884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
154978884ef4SEddie Cai {
155078884ef4SEddie Cai 	int i;
155178884ef4SEddie Cai 	for (i = 0; i < len; i++) {
155278884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
155378884ef4SEddie Cai 	}
155478884ef4SEddie Cai 	str[len] = 0;
155578884ef4SEddie Cai }
155678884ef4SEddie Cai 
155778884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
155878884ef4SEddie Cai 		FILE* inFile) {
155978884ef4SEddie Cai 	bool ret = false;
156078884ef4SEddie Cai 	int size, i;
156178884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
156278884ef4SEddie Cai 	if (!outFile)
156378884ef4SEddie Cai 		goto end;
156432268622SAndreas Färber 	printf("unpacking entry (%s)\n", name);
156578884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
156678884ef4SEddie Cai 	size = entry->dataSize;
156778884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
156878884ef4SEddie Cai 		goto end;
156978884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
157078884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
157178884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
157278884ef4SEddie Cai 		if (size % SMALL_PACKET)
157378884ef4SEddie Cai 		{
157478884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
157578884ef4SEddie Cai 		}
157678884ef4SEddie Cai 	} else {
157778884ef4SEddie Cai 		P_RC4(gBuf, size);
157878884ef4SEddie Cai 	}
157978884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
158078884ef4SEddie Cai 		goto end;
158178884ef4SEddie Cai 	ret = true;
158278884ef4SEddie Cai end:
158378884ef4SEddie Cai 	if (outFile)
158478884ef4SEddie Cai 		fclose(outFile);
158578884ef4SEddie Cai 	return ret;
158678884ef4SEddie Cai }
158778884ef4SEddie Cai 
158878884ef4SEddie Cai bool unpackBoot(char* path) {
158978884ef4SEddie Cai 	bool ret = false;
159078884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
159178884ef4SEddie Cai 	int entryNum, i;
159278884ef4SEddie Cai 	char name[MAX_NAME_LEN];
159378884ef4SEddie Cai 	rk_boot_entry* entrys;
159478884ef4SEddie Cai 	if (!inFile) {
159578884ef4SEddie Cai 		fprintf(stderr, "loader (%s) not found\n", path);
159678884ef4SEddie Cai 		goto end;
159778884ef4SEddie Cai 	}
159878884ef4SEddie Cai 
159978884ef4SEddie Cai 	rk_boot_header hdr;
160078884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
160132268622SAndreas Färber 		fprintf(stderr, "reading header failed\n");
160278884ef4SEddie Cai 		goto end;
160378884ef4SEddie Cai 	}
160478884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
160578884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
160678884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
160778884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
160832268622SAndreas Färber 		fprintf(stderr, "reading data failed\n");
160978884ef4SEddie Cai 		goto end;
161078884ef4SEddie Cai 	}
161178884ef4SEddie Cai 
161278884ef4SEddie Cai 	printf("entry num: %d\n", entryNum);
161378884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
161478884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
161578884ef4SEddie Cai 
161678884ef4SEddie Cai 		printf("entry: t=%d, name=%s, off=%d, size=%d\n",
161778884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
161878884ef4SEddie Cai 				entrys[i].dataSize);
161978884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
162032268622SAndreas Färber 			fprintf(stderr, "unpacking entry (%s) failed\n", name);
162178884ef4SEddie Cai 			goto end;
162278884ef4SEddie Cai 		}
162378884ef4SEddie Cai 	}
162478884ef4SEddie Cai 	printf("done\n");
162578884ef4SEddie Cai 	ret = true;
162678884ef4SEddie Cai end:
162778884ef4SEddie Cai 	if (inFile)
162878884ef4SEddie Cai 		fclose(inFile);
162978884ef4SEddie Cai 	return ret;
163078884ef4SEddie Cai }
163178884ef4SEddie Cai 
163276af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
163376af099aSliuyi {
163476af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
163576af099aSliuyi 		return false;
163676af099aSliuyi 	CRKImage *pImage = NULL;
163776af099aSliuyi 	CRKBoot *pBoot = NULL;
163876af099aSliuyi 	bool bRet, bSuccess = false;
163976af099aSliuyi 	int iRet;
164076af099aSliuyi 
164176af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
164276af099aSliuyi 	if (!bRet){
164376af099aSliuyi 		ERROR_COLOR_ATTR;
164432268622SAndreas Färber 		printf("Opening loader failed, exiting download boot!");
164576af099aSliuyi 		NORMAL_COLOR_ATTR;
164676af099aSliuyi 		printf("\r\n");
164776af099aSliuyi 		return bSuccess;
164876af099aSliuyi 	} else {
164976af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
165076af099aSliuyi 		CRKComm *pComm = NULL;
165176af099aSliuyi 		CRKDevice *pDevice = NULL;
165276af099aSliuyi 
165376af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
165476af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
165576af099aSliuyi 		if (!bRet) {
165676af099aSliuyi 			if (pImage)
165776af099aSliuyi 				delete pImage;
165876af099aSliuyi 			ERROR_COLOR_ATTR;
165976af099aSliuyi 			printf("Creating Comm Object failed!");
166076af099aSliuyi 			NORMAL_COLOR_ATTR;
166176af099aSliuyi 			printf("\r\n");
166276af099aSliuyi 			return bSuccess;
166376af099aSliuyi 		}
166476af099aSliuyi 
166576af099aSliuyi 		pDevice = new CRKDevice(dev);
166676af099aSliuyi 		if (!pDevice) {
166776af099aSliuyi 			if (pImage)
166876af099aSliuyi 				delete pImage;
166976af099aSliuyi 			if (pComm)
167076af099aSliuyi 				delete pComm;
167176af099aSliuyi 			ERROR_COLOR_ATTR;
167276af099aSliuyi 			printf("Creating device object failed!");
167376af099aSliuyi 			NORMAL_COLOR_ATTR;
167476af099aSliuyi 			printf("\r\n");
167576af099aSliuyi 			return bSuccess;
167676af099aSliuyi 		}
167776af099aSliuyi 
167876af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
167932268622SAndreas Färber 		printf("Downloading bootloader...\r\n");
168076af099aSliuyi 		iRet = pDevice->DownloadBoot();
168176af099aSliuyi 
168276af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
168376af099aSliuyi 		CURSOR_DEL_LINE;
168476af099aSliuyi 		if (iRet == 0) {
168576af099aSliuyi 			bSuccess = true;
168632268622SAndreas Färber 			printf("Downloading bootloader succeeded.\r\n");
168776af099aSliuyi 		}
168876af099aSliuyi 		else
168932268622SAndreas Färber 			printf("Downloading bootloader failed!\r\n");
169076af099aSliuyi 
169176af099aSliuyi 		if (pImage)
169276af099aSliuyi 			delete pImage;
169376af099aSliuyi 		if(pDevice)
169476af099aSliuyi 			delete pDevice;
169576af099aSliuyi 	}
169676af099aSliuyi 	return bSuccess;
169776af099aSliuyi }
1698c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1699c30d921cSKever Yang {
1700c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1701c30d921cSKever Yang 		return false;
1702c30d921cSKever Yang 	CRKImage *pImage = NULL;
1703c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1704c30d921cSKever Yang 	CRKComm *pComm = NULL;
1705c30d921cSKever Yang 	bool bRet, bSuccess = false;
1706c30d921cSKever Yang 	int iRet;
1707c30d921cSKever Yang 	char index;
1708c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1709c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1710c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1711c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1712c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1713c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1714c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1715c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1716c30d921cSKever Yang 	if (!bRet){
1717c30d921cSKever Yang 		ERROR_COLOR_ATTR;
171832268622SAndreas Färber 		printf("Opening loader failed, exiting upgrade loader!");
1719c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1720c30d921cSKever Yang 		printf("\r\n");
1721c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1722c30d921cSKever Yang 	} else {
1723c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1724c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1725c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1726c30d921cSKever Yang 		if (!bRet) {
1727c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1728c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1729c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1730c30d921cSKever Yang 			printf("\r\n");
1731c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1732c30d921cSKever Yang 		}
1733c30d921cSKever Yang 
173432268622SAndreas Färber 		printf("Upgrading loader...\r\n");
1735c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1736c30d921cSKever Yang 		if (index == -1) {
1737c30d921cSKever Yang 			if (g_pLogObject) {
173832268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1739c30d921cSKever Yang 			}
1740c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1741c30d921cSKever Yang 		}
1742c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1743c30d921cSKever Yang 		if (!bRet) {
1744c30d921cSKever Yang 			if (g_pLogObject) {
174532268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1746c30d921cSKever Yang 			}
1747c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1748c30d921cSKever Yang 		}
1749c30d921cSKever Yang 
1750c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1751c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1752c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1753c30d921cSKever Yang 			if (g_pLogObject) {
175432268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1755c30d921cSKever Yang 			}
1756c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1757c30d921cSKever Yang 		}
1758c30d921cSKever Yang 
1759c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1760c30d921cSKever Yang 		if (index == -1) {
1761c30d921cSKever Yang 			if (g_pLogObject) {
176232268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1763c30d921cSKever Yang 			}
1764c30d921cSKever Yang 			delete []loaderCodeBuffer;
1765c30d921cSKever Yang 			return -4;
1766c30d921cSKever Yang 		}
1767c30d921cSKever Yang 
1768c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1769c30d921cSKever Yang 		if (!bRet) {
1770c30d921cSKever Yang 			if (g_pLogObject) {
177132268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1772c30d921cSKever Yang 			}
1773c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1774c30d921cSKever Yang 		}
1775c30d921cSKever Yang 
1776c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1777c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1778c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1779c30d921cSKever Yang 			if (g_pLogObject) {
178032268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1781c30d921cSKever Yang 			}
1782c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1783c30d921cSKever Yang 		}
1784c30d921cSKever Yang 
1785c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1786c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1787c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1788c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1789c30d921cSKever Yang 		if (!pIDBData) {
1790c30d921cSKever Yang 			ERROR_COLOR_ATTR;
179132268622SAndreas Färber 			printf("Allocating memory failed!");
1792c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1793c30d921cSKever Yang 			printf("\r\n");
1794c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1795c30d921cSKever Yang 		}
1796c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1797b38fe5fcSliuyi 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
1798c30d921cSKever Yang 		if (iRet != 0) {
1799c30d921cSKever Yang 			ERROR_COLOR_ATTR;
180032268622SAndreas Färber 			printf("Making idblock failed!");
1801c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1802c30d921cSKever Yang 			printf("\r\n");
1803c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1804c30d921cSKever Yang 		}
1805c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
1806c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
1807c30d921cSKever Yang 		CURSOR_DEL_LINE;
1808c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
1809b38fe5fcSliuyi 			//pComm->Reset_Usb_Device();
1810c30d921cSKever Yang 			bSuccess = true;
181132268622SAndreas Färber 			printf("Upgrading loader succeeded.\r\n");
1812c30d921cSKever Yang 		} else {
181332268622SAndreas Färber 			printf("Upgrading loader failed!\r\n");
1814c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1815c30d921cSKever Yang 		}
1816c30d921cSKever Yang 	}
1817c30d921cSKever Yang Exit_UpgradeLoader:
1818c30d921cSKever Yang 	if (pImage)
1819c30d921cSKever Yang 		delete pImage;
1820c30d921cSKever Yang 	if (pComm)
1821c30d921cSKever Yang 		delete pComm;
1822c30d921cSKever Yang 	if (loaderCodeBuffer)
1823c30d921cSKever Yang 		delete []loaderCodeBuffer;
1824c30d921cSKever Yang 	if (loaderDataBuffer)
1825c30d921cSKever Yang 		delete []loaderDataBuffer;
1826c30d921cSKever Yang 	if (pIDBData)
1827c30d921cSKever Yang 		delete []pIDBData;
1828c30d921cSKever Yang 	return bSuccess;
1829c30d921cSKever Yang }
1830c30d921cSKever Yang 
183176af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
183276af099aSliuyi {
183376af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
183476af099aSliuyi 		return false;
183576af099aSliuyi 	CRKImage *pImage = NULL;
183676af099aSliuyi 	bool bRet, bSuccess = false;
183776af099aSliuyi 	int iRet;
183876af099aSliuyi 	CRKScan *pScan = NULL;
183976af099aSliuyi 	pScan = new CRKScan();
184076af099aSliuyi 	pScan->SetVidPid();
184176af099aSliuyi 
184276af099aSliuyi 	CRKComm *pComm = NULL;
184376af099aSliuyi 	CRKDevice *pDevice = NULL;
184476af099aSliuyi 
184576af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
184676af099aSliuyi 	if (!bRet) {
184776af099aSliuyi 		if (pScan)
184876af099aSliuyi 			delete pScan;
184976af099aSliuyi 		ERROR_COLOR_ATTR;
185076af099aSliuyi 		printf("Creating Comm Object failed!");
185176af099aSliuyi 		NORMAL_COLOR_ATTR;
185276af099aSliuyi 		printf("\r\n");
185376af099aSliuyi 		return bSuccess;
185476af099aSliuyi 	}
185576af099aSliuyi 
185676af099aSliuyi 	pDevice = new CRKDevice(dev);
185776af099aSliuyi 	if (!pDevice) {
185876af099aSliuyi 		if (pComm)
185976af099aSliuyi 			delete pComm;
186076af099aSliuyi 		if (pScan)
186176af099aSliuyi 			delete pScan;
186276af099aSliuyi 		ERROR_COLOR_ATTR;
186376af099aSliuyi 		printf("Creating device object failed!");
186476af099aSliuyi 		NORMAL_COLOR_ATTR;
186576af099aSliuyi 		printf("\r\n");
186676af099aSliuyi 		return bSuccess;
186776af099aSliuyi 	}
186876af099aSliuyi 
186976af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
187076af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
187176af099aSliuyi 
187232268622SAndreas Färber 	printf("Starting to erase flash...\r\n");
187376af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
187476af099aSliuyi 	if (pDevice)
187576af099aSliuyi 		delete pDevice;
187676af099aSliuyi 
187776af099aSliuyi 	if (iRet == 0) {
187876af099aSliuyi 		if (pScan) {
187976af099aSliuyi 			pScan->SetVidPid();
188076af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
188176af099aSliuyi 			delete pScan;
188276af099aSliuyi 		}
188376af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
188476af099aSliuyi 		CURSOR_DEL_LINE;
188576af099aSliuyi 		bSuccess = true;
188632268622SAndreas Färber 		printf("Erasing flash complete.\r\n");
188776af099aSliuyi 	}
188876af099aSliuyi 
188976af099aSliuyi 	return bSuccess;
189076af099aSliuyi }
189176af099aSliuyi 
189276af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
189376af099aSliuyi {
189476af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
189576af099aSliuyi 		return false;
189676af099aSliuyi 	CRKUsbComm *pComm = NULL;
189776af099aSliuyi 	bool bRet, bSuccess = false;
189876af099aSliuyi 	int iRet;
189976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
190076af099aSliuyi 	if (bRet) {
190176af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
190276af099aSliuyi 		if (iRet != ERR_SUCCESS) {
190376af099aSliuyi 			if (g_pLogObject)
190476af099aSliuyi 				g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
190532268622SAndreas Färber 			printf("Test Device failed!\r\n");
190676af099aSliuyi 		} else {
190776af099aSliuyi 			bSuccess = true;
190876af099aSliuyi 			printf("Test Device OK.\r\n");
190976af099aSliuyi 		}
191076af099aSliuyi 	} else {
191132268622SAndreas Färber 		printf("Test Device quit, creating comm object failed!\r\n");
191276af099aSliuyi 	}
191376af099aSliuyi 	if (pComm) {
191476af099aSliuyi 		delete pComm;
191576af099aSliuyi 		pComm = NULL;
191676af099aSliuyi 	}
191776af099aSliuyi 	return bSuccess;
191876af099aSliuyi }
191976af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
192076af099aSliuyi {
192176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
192276af099aSliuyi 		return false;
192376af099aSliuyi 	CRKUsbComm *pComm = NULL;
192476af099aSliuyi 	bool bRet, bSuccess = false;
192576af099aSliuyi 	int iRet;
192676af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
192776af099aSliuyi 	if (bRet) {
192876af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
192976af099aSliuyi 		if (iRet != ERR_SUCCESS) {
193076af099aSliuyi 			if (g_pLogObject)
193176af099aSliuyi 				g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
193232268622SAndreas Färber 			printf("Reset Device failed!\r\n");
193376af099aSliuyi 		} else {
193476af099aSliuyi 			bSuccess = true;
193576af099aSliuyi 			printf("Reset Device OK.\r\n");
193676af099aSliuyi 		}
193776af099aSliuyi 	} else {
193832268622SAndreas Färber 		printf("Reset Device quit, creating comm object failed!\r\n");
193976af099aSliuyi 	}
194076af099aSliuyi 	if (pComm) {
194176af099aSliuyi 		delete pComm;
194276af099aSliuyi 		pComm = NULL;
194376af099aSliuyi 	}
194476af099aSliuyi 	return bSuccess;
194576af099aSliuyi }
194676af099aSliuyi 
194776af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
194876af099aSliuyi {
194976af099aSliuyi 	CRKUsbComm *pComm = NULL;
195076af099aSliuyi 	bool bRet, bSuccess = false;
195176af099aSliuyi 	int iRet;
195276af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
195376af099aSliuyi 		return bSuccess;
195476af099aSliuyi 
195576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
195676af099aSliuyi 	if (bRet) {
195776af099aSliuyi 		BYTE flashID[5];
195876af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
195976af099aSliuyi 		if (iRet != ERR_SUCCESS) {
196076af099aSliuyi 			if (g_pLogObject)
196176af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
196232268622SAndreas Färber 			printf("Reading flash ID failed!\r\n");
196376af099aSliuyi 		} else {
196476af099aSliuyi 			printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
196576af099aSliuyi 			bSuccess = true;
196676af099aSliuyi 		}
196776af099aSliuyi 	} else {
196832268622SAndreas Färber 		printf("Read Flash ID quit, creating comm object failed!\r\n");
196976af099aSliuyi 	}
197076af099aSliuyi 	if (pComm) {
197176af099aSliuyi 		delete pComm;
197276af099aSliuyi 		pComm = NULL;
197376af099aSliuyi 	}
197476af099aSliuyi 	return bSuccess;
197576af099aSliuyi }
197676af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
197776af099aSliuyi {
197876af099aSliuyi 	CRKUsbComm *pComm = NULL;
197976af099aSliuyi 	bool bRet, bSuccess = false;
198076af099aSliuyi 	int iRet;
198176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
198276af099aSliuyi 		return bSuccess;
198376af099aSliuyi 
198476af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
198576af099aSliuyi 	if (bRet) {
198676af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
198776af099aSliuyi 		UINT uiRead;
198876af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
198976af099aSliuyi 		if (iRet != ERR_SUCCESS) {
199076af099aSliuyi 			if (g_pLogObject)
199176af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
199232268622SAndreas Färber 			printf("Read Flash Info failed!\r\n");
199376af099aSliuyi 		} else {
199476af099aSliuyi 			printf("Flash Info:\r\n");
199576af099aSliuyi 			if (info.bManufCode <= 7) {
199676af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
199776af099aSliuyi 			}
199876af099aSliuyi 			else
199976af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
200076af099aSliuyi 
200176af099aSliuyi 			printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
200276af099aSliuyi 			printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
200376af099aSliuyi 			printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
200476af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
200576af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
200676af099aSliuyi 			printf("\tFlash CS: ");
200776af099aSliuyi 			for(int i = 0; i < 8; i++) {
200876af099aSliuyi 				if( info.bFlashCS & (1 << i) )
200976af099aSliuyi 					printf("Flash<%d> ", i);
201076af099aSliuyi 			}
201176af099aSliuyi 			printf("\r\n");
201276af099aSliuyi 			bSuccess = true;
201376af099aSliuyi 		}
201476af099aSliuyi 	}else {
201532268622SAndreas Färber 		printf("Read Flash Info quit, creating comm object failed!\r\n");
201676af099aSliuyi 	}
201776af099aSliuyi 	if (pComm) {
201876af099aSliuyi 		delete pComm;
201976af099aSliuyi 		pComm = NULL;
202076af099aSliuyi 	}
202176af099aSliuyi 	return bSuccess;
202276af099aSliuyi }
202376af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
202476af099aSliuyi {
202576af099aSliuyi 	CRKUsbComm *pComm = NULL;
202676af099aSliuyi 	bool bRet, bSuccess = false;
202776af099aSliuyi 	int iRet;
202876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
202976af099aSliuyi 		return bSuccess;
203076af099aSliuyi 
203176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
203276af099aSliuyi 	if (bRet) {
203376af099aSliuyi 		BYTE chipInfo[16];
203476af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
203576af099aSliuyi 		if (iRet != ERR_SUCCESS) {
203676af099aSliuyi 			if (g_pLogObject)
203776af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
203832268622SAndreas Färber 			printf("Read Chip Info failed!\r\n");
203976af099aSliuyi 		} else {
204076af099aSliuyi 			string strChipInfo;
204176af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
204276af099aSliuyi 			printf("Chip Info: %s\r\n", strChipInfo.c_str());
204376af099aSliuyi 			bSuccess = true;
204476af099aSliuyi 		}
204576af099aSliuyi 	} else {
204632268622SAndreas Färber 		printf("Read Chip Info quit, creating comm object failed!\r\n");
204776af099aSliuyi 	}
204876af099aSliuyi 	if (pComm) {
204976af099aSliuyi 		delete pComm;
205076af099aSliuyi 		pComm = NULL;
205176af099aSliuyi 	}
205276af099aSliuyi 	return bSuccess;
205376af099aSliuyi }
205476af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
205576af099aSliuyi {
205676af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
205776af099aSliuyi 		return false;
205876af099aSliuyi 	CRKUsbComm *pComm = NULL;
205976af099aSliuyi 	FILE *file = NULL;
206076af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
206176af099aSliuyi 	int iRet;
206276af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
206376af099aSliuyi 	int nSectorSize = 512;
206476af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
206576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
206676af099aSliuyi 	if (bRet) {
206776af099aSliuyi 		if(szFile) {
206876af099aSliuyi 			file = fopen(szFile, "wb+");
206976af099aSliuyi 			if( !file ) {
207076af099aSliuyi 				printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
207176af099aSliuyi 				goto Exit_ReadLBA;
207276af099aSliuyi 			}
207376af099aSliuyi 		}
207476af099aSliuyi 
207576af099aSliuyi 		while(uiLen > 0) {
207676af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
207776af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
207876af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
207976af099aSliuyi 			if(ERR_SUCCESS == iRet) {
208076af099aSliuyi 				uiLen -= iRead;
208176af099aSliuyi 				iTotalRead += iRead;
208276af099aSliuyi 
208376af099aSliuyi 				if(szFile) {
208476af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
208576af099aSliuyi 					if (bFirst){
208676af099aSliuyi 						if (iTotalRead >= 1024)
208732268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
208876af099aSliuyi 						else
208932268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
209076af099aSliuyi 						bFirst = false;
209176af099aSliuyi 					} else {
209276af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
209376af099aSliuyi 						CURSOR_DEL_LINE;
209476af099aSliuyi 						if (iTotalRead >= 1024)
209532268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
209676af099aSliuyi 						else
209732268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
209876af099aSliuyi 					}
209976af099aSliuyi 				}
210076af099aSliuyi 				else
210176af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
210276af099aSliuyi 			} else {
210376af099aSliuyi 				if (g_pLogObject)
210476af099aSliuyi 					g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
210576af099aSliuyi 
210676af099aSliuyi 				printf("Read LBA failed!\r\n");
210776af099aSliuyi 				goto Exit_ReadLBA;
210876af099aSliuyi 			}
210976af099aSliuyi 		}
211076af099aSliuyi 		bSuccess = true;
211176af099aSliuyi 	} else {
211232268622SAndreas Färber 		printf("Read LBA quit, creating comm object failed!\r\n");
211376af099aSliuyi 	}
211476af099aSliuyi Exit_ReadLBA:
211576af099aSliuyi 	if (pComm) {
211676af099aSliuyi 		delete pComm;
211776af099aSliuyi 		pComm = NULL;
211876af099aSliuyi 	}
211976af099aSliuyi 	if (file)
212076af099aSliuyi 		fclose(file);
212176af099aSliuyi 	return bSuccess;
212276af099aSliuyi }
212376af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
212476af099aSliuyi {
212576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
212676af099aSliuyi 		return false;
212776af099aSliuyi 	CRKUsbComm *pComm = NULL;
212876af099aSliuyi 	FILE *file = NULL;
212976af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
213076af099aSliuyi 	int iRet;
213176af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
213276af099aSliuyi 	UINT iWrite = 0, iRead = 0;
213376af099aSliuyi 	UINT uiLen;
213476af099aSliuyi 	int nSectorSize = 512;
213576af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
213676af099aSliuyi 
213776af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
213876af099aSliuyi 	if (bRet) {
213976af099aSliuyi 		file = fopen(szFile, "rb");
214076af099aSliuyi 		if( !file ) {
214176af099aSliuyi 			printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
214276af099aSliuyi 			goto Exit_WriteLBA;
214376af099aSliuyi 		}
214476af099aSliuyi 
214576af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
214676af099aSliuyi 		iFileSize = ftello(file);
214776af099aSliuyi 		fseeko(file, 0, SEEK_SET);
214876af099aSliuyi 		while(iTotalWrite < iFileSize) {
214976af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
215076af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
215176af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
215276af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
215376af099aSliuyi 			if(ERR_SUCCESS == iRet) {
215476af099aSliuyi 				uiBegin += uiLen;
215576af099aSliuyi 				iTotalWrite += iWrite;
215676af099aSliuyi 				if (bFirst) {
215776af099aSliuyi 					if (iTotalWrite >= 1024)
215876af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
215976af099aSliuyi 					else
216032268622SAndreas Färber 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
216176af099aSliuyi 					bFirst = false;
216276af099aSliuyi 				} else {
216376af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
216476af099aSliuyi 					CURSOR_DEL_LINE;
216576af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
216676af099aSliuyi 				}
216776af099aSliuyi 			} else {
216876af099aSliuyi 				if (g_pLogObject)
216976af099aSliuyi 					g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
217076af099aSliuyi 
217176af099aSliuyi 				printf("Write LBA failed!\r\n");
217276af099aSliuyi 				goto Exit_WriteLBA;
217376af099aSliuyi 			}
217476af099aSliuyi 		}
217576af099aSliuyi 		bSuccess = true;
217676af099aSliuyi 	} else {
217732268622SAndreas Färber 		printf("Write LBA quit, creating comm object failed!\r\n");
217876af099aSliuyi 	}
217976af099aSliuyi Exit_WriteLBA:
218076af099aSliuyi 	if (pComm) {
218176af099aSliuyi 		delete pComm;
218276af099aSliuyi 		pComm = NULL;
218376af099aSliuyi 	}
218476af099aSliuyi 	if (file)
218576af099aSliuyi 		fclose(file);
218676af099aSliuyi 	return bSuccess;
218776af099aSliuyi }
218876af099aSliuyi 
218976af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
219076af099aSliuyi {
219176af099aSliuyi 	string strItem;
219276af099aSliuyi 	char szItem[100];
219376af099aSliuyi 	char *pos = NULL, *pStart;
219476af099aSliuyi 	pStart = pszItems;
219576af099aSliuyi 	pos = strchr(pStart, ',');
219676af099aSliuyi 	while(pos != NULL) {
219776af099aSliuyi 		memset(szItem, 0, 100);
219876af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
219976af099aSliuyi 		strItem = szItem;
220076af099aSliuyi 		vecItems.push_back(strItem);
220176af099aSliuyi 		pStart = pos + 1;
220276af099aSliuyi 		if (*pStart == 0)
220376af099aSliuyi 			break;
220476af099aSliuyi 		pos = strchr(pStart, ',');
220576af099aSliuyi 	}
220676af099aSliuyi 	if (strlen(pStart) > 0) {
220776af099aSliuyi 		memset(szItem, 0, 100);
220876af099aSliuyi 		strncpy(szItem, pStart, strlen(pStart));
220976af099aSliuyi 		strItem = szItem;
221076af099aSliuyi 		vecItems.push_back(strItem);
221176af099aSliuyi 	}
221276af099aSliuyi }
2213c30d921cSKever Yang 
2214d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
2215d71e8c20SEddie Cai {
2216d71e8c20SEddie Cai 	FILE *file = NULL;
2217d71e8c20SEddie Cai 	int len;
2218d71e8c20SEddie Cai 
2219d71e8c20SEddie Cai 	if(!tag || !spl)
2220d71e8c20SEddie Cai 		return;
2221d71e8c20SEddie Cai 	len = strlen(tag);
2222d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
2223d71e8c20SEddie Cai 	file = fopen(spl, "rb");
2224d71e8c20SEddie Cai 	if( !file ){
2225d71e8c20SEddie Cai 		return;
2226d71e8c20SEddie Cai 	}
2227d71e8c20SEddie Cai 	int iFileSize;
2228d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
2229d71e8c20SEddie Cai 	iFileSize = ftell(file);
2230d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
2231d71e8c20SEddie Cai 	char *Buf = NULL;
2232d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
2233d71e8c20SEddie Cai 	if (!Buf){
2234d71e8c20SEddie Cai 		fclose(file);
2235d71e8c20SEddie Cai 		return;
2236d71e8c20SEddie Cai 	}
2237d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
2238d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
2239d71e8c20SEddie Cai 	int iRead;
2240d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
2241d71e8c20SEddie Cai 	if (iRead != iFileSize){
2242d71e8c20SEddie Cai 		fclose(file);
2243d71e8c20SEddie Cai 		delete []Buf;
2244d71e8c20SEddie Cai 		return;
2245d71e8c20SEddie Cai 	}
2246d71e8c20SEddie Cai 	fclose(file);
2247d71e8c20SEddie Cai 
2248d71e8c20SEddie Cai 	len = strlen(spl);
224932268622SAndreas Färber 	char *taggedspl = new char[len + 5];
225032268622SAndreas Färber 	strcpy(taggedspl, spl);
225132268622SAndreas Färber 	strcpy(taggedspl + len, ".tag");
225232268622SAndreas Färber 	taggedspl[len+4] = 0;
225332268622SAndreas Färber 	printf("Writing tagged spl to %s\n", taggedspl);
2254d71e8c20SEddie Cai 
225532268622SAndreas Färber 	file = fopen(taggedspl, "wb");
2256d71e8c20SEddie Cai 	if( !file ){
225732268622SAndreas Färber 		delete []taggedspl;
2258d71e8c20SEddie Cai 		delete []Buf;
2259d71e8c20SEddie Cai 		return;
2260d71e8c20SEddie Cai 	}
2261d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
2262d71e8c20SEddie Cai 	fclose(file);
226332268622SAndreas Färber 	delete []taggedspl;
2264d71e8c20SEddie Cai 	delete []Buf;
2265d71e8c20SEddie Cai 	printf("done\n");
2266d71e8c20SEddie Cai 	return;
2267d71e8c20SEddie Cai }
2268d71e8c20SEddie Cai 
226976af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
227076af099aSliuyi {
227176af099aSliuyi 	string strCmd;
227276af099aSliuyi 	strCmd = argv[1];
227376af099aSliuyi 	ssize_t cnt;
227476af099aSliuyi 	bool bRet,bSuccess = false;
22758df2d64aSEddie Cai 	char *s;
22768df2d64aSEddie Cai 	int i, ret;
227776af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
227876af099aSliuyi 
227976af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
22808df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
22818df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
22828df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
228378884ef4SEddie Cai 
22848df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
228576af099aSliuyi 		usage();
228676af099aSliuyi 		return true;
22878df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
2288c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
228976af099aSliuyi 		return true;
229078884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
229178884ef4SEddie Cai 		mergeBoot();
229278884ef4SEddie Cai 
229378884ef4SEddie Cai 		return true;
229478884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
229578884ef4SEddie Cai 		string strLoader = argv[2];
229678884ef4SEddie Cai 
229778884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
229878884ef4SEddie Cai 		return true;
2299d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
2300d71e8c20SEddie Cai 		if (argc == 4) {
2301d71e8c20SEddie Cai 			string tag = argv[2];
2302d71e8c20SEddie Cai 			string spl = argv[3];
2303d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
2304d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
2305d71e8c20SEddie Cai 			return true;
2306d71e8c20SEddie Cai 		}
2307d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
2308d71e8c20SEddie Cai 		usage();
230976af099aSliuyi 	}
231076af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
231176af099aSliuyi 	if (cnt < 1) {
231276af099aSliuyi 		ERROR_COLOR_ATTR;
231332268622SAndreas Färber 		printf("Did not find any rockusb device, please plug device in!");
231476af099aSliuyi 		NORMAL_COLOR_ATTR;
231576af099aSliuyi 		printf("\r\n");
231676af099aSliuyi 		return bSuccess;
231776af099aSliuyi 	} else if (cnt > 1) {
231876af099aSliuyi 		ERROR_COLOR_ATTR;
231932268622SAndreas Färber 		printf("Found too many rockusb devices, please plug devices out!");
232076af099aSliuyi 		NORMAL_COLOR_ATTR;
232176af099aSliuyi 		printf("\r\n");
232276af099aSliuyi 		return bSuccess;
232376af099aSliuyi 	}
232476af099aSliuyi 
232576af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
232676af099aSliuyi 	if (!bRet) {
232776af099aSliuyi 		ERROR_COLOR_ATTR;
232832268622SAndreas Färber 		printf("Getting information about rockusb device failed!");
232976af099aSliuyi 		NORMAL_COLOR_ATTR;
233076af099aSliuyi 		printf("\r\n");
233176af099aSliuyi 		return bSuccess;
233276af099aSliuyi 	}
233376af099aSliuyi 
233476af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
233576af099aSliuyi 		if ((argc != 2) && (argc != 3))
233676af099aSliuyi 			printf("Parameter of [RD] command is invalid, please check help!\r\n");
233776af099aSliuyi 		else {
233876af099aSliuyi 			if (argc == 2)
233976af099aSliuyi 				bSuccess = reset_device(dev);
234076af099aSliuyi 			else {
234176af099aSliuyi 				UINT uiSubCode;
234276af099aSliuyi 				char *pszEnd;
234376af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
234476af099aSliuyi 				if (*pszEnd)
234576af099aSliuyi 					printf("Subcode is invalid, please check!\r\n");
234676af099aSliuyi 				else {
234776af099aSliuyi 					if (uiSubCode <= 5)
234876af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
234976af099aSliuyi 					else
235076af099aSliuyi 						printf("Subcode is invalid, please check!\r\n");
235176af099aSliuyi 				}
235276af099aSliuyi 			}
235376af099aSliuyi 		}
235476af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
235576af099aSliuyi 		bSuccess = test_device(dev);
235676af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
235776af099aSliuyi 		bSuccess = read_flash_id(dev);
235876af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
235976af099aSliuyi 		bSuccess = read_flash_info(dev);
236076af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
236176af099aSliuyi 		bSuccess = read_chip_info(dev);
236276af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
236376af099aSliuyi 		if (argc > 2) {
236476af099aSliuyi 			string strLoader;
236576af099aSliuyi 			strLoader = argv[2];
236676af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
236776af099aSliuyi 		} else if (argc == 2) {
2368*c29e5f0fSliuyi 			ret = find_config_item(g_ConfigItemVec, "loader");
236976af099aSliuyi 			if (ret == -1)
237032268622SAndreas Färber 				printf("Did not find loader item in config!\r\n");
237176af099aSliuyi 			else
237276af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
237376af099aSliuyi 		} else
237476af099aSliuyi 			printf("Parameter of [DB] command is invalid, please check help!\r\n");
2375c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
2376c30d921cSKever Yang 		if (argc > 2) {
2377c30d921cSKever Yang 			string strParameter;
2378c30d921cSKever Yang 			strParameter = argv[2];
2379c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
2380c30d921cSKever Yang 		} else
2381c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid, please check help!\r\n");
2382c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
2383c30d921cSKever Yang 		if (argc > 2) {
2384c30d921cSKever Yang 			string strLoader;
2385c30d921cSKever Yang 			strLoader = argv[2];
2386c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
2387c30d921cSKever Yang 		} else
2388c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid, please check help!\r\n");
238976af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
239076af099aSliuyi 		if (argc == 2) {
239176af099aSliuyi 			bSuccess = erase_flash(dev);
239276af099aSliuyi 		} else
239376af099aSliuyi 			printf("Parameter of [EF] command is invalid, please check help!\r\n");
239476af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
239576af099aSliuyi 		if (argc == 4) {
239676af099aSliuyi 			UINT uiBegin;
239776af099aSliuyi 			char *pszEnd;
239876af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
239976af099aSliuyi 			if (*pszEnd)
240076af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
240176af099aSliuyi 			else
240276af099aSliuyi 				bSuccess = write_lba(dev, uiBegin, argv[3]);
240376af099aSliuyi 		} else
240476af099aSliuyi 			printf("Parameter of [WL] command is invalid, please check help!\r\n");
240576af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
240676af099aSliuyi 		char *pszEnd;
240776af099aSliuyi 		UINT uiBegin, uiLen;
240876af099aSliuyi 		if (argc != 5)
240976af099aSliuyi 			printf("Parameter of [RL] command is invalid, please check help!\r\n");
241076af099aSliuyi 		else {
241176af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
241276af099aSliuyi 			if (*pszEnd)
241376af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
241476af099aSliuyi 			else {
241576af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
241676af099aSliuyi 				if (*pszEnd)
241776af099aSliuyi 					printf("Len is invalid, please check!\r\n");
241876af099aSliuyi 				else {
241976af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
242076af099aSliuyi 				}
242176af099aSliuyi 			}
242276af099aSliuyi 		}
242376af099aSliuyi 	} else {
24249bc231bdSAndreas Färber 		printf("command is invalid!\r\n");
24259bc231bdSAndreas Färber 		usage();
242676af099aSliuyi 	}
242776af099aSliuyi 	return bSuccess;
242876af099aSliuyi }
242976af099aSliuyi 
243076af099aSliuyi 
243176af099aSliuyi int main(int argc, char* argv[])
243276af099aSliuyi {
243376af099aSliuyi 	CRKScan *pScan = NULL;
243476af099aSliuyi 	int ret;
243576af099aSliuyi 	char szProgramProcPath[100];
243676af099aSliuyi 	char szProgramDir[256];
243776af099aSliuyi 	string strLogDir,strConfigFile;
243876af099aSliuyi 	struct stat statBuf;
243976af099aSliuyi 
244076af099aSliuyi 	g_ConfigItemVec.clear();
244176af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
244276af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
244376af099aSliuyi 		strcpy(szProgramDir, ".");
244476af099aSliuyi 	else {
244576af099aSliuyi 		char *pSlash;
244676af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
244776af099aSliuyi 		if (pSlash)
244876af099aSliuyi 			*pSlash = '\0';
244976af099aSliuyi 	}
245076af099aSliuyi 	strLogDir = szProgramDir;
245176af099aSliuyi 	strLogDir +=  "/log/";
245276af099aSliuyi 	strConfigFile = szProgramDir;
245376af099aSliuyi 	strConfigFile += "/config.ini";
245476af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
245576af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
2456e5ee8cc0Sliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
245776af099aSliuyi 
245876af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
245976af099aSliuyi 		if (g_pLogObject) {
246076af099aSliuyi 			g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
246176af099aSliuyi 		}
246276af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
246376af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
246476af099aSliuyi 	}
246576af099aSliuyi 
246676af099aSliuyi 	ret = libusb_init(NULL);
246776af099aSliuyi 	if (ret < 0) {
246876af099aSliuyi 		if (g_pLogObject) {
246976af099aSliuyi 			g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
247076af099aSliuyi 			delete g_pLogObject;
247176af099aSliuyi 		}
247276af099aSliuyi 		return -1;
247376af099aSliuyi 	}
247476af099aSliuyi 
247576af099aSliuyi 	pScan = new CRKScan();
247676af099aSliuyi 	if (!pScan) {
247776af099aSliuyi 		if (g_pLogObject) {
247832268622SAndreas Färber 			g_pLogObject->Record("Error: failed to create object for searching device");
247976af099aSliuyi 			delete g_pLogObject;
248076af099aSliuyi 		}
248176af099aSliuyi 		libusb_exit(NULL);
248276af099aSliuyi 		return -2;
248376af099aSliuyi 	}
248476af099aSliuyi 	pScan->SetVidPid();
248576af099aSliuyi 
248676af099aSliuyi 	if (argc == 1)
248776af099aSliuyi 		usage();
248876af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
248976af099aSliuyi 			return -0xFF;
249076af099aSliuyi 	if (pScan)
249176af099aSliuyi 		delete pScan;
249276af099aSliuyi 	if (g_pLogObject)
249376af099aSliuyi 		delete g_pLogObject;
249476af099aSliuyi 	libusb_exit(NULL);
249576af099aSliuyi 	return 0;
249676af099aSliuyi }
2497