xref: /rkdeveloptool/main.cpp (revision b38fe5fc11d9a366abba1cd9ee58e5b1f9b88874)
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 }
21676af099aSliuyi int find_config_item(const char *pszName)
21776af099aSliuyi {
21876af099aSliuyi 	unsigned int i;
21976af099aSliuyi 	for(i = 0; i < g_ConfigItemVec.size(); i++){
22076af099aSliuyi 		if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){
22176af099aSliuyi 			return i;
22276af099aSliuyi 		}
22376af099aSliuyi 	}
22476af099aSliuyi 	return -1;
22576af099aSliuyi }
22676af099aSliuyi 
22776af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
22876af099aSliuyi {
22976af099aSliuyi 
23076af099aSliuyi 	stringstream configStream(pConfig);
23176af099aSliuyi 	string strLine, strItemName, strItemValue;
23276af099aSliuyi 	string::size_type line_size,pos;
23376af099aSliuyi 	STRUCT_CONFIG_ITEM item;
23476af099aSliuyi 	vecItem.clear();
23576af099aSliuyi 	while (!configStream.eof()){
23676af099aSliuyi 		getline(configStream, strLine);
23776af099aSliuyi 		line_size = strLine.size();
23876af099aSliuyi 		if (line_size == 0)
23976af099aSliuyi 			continue;
24076af099aSliuyi 		if (strLine[line_size-1] == '\r'){
24176af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
24276af099aSliuyi 		}
243c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
244c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
245c30d921cSKever Yang 		if (strLine.size()==0 )
246c30d921cSKever Yang 			continue;
247c30d921cSKever Yang 		if (strLine[0] == '#')
248c30d921cSKever Yang 			continue;
24976af099aSliuyi 		pos = strLine.find("=");
25076af099aSliuyi 		if (pos == string::npos){
25176af099aSliuyi 			continue;
25276af099aSliuyi 		}
25376af099aSliuyi 		strItemName = strLine.substr(0, pos);
25476af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
25576af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
25676af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
25776af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
25876af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
25976af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
26076af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
26176af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
26276af099aSliuyi 			vecItem.push_back(item);
26376af099aSliuyi 		}
26476af099aSliuyi 	}
26576af099aSliuyi 	return true;
26676af099aSliuyi 
26776af099aSliuyi }
26876af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
26976af099aSliuyi {
27076af099aSliuyi 	FILE *file = NULL;
27176af099aSliuyi 	file = fopen(pConfigFile, "rb");
27276af099aSliuyi 	if( !file ){
27376af099aSliuyi 		if (g_pLogObject)
27432268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile);
27576af099aSliuyi 		return false;
27676af099aSliuyi 	}
27776af099aSliuyi 	int iFileSize;
27876af099aSliuyi 	fseek(file, 0, SEEK_END);
27976af099aSliuyi 	iFileSize = ftell(file);
28076af099aSliuyi 	fseek(file, 0, SEEK_SET);
28176af099aSliuyi 	char *pConfigBuf = NULL;
28276af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
28376af099aSliuyi 	if (!pConfigBuf){
28476af099aSliuyi 		fclose(file);
28576af099aSliuyi 		return false;
28676af099aSliuyi 	}
28776af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
28876af099aSliuyi 	int iRead;
28976af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
29076af099aSliuyi 	if (iRead != iFileSize){
29176af099aSliuyi 		if (g_pLogObject)
29232268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize);
29376af099aSliuyi 		fclose(file);
29476af099aSliuyi 		delete []pConfigBuf;
29576af099aSliuyi 		return false;
29676af099aSliuyi 	}
29776af099aSliuyi 	fclose(file);
29876af099aSliuyi 	bool bRet;
29976af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
30076af099aSliuyi 	delete []pConfigBuf;
30176af099aSliuyi 	return bRet;
30276af099aSliuyi }
303c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
304c30d921cSKever Yang {
305c30d921cSKever Yang 	string::size_type pos,prevPos;
306c30d921cSKever Yang 	string strOffset,strLen;
307c30d921cSKever Yang 	int iCount;
308c30d921cSKever Yang 	prevPos = pos = 0;
309c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
310c30d921cSKever Yang 		return false;
311c30d921cSKever Yang 	}
312c30d921cSKever Yang 	pos = strPartInfo.find('@');
313c30d921cSKever Yang 	if (pos == string::npos) {
314c30d921cSKever Yang 		return false;
315c30d921cSKever Yang 	}
316c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
317c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
318c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
319c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
320c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
321c30d921cSKever Yang 	} else {
322c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
323c30d921cSKever Yang 		if (iCount != 1) {
324c30d921cSKever Yang 			return false;
325c30d921cSKever Yang 		}
326c30d921cSKever Yang 	}
327c30d921cSKever Yang 
328c30d921cSKever Yang 	prevPos = pos + 1;
329c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
330c30d921cSKever Yang 	if (pos == string::npos) {
331c30d921cSKever Yang 		return false;
332c30d921cSKever Yang 	}
333c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
334c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
335c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
336c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
337c30d921cSKever Yang 	if (iCount != 1) {
338c30d921cSKever Yang 		return false;
339c30d921cSKever Yang 	}
340c30d921cSKever Yang 	prevPos = pos + 1;
341c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
342c30d921cSKever Yang 	if (pos == string::npos) {
343c30d921cSKever Yang 		return false;
344c30d921cSKever Yang 	}
345c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
346c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
347c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
348c30d921cSKever Yang 
349c30d921cSKever Yang 	return true;
350c30d921cSKever Yang }
351c30d921cSKever Yang 
352c30d921cSKever Yang bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem)
353c30d921cSKever Yang {
354c30d921cSKever Yang 	stringstream paramStream(pParameter);
355c30d921cSKever Yang 	bool bRet,bFind = false;
356c30d921cSKever Yang 	string strLine, strPartition, strPartInfo, strPartName;
357c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
358c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
359c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
360c30d921cSKever Yang 	vecItem.clear();
361c30d921cSKever Yang 	while (!paramStream.eof()) {
362c30d921cSKever Yang 		getline(paramStream,strLine);
363c30d921cSKever Yang 		line_size = strLine.size();
364c30d921cSKever Yang 		if (line_size == 0)
365c30d921cSKever Yang 			continue;
366c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
367c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
368c30d921cSKever Yang 		}
369c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
370c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
371c30d921cSKever Yang 		if (strLine.size()==0 )
372c30d921cSKever Yang 			continue;
373c30d921cSKever Yang 		if (strLine[0] == '#')
374c30d921cSKever Yang 			continue;
375c30d921cSKever Yang 		pos = strLine.find("mtdparts");
376c30d921cSKever Yang 		if (pos == string::npos) {
377c30d921cSKever Yang 			continue;
378c30d921cSKever Yang 		}
379c30d921cSKever Yang 		bFind = true;
380c30d921cSKever Yang 		posColon = strLine.find(':', pos);
381c30d921cSKever Yang 		if (posColon == string::npos) {
382c30d921cSKever Yang 			continue;
383c30d921cSKever Yang 		}
384c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
385c30d921cSKever Yang 		pos = 0;
386c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
387c30d921cSKever Yang 		while (posComma != string::npos) {
388c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
389c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
390c30d921cSKever Yang 			if (bRet) {
391c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
392c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
393c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
394c30d921cSKever Yang 				vecItem.push_back(item);
395c30d921cSKever Yang 			}
396c30d921cSKever Yang 			pos = posComma + 1;
397c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
398c30d921cSKever Yang 		}
399c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
400c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
401c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
402c30d921cSKever Yang 			if (bRet) {
403c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
404c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
405c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
406c30d921cSKever Yang 				vecItem.push_back(item);
407c30d921cSKever Yang 			}
408c30d921cSKever Yang 		}
409c30d921cSKever Yang 		break;
410c30d921cSKever Yang 	}
411c30d921cSKever Yang 	return bFind;
412c30d921cSKever Yang 
413c30d921cSKever Yang }
414c30d921cSKever Yang bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem)
415c30d921cSKever Yang {
416c30d921cSKever Yang 	FILE *file = NULL;
417c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
418c30d921cSKever Yang 	if( !file ) {
419c30d921cSKever Yang 		if (g_pLogObject)
42032268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
421c30d921cSKever Yang 		return false;
422c30d921cSKever Yang 	}
423c30d921cSKever Yang 	int iFileSize;
424c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
425c30d921cSKever Yang 	iFileSize = ftell(file);
426c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
427c30d921cSKever Yang 	char *pParamBuf = NULL;
428c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
429c30d921cSKever Yang 	if (!pParamBuf) {
430c30d921cSKever Yang 		fclose(file);
431c30d921cSKever Yang 		return false;
432c30d921cSKever Yang 	}
433c30d921cSKever Yang 	int iRead;
434c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
435c30d921cSKever Yang 	if (iRead != iFileSize) {
436c30d921cSKever Yang 		if (g_pLogObject)
43732268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
438c30d921cSKever Yang 		fclose(file);
439c30d921cSKever Yang 		delete []pParamBuf;
440c30d921cSKever Yang 		return false;
441c30d921cSKever Yang 	}
442c30d921cSKever Yang 	fclose(file);
443c30d921cSKever Yang 	bool bRet;
444c30d921cSKever Yang 	bRet = parse_parameter(pParamBuf, vecItem);
445c30d921cSKever Yang 	delete []pParamBuf;
446c30d921cSKever Yang 	return bRet;
447c30d921cSKever Yang }
448c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
449c30d921cSKever Yang {
450c30d921cSKever Yang 	efi_guid_t id;
451c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
452c30d921cSKever Yang 	unsigned int i;
453c30d921cSKever Yang 
454c30d921cSKever Yang 	/* Set all fields randomly */
455c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
456c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
457c30d921cSKever Yang 
458c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
459c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
460c30d921cSKever Yang 
461c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
462c30d921cSKever Yang }
463c30d921cSKever Yang 
464c30d921cSKever Yang void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, u64 diskSectors)
465c30d921cSKever Yang {
466c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
467c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
468c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
469c30d921cSKever Yang 	u32 i,j;
470c30d921cSKever Yang 	string strPartName;
471c30d921cSKever Yang 	string::size_type colonPos;
472c30d921cSKever Yang 	/*1.protective mbr*/
473c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
474c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
475c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
476c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
477c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
478c30d921cSKever Yang 	/*2.gpt header*/
479c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
480c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
481c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
482c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
483c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
484c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
485c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
486c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
487c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
488c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
489c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
490c30d921cSKever Yang 	gptHead->header_crc32 = 0;
491c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
492c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
493c30d921cSKever Yang 
494c30d921cSKever Yang 	/*3.gpt partition entry*/
495c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
496c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
497c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
498c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
499c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
500c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
501c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
502c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
503c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
504c30d921cSKever Yang 		if (colonPos != string::npos) {
505c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
506c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
507c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
508c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
509c30d921cSKever Yang 		}
510c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
511c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
512c30d921cSKever Yang 		gptEntry++;
513c30d921cSKever Yang 	}
514c30d921cSKever Yang 
515c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
516c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
517c30d921cSKever Yang 
518c30d921cSKever Yang }
519*b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
520c30d921cSKever Yang {
521c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
522c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
523c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
524c30d921cSKever Yang 
525c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
526*b38fe5fcSliuyi 	pSec0->uiRc4Flag = rc4Flag;
527c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
528c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
529c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
530c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
531c30d921cSKever Yang 	return true;
532c30d921cSKever Yang }
533c30d921cSKever Yang 
534c30d921cSKever Yang 
535c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
536c30d921cSKever Yang {
537c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
538c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
539c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
540c30d921cSKever Yang 
541c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
542c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
543c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
544c30d921cSKever Yang 	return true;
545c30d921cSKever Yang }
546c30d921cSKever Yang 
547c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
548c30d921cSKever Yang {
549c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
550c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
551c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
552c30d921cSKever Yang 
553c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
554c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
555c30d921cSKever Yang 	return true;
556c30d921cSKever Yang }
557c30d921cSKever Yang 
558c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
559c30d921cSKever Yang {
560c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
561c30d921cSKever Yang 	return true;
562c30d921cSKever Yang }
563c30d921cSKever Yang 
564*b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
565c30d921cSKever Yang {
566c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
567c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
568c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
569c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
570c30d921cSKever Yang 	UINT i;
571*b38fe5fcSliuyi 	printf("rc4=%d\r\n\r\n\r\n",rc4Flag);
572*b38fe5fcSliuyi 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
573c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
574c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
575c30d921cSKever Yang 		return -6;
576c30d921cSKever Yang 	}
577c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
578c30d921cSKever Yang 		return -7;
579c30d921cSKever Yang 	}
580c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
581c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
582c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
583c30d921cSKever Yang 
584c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
585c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
586c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
587*b38fe5fcSliuyi 
588*b38fe5fcSliuyi 	if (rc4Flag) {
589*b38fe5fcSliuyi 		for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
590*b38fe5fcSliuyi 			P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
591*b38fe5fcSliuyi 		for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
592*b38fe5fcSliuyi 			P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
593*b38fe5fcSliuyi 	}
594*b38fe5fcSliuyi 
595c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
596c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
597c30d921cSKever Yang 
598c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
599c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
600c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
601c30d921cSKever Yang 		if(i == 1) {
602c30d921cSKever Yang 			continue;
603c30d921cSKever Yang 		} else {
604c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
605c30d921cSKever Yang 		}
606c30d921cSKever Yang 	}
607c30d921cSKever Yang 	return 0;
608c30d921cSKever Yang }
609c30d921cSKever Yang 
610c30d921cSKever Yang 
61176af099aSliuyi 
61276af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
61376af099aSliuyi {
61476af099aSliuyi 	if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
61576af099aSliuyi 		return true;
61676af099aSliuyi 	else
61776af099aSliuyi 	{
61876af099aSliuyi 		ERROR_COLOR_ATTR;
61932268622SAndreas Färber 		printf("The device does not support this operation!");
62076af099aSliuyi 		NORMAL_COLOR_ATTR;
62176af099aSliuyi 		printf("\r\n");
62276af099aSliuyi 		return false;
62376af099aSliuyi 	}
62476af099aSliuyi }
625c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
626c30d921cSKever Yang {
627c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
628c30d921cSKever Yang 	u32 total_size_sector;
629c30d921cSKever Yang 	CRKComm *pComm = NULL;
630c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
631c30d921cSKever Yang 	int iRet;
632c30d921cSKever Yang 	bool bRet, bSuccess = false;
633c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
634c30d921cSKever Yang 		return false;
635c30d921cSKever Yang 
636c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
637c30d921cSKever Yang 	if (!bRet) {
638c30d921cSKever Yang 		ERROR_COLOR_ATTR;
639c30d921cSKever Yang 		printf("Creating Comm Object failed!");
640c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
641c30d921cSKever Yang 		printf("\r\n");
642c30d921cSKever Yang 		return bSuccess;
643c30d921cSKever Yang 	}
64432268622SAndreas Färber 	printf("Writing gpt...\r\n");
645c30d921cSKever Yang 	//1.get flash info
646c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
647c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
648c30d921cSKever Yang 		ERROR_COLOR_ATTR;
649c30d921cSKever Yang 		printf("Reading Flash Info failed!");
650c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
651c30d921cSKever Yang 		printf("\r\n");
652c30d921cSKever Yang 		return bSuccess;
653c30d921cSKever Yang 	}
654c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
655c30d921cSKever Yang 	//2.get partition from parameter
656c30d921cSKever Yang 	bRet = parse_parameter_file(szParameter, vecItems);
657c30d921cSKever Yang 	if (!bRet) {
658c30d921cSKever Yang 		ERROR_COLOR_ATTR;
659c30d921cSKever Yang 		printf("Parsing parameter failed!");
660c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
661c30d921cSKever Yang 		printf("\r\n");
662c30d921cSKever Yang 		return bSuccess;
663c30d921cSKever Yang 	}
664c30d921cSKever Yang 	vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 34;
665c30d921cSKever Yang 	//3.generate gpt info
666c30d921cSKever Yang 	create_gpt_buffer(master_gpt, vecItems, total_size_sector);
667c30d921cSKever Yang 	memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
668c30d921cSKever Yang 	memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
669c30d921cSKever Yang 	//4. write gpt
670c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
671c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
672c30d921cSKever Yang 		ERROR_COLOR_ATTR;
673c30d921cSKever Yang 		printf("Writing master gpt failed!");
674c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
675c30d921cSKever Yang 		printf("\r\n");
676c30d921cSKever Yang 		return bSuccess;
677c30d921cSKever Yang 	}
678c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(total_size_sector - 34, 33, backup_gpt);
679c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
680c30d921cSKever Yang 		ERROR_COLOR_ATTR;
681c30d921cSKever Yang 		printf("Writing backup gpt failed!");
682c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
683c30d921cSKever Yang 		printf("\r\n");
684c30d921cSKever Yang 		return bSuccess;
685c30d921cSKever Yang 	}
686c30d921cSKever Yang 	bSuccess = true;
687c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
688c30d921cSKever Yang 	CURSOR_DEL_LINE;
68932268622SAndreas Färber 	printf("Writing gpt succeeded.\r\n");
690c30d921cSKever Yang 	return bSuccess;
691c30d921cSKever Yang }
69276af099aSliuyi 
69378884ef4SEddie Cai #include "boot_merger.h"
69478884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
69578884ef4SEddie Cai options gOpts;
69678884ef4SEddie Cai 
69778884ef4SEddie Cai 
69878884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
69978884ef4SEddie Cai char* gConfigPath;
70078884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
70178884ef4SEddie Cai 
70278884ef4SEddie Cai static inline void fixPath(char* path) {
70378884ef4SEddie Cai 	int i, len = strlen(path);
70478884ef4SEddie Cai 	for(i=0; i<len; i++) {
70578884ef4SEddie Cai 		if (path[i] == '\\')
70678884ef4SEddie Cai 			path[i] = '/';
70778884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
70878884ef4SEddie Cai 			path[i] = '\0';
70978884ef4SEddie Cai 	}
71078884ef4SEddie Cai }
71178884ef4SEddie Cai 
71278884ef4SEddie Cai static bool parseChip(FILE* file) {
71378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
71478884ef4SEddie Cai 		return false;
71578884ef4SEddie Cai 	}
71678884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
71778884ef4SEddie Cai 		return false;
71878884ef4SEddie Cai 	}
71978884ef4SEddie Cai 	printf("chip: %s\n", gOpts.chip);
72078884ef4SEddie Cai 	return true;
72178884ef4SEddie Cai }
72278884ef4SEddie Cai 
72378884ef4SEddie Cai static bool parseVersion(FILE* file) {
72478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
72578884ef4SEddie Cai 		return false;
72678884ef4SEddie Cai 	}
72778884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
72878884ef4SEddie Cai 		return false;
72978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
73078884ef4SEddie Cai 		return false;
73178884ef4SEddie Cai 	}
73278884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
73378884ef4SEddie Cai 		return false;
73478884ef4SEddie Cai 	printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
73578884ef4SEddie Cai 	return true;
73678884ef4SEddie Cai }
73778884ef4SEddie Cai 
73878884ef4SEddie Cai static bool parse471(FILE* file) {
73978884ef4SEddie Cai 	int i, index, pos;
74078884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
74178884ef4SEddie Cai 
74278884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
74378884ef4SEddie Cai 		return false;
74478884ef4SEddie Cai 	}
74578884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
74678884ef4SEddie Cai 		return false;
74778884ef4SEddie Cai 	printf("num: %d\n", gOpts.code471Num);
74878884ef4SEddie Cai 	if (!gOpts.code471Num)
74978884ef4SEddie Cai 		return true;
75078884ef4SEddie Cai 	if (gOpts.code471Num < 0)
75178884ef4SEddie Cai 		return false;
75278884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
75378884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
75478884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
75578884ef4SEddie Cai 			return false;
75678884ef4SEddie Cai 		}
75778884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
75878884ef4SEddie Cai 				!= 2)
75978884ef4SEddie Cai 			return false;
76078884ef4SEddie Cai 		index--;
76178884ef4SEddie Cai 		fixPath(buf);
76278884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
76378884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code471Path[index]);
76478884ef4SEddie Cai 	}
76578884ef4SEddie Cai 	pos = ftell(file);
76678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
76778884ef4SEddie Cai 		return false;
76878884ef4SEddie Cai 	}
76978884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
77078884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
77178884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code471Sleep);
77278884ef4SEddie Cai 	return true;
77378884ef4SEddie Cai }
77478884ef4SEddie Cai 
77578884ef4SEddie Cai static bool parse472(FILE* file) {
77678884ef4SEddie Cai 	int i, index, pos;
77778884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
77878884ef4SEddie Cai 
77978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
78078884ef4SEddie Cai 		return false;
78178884ef4SEddie Cai 	}
78278884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
78378884ef4SEddie Cai 		return false;
78478884ef4SEddie Cai 	printf("num: %d\n", gOpts.code472Num);
78578884ef4SEddie Cai 	if (!gOpts.code472Num)
78678884ef4SEddie Cai 		return true;
78778884ef4SEddie Cai 	if (gOpts.code472Num < 0)
78878884ef4SEddie Cai 		return false;
78978884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
79078884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
79178884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
79278884ef4SEddie Cai 			return false;
79378884ef4SEddie Cai 		}
79478884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
79578884ef4SEddie Cai 				!= 2)
79678884ef4SEddie Cai 			return false;
79778884ef4SEddie Cai 		fixPath(buf);
79878884ef4SEddie Cai 		index--;
79978884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
80078884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code472Path[index]);
80178884ef4SEddie Cai 	}
80278884ef4SEddie Cai 	pos = ftell(file);
80378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
80478884ef4SEddie Cai 		return false;
80578884ef4SEddie Cai 	}
80678884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
80778884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
80878884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code472Sleep);
80978884ef4SEddie Cai 	return true;
81078884ef4SEddie Cai }
81178884ef4SEddie Cai 
81278884ef4SEddie Cai static bool parseLoader(FILE* file) {
81378884ef4SEddie Cai 	int i, j, index, pos;
81478884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
81578884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
81678884ef4SEddie Cai 
81778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
81878884ef4SEddie Cai 		return false;
81978884ef4SEddie Cai 	}
82078884ef4SEddie Cai 	pos = ftell(file);
82178884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
82278884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
82378884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
82478884ef4SEddie Cai 			return false;
82578884ef4SEddie Cai 		}
82678884ef4SEddie Cai 	}
82778884ef4SEddie Cai 	printf("num: %d\n", gOpts.loaderNum);
82878884ef4SEddie Cai 	if (!gOpts.loaderNum)
82978884ef4SEddie Cai 		return false;
83078884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
83178884ef4SEddie Cai 		return false;
83278884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
83378884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
83478884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
83578884ef4SEddie Cai 			return false;
83678884ef4SEddie Cai 		}
83778884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
83878884ef4SEddie Cai 				!= 2)
83978884ef4SEddie Cai 			return false;
84078884ef4SEddie Cai 		index--;
84178884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
84278884ef4SEddie Cai 		printf("name%d: %s\n", index, gOpts.loader[index].name);
84378884ef4SEddie Cai 	}
84478884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
84578884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
84678884ef4SEddie Cai 			return false;
84778884ef4SEddie Cai 		}
84878884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
84978884ef4SEddie Cai 				!= 2)
85078884ef4SEddie Cai 			return false;
85178884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
85278884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
85378884ef4SEddie Cai 				fixPath(buf2);
85478884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
85578884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
85678884ef4SEddie Cai 				break;
85778884ef4SEddie Cai 			}
85878884ef4SEddie Cai 		}
85978884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
86078884ef4SEddie Cai 			return false;
86178884ef4SEddie Cai 		}
86278884ef4SEddie Cai 	}
86378884ef4SEddie Cai 	return true;
86478884ef4SEddie Cai }
86578884ef4SEddie Cai 
86678884ef4SEddie Cai static bool parseOut(FILE* file) {
86778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
86878884ef4SEddie Cai 		return false;
86978884ef4SEddie Cai 	}
87078884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
87178884ef4SEddie Cai 		return false;
87278884ef4SEddie Cai 	fixPath(gOpts.outPath);
87378884ef4SEddie Cai 	printf("out: %s\n", gOpts.outPath);
87478884ef4SEddie Cai 	return true;
87578884ef4SEddie Cai }
87678884ef4SEddie Cai 
87778884ef4SEddie Cai 
87878884ef4SEddie Cai void printOpts(FILE* out) {
87978884ef4SEddie Cai 	int i;
88078884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
88178884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
88278884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
88378884ef4SEddie Cai 
88478884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
88578884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
88678884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
88778884ef4SEddie Cai 	}
88878884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
88978884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
89078884ef4SEddie Cai 
89178884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
89278884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
89378884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
89478884ef4SEddie Cai 	}
89578884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
89678884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
89778884ef4SEddie Cai 
89878884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
89978884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
90078884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
90178884ef4SEddie Cai 	}
90278884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
90378884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
90478884ef4SEddie Cai 	}
90578884ef4SEddie Cai 
90678884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
90778884ef4SEddie Cai }
90878884ef4SEddie Cai 
90978884ef4SEddie Cai static bool parseOpts(void) {
91078884ef4SEddie Cai 	bool ret = false;
91178884ef4SEddie Cai 	bool chipOk = false;
91278884ef4SEddie Cai 	bool versionOk = false;
91378884ef4SEddie Cai 	bool code471Ok = true;
91478884ef4SEddie Cai 	bool code472Ok = true;
91578884ef4SEddie Cai 	bool loaderOk = false;
91678884ef4SEddie Cai 	bool outOk = false;
91778884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
91878884ef4SEddie Cai 
91978884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
92078884ef4SEddie Cai 	FILE* file;
92178884ef4SEddie Cai 	file = fopen(configPath, "r");
92278884ef4SEddie Cai 	if (!file) {
92378884ef4SEddie Cai 		fprintf(stderr, "config (%s) not found!\n", configPath);
92478884ef4SEddie Cai 		if (configPath == (char*)DEF_CONFIG_FILE) {
92578884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
92678884ef4SEddie Cai 			if (file) {
92732268622SAndreas Färber 				fprintf(stderr, "creating defconfig\n");
92878884ef4SEddie Cai 				printOpts(file);
92978884ef4SEddie Cai 			}
93078884ef4SEddie Cai 		}
93178884ef4SEddie Cai 		goto end;
93278884ef4SEddie Cai 	}
93378884ef4SEddie Cai 
93432268622SAndreas Färber 	printf("Starting to parse...\n");
93578884ef4SEddie Cai 
93678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
93778884ef4SEddie Cai 		goto end;
93878884ef4SEddie Cai 	}
93978884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
94078884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
94178884ef4SEddie Cai 			chipOk = parseChip(file);
94278884ef4SEddie Cai 			if (!chipOk) {
94378884ef4SEddie Cai 				printf("parseChip failed!\n");
94478884ef4SEddie Cai 				goto end;
94578884ef4SEddie Cai 			}
94678884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
94778884ef4SEddie Cai 			versionOk = parseVersion(file);
94878884ef4SEddie Cai 			if (!versionOk) {
94978884ef4SEddie Cai 				printf("parseVersion failed!\n");
95078884ef4SEddie Cai 				goto end;
95178884ef4SEddie Cai 			}
95278884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
95378884ef4SEddie Cai 			code471Ok = parse471(file);
95478884ef4SEddie Cai 			if (!code471Ok) {
95578884ef4SEddie Cai 				printf("parse471 failed!\n");
95678884ef4SEddie Cai 				goto end;
95778884ef4SEddie Cai 			}
95878884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
95978884ef4SEddie Cai 			code472Ok = parse472(file);
96078884ef4SEddie Cai 			if (!code472Ok) {
96178884ef4SEddie Cai 				printf("parse472 failed!\n");
96278884ef4SEddie Cai 				goto end;
96378884ef4SEddie Cai 			}
96478884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
96578884ef4SEddie Cai 			loaderOk = parseLoader(file);
96678884ef4SEddie Cai 			if (!loaderOk) {
96778884ef4SEddie Cai 				printf("parseLoader failed!\n");
96878884ef4SEddie Cai 				goto end;
96978884ef4SEddie Cai 			}
97078884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
97178884ef4SEddie Cai 			outOk = parseOut(file);
97278884ef4SEddie Cai 			if (!outOk) {
97378884ef4SEddie Cai 				printf("parseOut failed!\n");
97478884ef4SEddie Cai 				goto end;
97578884ef4SEddie Cai 			}
97678884ef4SEddie Cai 		} else if (buf[0] == '#') {
97778884ef4SEddie Cai 			continue;
97878884ef4SEddie Cai 		} else {
97978884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
98078884ef4SEddie Cai 			goto end;
98178884ef4SEddie Cai 		}
98278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
98378884ef4SEddie Cai 			goto end;
98478884ef4SEddie Cai 		}
98578884ef4SEddie Cai 	}
98678884ef4SEddie Cai 
98778884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
98878884ef4SEddie Cai 			&& loaderOk && outOk)
98978884ef4SEddie Cai 		ret = true;
99078884ef4SEddie Cai end:
99178884ef4SEddie Cai 	if (file)
99278884ef4SEddie Cai 		fclose(file);
99378884ef4SEddie Cai 	return ret;
99478884ef4SEddie Cai }
99578884ef4SEddie Cai 
99678884ef4SEddie Cai bool initOpts(void) {
99778884ef4SEddie Cai 	//set default opts
99878884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
99978884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
100078884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
100178884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
100278884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
100378884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
100478884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
100578884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
100678884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
100778884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
100878884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
100978884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
101078884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
101178884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
101278884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
101378884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
101478884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
101578884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
101678884ef4SEddie Cai 
101778884ef4SEddie Cai 	return parseOpts();
101878884ef4SEddie Cai }
101978884ef4SEddie Cai 
102078884ef4SEddie Cai /************merge code****************/
102178884ef4SEddie Cai 
102278884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
102378884ef4SEddie Cai 	uint8_t tmp[2] = {0};
102478884ef4SEddie Cai 	int i;
102578884ef4SEddie Cai 	uint32_t ret;
102678884ef4SEddie Cai 	//if (value > 0xFFFF) {
102778884ef4SEddie Cai 	//	return 0;
102878884ef4SEddie Cai 	//}
102978884ef4SEddie Cai 	for(i=0; i < 2; i++) {
103078884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
103178884ef4SEddie Cai 		value /= 100;
103278884ef4SEddie Cai 	}
103378884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
103478884ef4SEddie Cai 
103578884ef4SEddie Cai 	printf("ret: %x\n",ret);
103678884ef4SEddie Cai 	return ret&0xFF;
103778884ef4SEddie Cai }
103878884ef4SEddie Cai 
103978884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
104078884ef4SEddie Cai {
104178884ef4SEddie Cai 	int i;
104278884ef4SEddie Cai 	for (i = 0; i < len; i++) {
104378884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
104478884ef4SEddie Cai 	}
104578884ef4SEddie Cai 	wide[len] = 0;
104678884ef4SEddie Cai }
104778884ef4SEddie Cai 
104878884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
104978884ef4SEddie Cai 	char* end;
105078884ef4SEddie Cai 	char* start;
105178884ef4SEddie Cai 	int len;
105278884ef4SEddie Cai 	if (!path || !dst)
105378884ef4SEddie Cai 		return;
105478884ef4SEddie Cai 	start = strrchr(path, '/');
105578884ef4SEddie Cai 	if (!start)
105678884ef4SEddie Cai 		start = path;
105778884ef4SEddie Cai 	else
105878884ef4SEddie Cai 		start++;
105978884ef4SEddie Cai 	end = strrchr(path, '.');
1060641cfa16SEddie Cai 	if (!end || (end < start))
106178884ef4SEddie Cai 		end = path + strlen(path);
106278884ef4SEddie Cai 	len = end - start;
106378884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
106478884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
106578884ef4SEddie Cai 	str2wide(start, dst, len);
106678884ef4SEddie Cai 
106778884ef4SEddie Cai 
106878884ef4SEddie Cai 		char name[MAX_NAME_LEN];
106978884ef4SEddie Cai 		memset(name, 0, sizeof(name));
107078884ef4SEddie Cai 		memcpy(name, start, len);
107178884ef4SEddie Cai 		printf("path: %s, name: %s\n", path, name);
107278884ef4SEddie Cai 
107378884ef4SEddie Cai }
107478884ef4SEddie Cai 
107578884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
107678884ef4SEddie Cai 	struct stat st;
107778884ef4SEddie Cai 	if(stat(path, &st) < 0)
107878884ef4SEddie Cai 		return false;
107978884ef4SEddie Cai 	*size = st.st_size;
108078884ef4SEddie Cai 	printf("path: %s, size: %d\n", path, *size);
108178884ef4SEddie Cai 	return true;
108278884ef4SEddie Cai }
108378884ef4SEddie Cai 
108478884ef4SEddie Cai static inline rk_time getTime(void) {
108578884ef4SEddie Cai 	rk_time rkTime;
108678884ef4SEddie Cai 
108778884ef4SEddie Cai 	struct tm *tm;
108878884ef4SEddie Cai 	time_t tt = time(NULL);
108978884ef4SEddie Cai 	tm = localtime(&tt);
109078884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
109178884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
109278884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
109378884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
109478884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
109578884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
109678884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
109778884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
109878884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
109978884ef4SEddie Cai 	return rkTime;
110078884ef4SEddie Cai }
110178884ef4SEddie Cai 
110278884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
110378884ef4SEddie Cai 	bool ret = false;
110478884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
110578884ef4SEddie Cai 	uint8_t* buf;
110678884ef4SEddie Cai 
110778884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
110878884ef4SEddie Cai 	if (!inFile)
110978884ef4SEddie Cai 		goto end;
111078884ef4SEddie Cai 
111178884ef4SEddie Cai 	if (!getFileSize(path, &size))
111278884ef4SEddie Cai 		goto end;
111378884ef4SEddie Cai 	if (fix) {
111478884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
111578884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
111678884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
111778884ef4SEddie Cai 		fixSize +=tmp;
111878884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
111978884ef4SEddie Cai 	} else {
112078884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
112178884ef4SEddie Cai 	}
112278884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
112378884ef4SEddie Cai 		goto end;
112478884ef4SEddie Cai 
112578884ef4SEddie Cai 	if (fix) {
112678884ef4SEddie Cai 
112778884ef4SEddie Cai 		buf = gBuf;
112878884ef4SEddie Cai 		size = fixSize;
112978884ef4SEddie Cai 		while(1) {
113078884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
113178884ef4SEddie Cai 			buf += SMALL_PACKET;
113278884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
113378884ef4SEddie Cai 				break;
113478884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
113578884ef4SEddie Cai 		}
113678884ef4SEddie Cai 	} else {
113778884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
113878884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
113978884ef4SEddie Cai 		size +=tmp;
114078884ef4SEddie Cai 		P_RC4(gBuf, size);
114178884ef4SEddie Cai 	}
114278884ef4SEddie Cai 
114378884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
114478884ef4SEddie Cai 		goto end;
114578884ef4SEddie Cai 	ret = true;
114678884ef4SEddie Cai end:
114778884ef4SEddie Cai 	if (inFile)
114878884ef4SEddie Cai 		fclose(inFile);
114978884ef4SEddie Cai 	if (!ret)
115032268622SAndreas Färber 		printf("writing entry (%s) failed\n", path);
115178884ef4SEddie Cai 	return ret;
115278884ef4SEddie Cai }
115378884ef4SEddie Cai 
115478884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
115578884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
115678884ef4SEddie Cai 	uint32_t size;
115778884ef4SEddie Cai 	rk_boot_entry entry;
115878884ef4SEddie Cai 
115932268622SAndreas Färber 	printf("writing: %s\n", path);
1160641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
116178884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
116278884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
116378884ef4SEddie Cai 	entry.type = type;
116478884ef4SEddie Cai 	entry.dataOffset = *offset;
116578884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
116632268622SAndreas Färber 		printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
116778884ef4SEddie Cai 		return false;
116878884ef4SEddie Cai 	}
116978884ef4SEddie Cai 	if (fix)
117078884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
117178884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
117278884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
117332268622SAndreas Färber 	printf("alignment size: %d\n", size);
117478884ef4SEddie Cai 	entry.dataSize = size;
117578884ef4SEddie Cai 	entry.dataDelay = delay;
117678884ef4SEddie Cai 	*offset += size;
117778884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
117878884ef4SEddie Cai 	return true;
117978884ef4SEddie Cai }
118078884ef4SEddie Cai 
118178884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
118278884ef4SEddie Cai 	char buffer[5];
118378884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
118478884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
118578884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
118678884ef4SEddie Cai }
118778884ef4SEddie Cai 
118878884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
118978884ef4SEddie Cai 	printf("chip: %s\n", chip);
119078884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
119178884ef4SEddie Cai 	if(!chip) {
119278884ef4SEddie Cai 		goto end;
119378884ef4SEddie Cai 	}
119478884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
119578884ef4SEddie Cai 		chipType = RK28_DEVICE;
119678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
119778884ef4SEddie Cai 		chipType = RK28_DEVICE;
119878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
119978884ef4SEddie Cai 		chipType = RK281X_DEVICE;
120078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
120178884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
120278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
120378884ef4SEddie Cai 		chipType = RK27_DEVICE;
120478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
120578884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
120678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
120778884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
120878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
120978884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
121078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
121178884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
121278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
121378884ef4SEddie Cai 		chipType = RK29_DEVICE;
121478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
121578884ef4SEddie Cai 		chipType = RK292X_DEVICE;
121678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
121778884ef4SEddie Cai 		chipType = RK30_DEVICE;
121878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
121978884ef4SEddie Cai 		chipType = RK30B_DEVICE;
122078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
122178884ef4SEddie Cai 		chipType = RK31_DEVICE;
122278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
122378884ef4SEddie Cai 		chipType = RK32_DEVICE;
122478884ef4SEddie Cai 	} else {
122578884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
122678884ef4SEddie Cai 	}
122778884ef4SEddie Cai 
122878884ef4SEddie Cai end:
122978884ef4SEddie Cai 	printf("type: 0x%x\n", chipType);
123078884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
123132268622SAndreas Färber 		printf("chip type not supported!\n");
123278884ef4SEddie Cai 	}
123378884ef4SEddie Cai 	return chipType;
123478884ef4SEddie Cai }
123578884ef4SEddie Cai 
123678884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
123778884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
123878884ef4SEddie Cai 	hdr->tag = TAG;
123978884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
124078884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
124178884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
124278884ef4SEddie Cai 	hdr->releaseTime = getTime();
124378884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
124478884ef4SEddie Cai 
124578884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
124678884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
124778884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
124878884ef4SEddie Cai 
124978884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
125078884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
125178884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
125278884ef4SEddie Cai 
125378884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
125478884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
125578884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
125678884ef4SEddie Cai #ifndef USE_P_RC4
125778884ef4SEddie Cai 	hdr->rc4Flag = 1;
125878884ef4SEddie Cai #endif
125978884ef4SEddie Cai }
126078884ef4SEddie Cai 
126178884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
126278884ef4SEddie Cai 	uint32_t size = 0;
126378884ef4SEddie Cai 	uint32_t crc = 0;
126478884ef4SEddie Cai 
126578884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
126678884ef4SEddie Cai 	getFileSize(path, &size);
126778884ef4SEddie Cai 	if (!file)
126878884ef4SEddie Cai 		goto end;
126978884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
127078884ef4SEddie Cai 		goto end;
127178884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
127278884ef4SEddie Cai 	printf("crc: 0x%08x\n", crc);
127378884ef4SEddie Cai end:
127478884ef4SEddie Cai 	if (file)
127578884ef4SEddie Cai 		fclose(file);
127678884ef4SEddie Cai 	return crc;
127778884ef4SEddie Cai }
127878884ef4SEddie Cai 
127978884ef4SEddie Cai bool mergeBoot(void) {
128078884ef4SEddie Cai 	uint32_t dataOffset;
128178884ef4SEddie Cai 	bool ret = false;
128278884ef4SEddie Cai 	int i;
128378884ef4SEddie Cai 	FILE* outFile;
128478884ef4SEddie Cai 	uint32_t crc;
128578884ef4SEddie Cai 	rk_boot_header hdr;
128678884ef4SEddie Cai 
128778884ef4SEddie Cai 	if (!initOpts())
128878884ef4SEddie Cai 		return false;
128978884ef4SEddie Cai 	{
129078884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
129178884ef4SEddie Cai 		char version[MAX_LINE_LEN];
129278884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
129378884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
129478884ef4SEddie Cai 			subfix[0] = '\0';
129578884ef4SEddie Cai 		}
129678884ef4SEddie Cai 		strcat(gOpts.outPath, version);
129778884ef4SEddie Cai 		printf("fix opt: %s\n", gOpts.outPath);
129878884ef4SEddie Cai 	}
129978884ef4SEddie Cai 
130078884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
130178884ef4SEddie Cai 	printOpts(stdout);
130278884ef4SEddie Cai 	printf("---------------\n\n");
130378884ef4SEddie Cai 
130478884ef4SEddie Cai 
130578884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
130678884ef4SEddie Cai 	if (!outFile) {
130732268622SAndreas Färber 		printf("Opening output file (%s) failed\n", gOpts.outPath);
130878884ef4SEddie Cai 		goto end;
130978884ef4SEddie Cai 	}
131078884ef4SEddie Cai 
131178884ef4SEddie Cai 	getBoothdr(&hdr);
131232268622SAndreas Färber 	printf("Writing header...\n");
131378884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
131478884ef4SEddie Cai 
131578884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
131678884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
131778884ef4SEddie Cai 		sizeof(rk_boot_entry);
131878884ef4SEddie Cai 
131932268622SAndreas Färber 	printf("Writing code 471 entry...\n");
132078884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
132178884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
132278884ef4SEddie Cai 					&dataOffset, NULL, false))
132378884ef4SEddie Cai 			goto end;
132478884ef4SEddie Cai 	}
132532268622SAndreas Färber 	printf("Writing code 472 entry...\n");
132678884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
132778884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
132878884ef4SEddie Cai 					&dataOffset, NULL, false))
132978884ef4SEddie Cai 			goto end;
133078884ef4SEddie Cai 	}
133132268622SAndreas Färber 	printf("Writing loader entry...\n");
133278884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
133378884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
133478884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
133578884ef4SEddie Cai 			goto end;
133678884ef4SEddie Cai 	}
133778884ef4SEddie Cai 
133832268622SAndreas Färber 	printf("Writing code 471...\n");
133978884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
134078884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
134178884ef4SEddie Cai 			goto end;
134278884ef4SEddie Cai 	}
134332268622SAndreas Färber 	printf("Writing code 472...\n");
134478884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
134578884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
134678884ef4SEddie Cai 			goto end;
134778884ef4SEddie Cai 	}
134832268622SAndreas Färber 	printf("Writing loader...\n");
134978884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
135078884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
135178884ef4SEddie Cai 			goto end;
135278884ef4SEddie Cai 	}
135378884ef4SEddie Cai 	fflush(outFile);
135478884ef4SEddie Cai 
135532268622SAndreas Färber 	printf("Writing crc...\n");
135678884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
135778884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
135878884ef4SEddie Cai 		goto end;
135932268622SAndreas Färber 	printf("Done.\n");
136078884ef4SEddie Cai 	ret = true;
136178884ef4SEddie Cai end:
136278884ef4SEddie Cai 	if (outFile)
136378884ef4SEddie Cai 		fclose(outFile);
136478884ef4SEddie Cai 	return ret;
136578884ef4SEddie Cai }
136678884ef4SEddie Cai 
136778884ef4SEddie Cai /************merge code end************/
136878884ef4SEddie Cai /************unpack code***************/
136978884ef4SEddie Cai 
137078884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
137178884ef4SEddie Cai {
137278884ef4SEddie Cai 	int i;
137378884ef4SEddie Cai 	for (i = 0; i < len; i++) {
137478884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
137578884ef4SEddie Cai 	}
137678884ef4SEddie Cai 	str[len] = 0;
137778884ef4SEddie Cai }
137878884ef4SEddie Cai 
137978884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
138078884ef4SEddie Cai 		FILE* inFile) {
138178884ef4SEddie Cai 	bool ret = false;
138278884ef4SEddie Cai 	int size, i;
138378884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
138478884ef4SEddie Cai 	if (!outFile)
138578884ef4SEddie Cai 		goto end;
138632268622SAndreas Färber 	printf("unpacking entry (%s)\n", name);
138778884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
138878884ef4SEddie Cai 	size = entry->dataSize;
138978884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
139078884ef4SEddie Cai 		goto end;
139178884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
139278884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
139378884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
139478884ef4SEddie Cai 		if (size % SMALL_PACKET)
139578884ef4SEddie Cai 		{
139678884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
139778884ef4SEddie Cai 		}
139878884ef4SEddie Cai 	} else {
139978884ef4SEddie Cai 		P_RC4(gBuf, size);
140078884ef4SEddie Cai 	}
140178884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
140278884ef4SEddie Cai 		goto end;
140378884ef4SEddie Cai 	ret = true;
140478884ef4SEddie Cai end:
140578884ef4SEddie Cai 	if (outFile)
140678884ef4SEddie Cai 		fclose(outFile);
140778884ef4SEddie Cai 	return ret;
140878884ef4SEddie Cai }
140978884ef4SEddie Cai 
141078884ef4SEddie Cai bool unpackBoot(char* path) {
141178884ef4SEddie Cai 	bool ret = false;
141278884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
141378884ef4SEddie Cai 	int entryNum, i;
141478884ef4SEddie Cai 	char name[MAX_NAME_LEN];
141578884ef4SEddie Cai 	rk_boot_entry* entrys;
141678884ef4SEddie Cai 	if (!inFile) {
141778884ef4SEddie Cai 		fprintf(stderr, "loader (%s) not found\n", path);
141878884ef4SEddie Cai 		goto end;
141978884ef4SEddie Cai 	}
142078884ef4SEddie Cai 
142178884ef4SEddie Cai 	rk_boot_header hdr;
142278884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
142332268622SAndreas Färber 		fprintf(stderr, "reading header failed\n");
142478884ef4SEddie Cai 		goto end;
142578884ef4SEddie Cai 	}
142678884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
142778884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
142878884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
142978884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
143032268622SAndreas Färber 		fprintf(stderr, "reading data failed\n");
143178884ef4SEddie Cai 		goto end;
143278884ef4SEddie Cai 	}
143378884ef4SEddie Cai 
143478884ef4SEddie Cai 	printf("entry num: %d\n", entryNum);
143578884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
143678884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
143778884ef4SEddie Cai 
143878884ef4SEddie Cai 		printf("entry: t=%d, name=%s, off=%d, size=%d\n",
143978884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
144078884ef4SEddie Cai 				entrys[i].dataSize);
144178884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
144232268622SAndreas Färber 			fprintf(stderr, "unpacking entry (%s) failed\n", name);
144378884ef4SEddie Cai 			goto end;
144478884ef4SEddie Cai 		}
144578884ef4SEddie Cai 	}
144678884ef4SEddie Cai 	printf("done\n");
144778884ef4SEddie Cai 	ret = true;
144878884ef4SEddie Cai end:
144978884ef4SEddie Cai 	if (inFile)
145078884ef4SEddie Cai 		fclose(inFile);
145178884ef4SEddie Cai 	return ret;
145278884ef4SEddie Cai }
145378884ef4SEddie Cai 
145476af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
145576af099aSliuyi {
145676af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
145776af099aSliuyi 		return false;
145876af099aSliuyi 	CRKImage *pImage = NULL;
145976af099aSliuyi 	CRKBoot *pBoot = NULL;
146076af099aSliuyi 	bool bRet, bSuccess = false;
146176af099aSliuyi 	int iRet;
146276af099aSliuyi 
146376af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
146476af099aSliuyi 	if (!bRet){
146576af099aSliuyi 		ERROR_COLOR_ATTR;
146632268622SAndreas Färber 		printf("Opening loader failed, exiting download boot!");
146776af099aSliuyi 		NORMAL_COLOR_ATTR;
146876af099aSliuyi 		printf("\r\n");
146976af099aSliuyi 		return bSuccess;
147076af099aSliuyi 	} else {
147176af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
147276af099aSliuyi 		CRKComm *pComm = NULL;
147376af099aSliuyi 		CRKDevice *pDevice = NULL;
147476af099aSliuyi 
147576af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
147676af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
147776af099aSliuyi 		if (!bRet) {
147876af099aSliuyi 			if (pImage)
147976af099aSliuyi 				delete pImage;
148076af099aSliuyi 			ERROR_COLOR_ATTR;
148176af099aSliuyi 			printf("Creating Comm Object failed!");
148276af099aSliuyi 			NORMAL_COLOR_ATTR;
148376af099aSliuyi 			printf("\r\n");
148476af099aSliuyi 			return bSuccess;
148576af099aSliuyi 		}
148676af099aSliuyi 
148776af099aSliuyi 		pDevice = new CRKDevice(dev);
148876af099aSliuyi 		if (!pDevice) {
148976af099aSliuyi 			if (pImage)
149076af099aSliuyi 				delete pImage;
149176af099aSliuyi 			if (pComm)
149276af099aSliuyi 				delete pComm;
149376af099aSliuyi 			ERROR_COLOR_ATTR;
149476af099aSliuyi 			printf("Creating device object failed!");
149576af099aSliuyi 			NORMAL_COLOR_ATTR;
149676af099aSliuyi 			printf("\r\n");
149776af099aSliuyi 			return bSuccess;
149876af099aSliuyi 		}
149976af099aSliuyi 
150076af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
150132268622SAndreas Färber 		printf("Downloading bootloader...\r\n");
150276af099aSliuyi 		iRet = pDevice->DownloadBoot();
150376af099aSliuyi 
150476af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
150576af099aSliuyi 		CURSOR_DEL_LINE;
150676af099aSliuyi 		if (iRet == 0) {
150776af099aSliuyi 			bSuccess = true;
150832268622SAndreas Färber 			printf("Downloading bootloader succeeded.\r\n");
150976af099aSliuyi 		}
151076af099aSliuyi 		else
151132268622SAndreas Färber 			printf("Downloading bootloader failed!\r\n");
151276af099aSliuyi 
151376af099aSliuyi 		if (pImage)
151476af099aSliuyi 			delete pImage;
151576af099aSliuyi 		if(pDevice)
151676af099aSliuyi 			delete pDevice;
151776af099aSliuyi 	}
151876af099aSliuyi 	return bSuccess;
151976af099aSliuyi }
1520c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1521c30d921cSKever Yang {
1522c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1523c30d921cSKever Yang 		return false;
1524c30d921cSKever Yang 	CRKImage *pImage = NULL;
1525c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1526c30d921cSKever Yang 	CRKComm *pComm = NULL;
1527c30d921cSKever Yang 	bool bRet, bSuccess = false;
1528c30d921cSKever Yang 	int iRet;
1529c30d921cSKever Yang 	char index;
1530c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1531c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1532c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1533c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1534c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1535c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1536c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1537c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1538c30d921cSKever Yang 	if (!bRet){
1539c30d921cSKever Yang 		ERROR_COLOR_ATTR;
154032268622SAndreas Färber 		printf("Opening loader failed, exiting upgrade loader!");
1541c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1542c30d921cSKever Yang 		printf("\r\n");
1543c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1544c30d921cSKever Yang 	} else {
1545c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1546c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1547c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1548c30d921cSKever Yang 		if (!bRet) {
1549c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1550c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1551c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1552c30d921cSKever Yang 			printf("\r\n");
1553c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1554c30d921cSKever Yang 		}
1555c30d921cSKever Yang 
155632268622SAndreas Färber 		printf("Upgrading loader...\r\n");
1557c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1558c30d921cSKever Yang 		if (index == -1) {
1559c30d921cSKever Yang 			if (g_pLogObject) {
156032268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1561c30d921cSKever Yang 			}
1562c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1563c30d921cSKever Yang 		}
1564c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1565c30d921cSKever Yang 		if (!bRet) {
1566c30d921cSKever Yang 			if (g_pLogObject) {
156732268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1568c30d921cSKever Yang 			}
1569c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1570c30d921cSKever Yang 		}
1571c30d921cSKever Yang 
1572c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1573c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1574c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1575c30d921cSKever Yang 			if (g_pLogObject) {
157632268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1577c30d921cSKever Yang 			}
1578c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1579c30d921cSKever Yang 		}
1580c30d921cSKever Yang 
1581c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1582c30d921cSKever Yang 		if (index == -1) {
1583c30d921cSKever Yang 			if (g_pLogObject) {
158432268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1585c30d921cSKever Yang 			}
1586c30d921cSKever Yang 			delete []loaderCodeBuffer;
1587c30d921cSKever Yang 			return -4;
1588c30d921cSKever Yang 		}
1589c30d921cSKever Yang 
1590c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1591c30d921cSKever Yang 		if (!bRet) {
1592c30d921cSKever Yang 			if (g_pLogObject) {
159332268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1594c30d921cSKever Yang 			}
1595c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1596c30d921cSKever Yang 		}
1597c30d921cSKever Yang 
1598c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1599c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1600c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1601c30d921cSKever Yang 			if (g_pLogObject) {
160232268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1603c30d921cSKever Yang 			}
1604c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1605c30d921cSKever Yang 		}
1606c30d921cSKever Yang 
1607c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1608c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1609c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1610c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1611c30d921cSKever Yang 		if (!pIDBData) {
1612c30d921cSKever Yang 			ERROR_COLOR_ATTR;
161332268622SAndreas Färber 			printf("Allocating memory failed!");
1614c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1615c30d921cSKever Yang 			printf("\r\n");
1616c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1617c30d921cSKever Yang 		}
1618c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1619*b38fe5fcSliuyi 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
1620c30d921cSKever Yang 		if (iRet != 0) {
1621c30d921cSKever Yang 			ERROR_COLOR_ATTR;
162232268622SAndreas Färber 			printf("Making idblock failed!");
1623c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1624c30d921cSKever Yang 			printf("\r\n");
1625c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1626c30d921cSKever Yang 		}
1627*b38fe5fcSliuyi 		if (g_pLogObject)
1628*b38fe5fcSliuyi 			g_pLogObject->SaveBuffer("idblock.bin",pIDBData,dwSectorNum*SECTOR_SIZE);
1629c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
1630c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
1631c30d921cSKever Yang 		CURSOR_DEL_LINE;
1632c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
1633*b38fe5fcSliuyi 			//pComm->Reset_Usb_Device();
1634c30d921cSKever Yang 			bSuccess = true;
163532268622SAndreas Färber 			printf("Upgrading loader succeeded.\r\n");
1636c30d921cSKever Yang 		} else {
163732268622SAndreas Färber 			printf("Upgrading loader failed!\r\n");
1638c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1639c30d921cSKever Yang 		}
1640c30d921cSKever Yang 	}
1641c30d921cSKever Yang Exit_UpgradeLoader:
1642c30d921cSKever Yang 	if (pImage)
1643c30d921cSKever Yang 		delete pImage;
1644c30d921cSKever Yang 	if (pComm)
1645c30d921cSKever Yang 		delete pComm;
1646c30d921cSKever Yang 	if (loaderCodeBuffer)
1647c30d921cSKever Yang 		delete []loaderCodeBuffer;
1648c30d921cSKever Yang 	if (loaderDataBuffer)
1649c30d921cSKever Yang 		delete []loaderDataBuffer;
1650c30d921cSKever Yang 	if (pIDBData)
1651c30d921cSKever Yang 		delete []pIDBData;
1652c30d921cSKever Yang 	return bSuccess;
1653c30d921cSKever Yang }
1654c30d921cSKever Yang 
165576af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
165676af099aSliuyi {
165776af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
165876af099aSliuyi 		return false;
165976af099aSliuyi 	CRKImage *pImage = NULL;
166076af099aSliuyi 	bool bRet, bSuccess = false;
166176af099aSliuyi 	int iRet;
166276af099aSliuyi 	CRKScan *pScan = NULL;
166376af099aSliuyi 	pScan = new CRKScan();
166476af099aSliuyi 	pScan->SetVidPid();
166576af099aSliuyi 
166676af099aSliuyi 	CRKComm *pComm = NULL;
166776af099aSliuyi 	CRKDevice *pDevice = NULL;
166876af099aSliuyi 
166976af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
167076af099aSliuyi 	if (!bRet) {
167176af099aSliuyi 		if (pScan)
167276af099aSliuyi 			delete pScan;
167376af099aSliuyi 		ERROR_COLOR_ATTR;
167476af099aSliuyi 		printf("Creating Comm Object failed!");
167576af099aSliuyi 		NORMAL_COLOR_ATTR;
167676af099aSliuyi 		printf("\r\n");
167776af099aSliuyi 		return bSuccess;
167876af099aSliuyi 	}
167976af099aSliuyi 
168076af099aSliuyi 	pDevice = new CRKDevice(dev);
168176af099aSliuyi 	if (!pDevice) {
168276af099aSliuyi 		if (pComm)
168376af099aSliuyi 			delete pComm;
168476af099aSliuyi 		if (pScan)
168576af099aSliuyi 			delete pScan;
168676af099aSliuyi 		ERROR_COLOR_ATTR;
168776af099aSliuyi 		printf("Creating device object failed!");
168876af099aSliuyi 		NORMAL_COLOR_ATTR;
168976af099aSliuyi 		printf("\r\n");
169076af099aSliuyi 		return bSuccess;
169176af099aSliuyi 	}
169276af099aSliuyi 
169376af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
169476af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
169576af099aSliuyi 
169632268622SAndreas Färber 	printf("Starting to erase flash...\r\n");
169776af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
169876af099aSliuyi 	if (pDevice)
169976af099aSliuyi 		delete pDevice;
170076af099aSliuyi 
170176af099aSliuyi 	if (iRet == 0) {
170276af099aSliuyi 		if (pScan) {
170376af099aSliuyi 			pScan->SetVidPid();
170476af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
170576af099aSliuyi 			delete pScan;
170676af099aSliuyi 		}
170776af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
170876af099aSliuyi 		CURSOR_DEL_LINE;
170976af099aSliuyi 		bSuccess = true;
171032268622SAndreas Färber 		printf("Erasing flash complete.\r\n");
171176af099aSliuyi 	}
171276af099aSliuyi 
171376af099aSliuyi 	return bSuccess;
171476af099aSliuyi }
171576af099aSliuyi 
171676af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
171776af099aSliuyi {
171876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
171976af099aSliuyi 		return false;
172076af099aSliuyi 	CRKUsbComm *pComm = NULL;
172176af099aSliuyi 	bool bRet, bSuccess = false;
172276af099aSliuyi 	int iRet;
172376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
172476af099aSliuyi 	if (bRet) {
172576af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
172676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
172776af099aSliuyi 			if (g_pLogObject)
172876af099aSliuyi 				g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
172932268622SAndreas Färber 			printf("Test Device failed!\r\n");
173076af099aSliuyi 		} else {
173176af099aSliuyi 			bSuccess = true;
173276af099aSliuyi 			printf("Test Device OK.\r\n");
173376af099aSliuyi 		}
173476af099aSliuyi 	} else {
173532268622SAndreas Färber 		printf("Test Device quit, creating comm object failed!\r\n");
173676af099aSliuyi 	}
173776af099aSliuyi 	if (pComm) {
173876af099aSliuyi 		delete pComm;
173976af099aSliuyi 		pComm = NULL;
174076af099aSliuyi 	}
174176af099aSliuyi 	return bSuccess;
174276af099aSliuyi }
174376af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
174476af099aSliuyi {
174576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
174676af099aSliuyi 		return false;
174776af099aSliuyi 	CRKUsbComm *pComm = NULL;
174876af099aSliuyi 	bool bRet, bSuccess = false;
174976af099aSliuyi 	int iRet;
175076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
175176af099aSliuyi 	if (bRet) {
175276af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
175376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
175476af099aSliuyi 			if (g_pLogObject)
175576af099aSliuyi 				g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
175632268622SAndreas Färber 			printf("Reset Device failed!\r\n");
175776af099aSliuyi 		} else {
175876af099aSliuyi 			bSuccess = true;
175976af099aSliuyi 			printf("Reset Device OK.\r\n");
176076af099aSliuyi 		}
176176af099aSliuyi 	} else {
176232268622SAndreas Färber 		printf("Reset Device quit, creating comm object failed!\r\n");
176376af099aSliuyi 	}
176476af099aSliuyi 	if (pComm) {
176576af099aSliuyi 		delete pComm;
176676af099aSliuyi 		pComm = NULL;
176776af099aSliuyi 	}
176876af099aSliuyi 	return bSuccess;
176976af099aSliuyi }
177076af099aSliuyi 
177176af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
177276af099aSliuyi {
177376af099aSliuyi 	CRKUsbComm *pComm = NULL;
177476af099aSliuyi 	bool bRet, bSuccess = false;
177576af099aSliuyi 	int iRet;
177676af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
177776af099aSliuyi 		return bSuccess;
177876af099aSliuyi 
177976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
178076af099aSliuyi 	if (bRet) {
178176af099aSliuyi 		BYTE flashID[5];
178276af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
178376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
178476af099aSliuyi 			if (g_pLogObject)
178576af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
178632268622SAndreas Färber 			printf("Reading flash ID failed!\r\n");
178776af099aSliuyi 		} else {
178876af099aSliuyi 			printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
178976af099aSliuyi 			bSuccess = true;
179076af099aSliuyi 		}
179176af099aSliuyi 	} else {
179232268622SAndreas Färber 		printf("Read Flash ID quit, creating comm object failed!\r\n");
179376af099aSliuyi 	}
179476af099aSliuyi 	if (pComm) {
179576af099aSliuyi 		delete pComm;
179676af099aSliuyi 		pComm = NULL;
179776af099aSliuyi 	}
179876af099aSliuyi 	return bSuccess;
179976af099aSliuyi }
180076af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
180176af099aSliuyi {
180276af099aSliuyi 	CRKUsbComm *pComm = NULL;
180376af099aSliuyi 	bool bRet, bSuccess = false;
180476af099aSliuyi 	int iRet;
180576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
180676af099aSliuyi 		return bSuccess;
180776af099aSliuyi 
180876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
180976af099aSliuyi 	if (bRet) {
181076af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
181176af099aSliuyi 		UINT uiRead;
181276af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
181376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
181476af099aSliuyi 			if (g_pLogObject)
181576af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
181632268622SAndreas Färber 			printf("Read Flash Info failed!\r\n");
181776af099aSliuyi 		} else {
181876af099aSliuyi 			printf("Flash Info:\r\n");
181976af099aSliuyi 			if (info.bManufCode <= 7) {
182076af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
182176af099aSliuyi 			}
182276af099aSliuyi 			else
182376af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
182476af099aSliuyi 
182576af099aSliuyi 			printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
182676af099aSliuyi 			printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
182776af099aSliuyi 			printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
182876af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
182976af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
183076af099aSliuyi 			printf("\tFlash CS: ");
183176af099aSliuyi 			for(int i = 0; i < 8; i++) {
183276af099aSliuyi 				if( info.bFlashCS & (1 << i) )
183376af099aSliuyi 					printf("Flash<%d> ", i);
183476af099aSliuyi 			}
183576af099aSliuyi 			printf("\r\n");
183676af099aSliuyi 			bSuccess = true;
183776af099aSliuyi 		}
183876af099aSliuyi 	}else {
183932268622SAndreas Färber 		printf("Read Flash Info quit, creating comm object failed!\r\n");
184076af099aSliuyi 	}
184176af099aSliuyi 	if (pComm) {
184276af099aSliuyi 		delete pComm;
184376af099aSliuyi 		pComm = NULL;
184476af099aSliuyi 	}
184576af099aSliuyi 	return bSuccess;
184676af099aSliuyi }
184776af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
184876af099aSliuyi {
184976af099aSliuyi 	CRKUsbComm *pComm = NULL;
185076af099aSliuyi 	bool bRet, bSuccess = false;
185176af099aSliuyi 	int iRet;
185276af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
185376af099aSliuyi 		return bSuccess;
185476af099aSliuyi 
185576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
185676af099aSliuyi 	if (bRet) {
185776af099aSliuyi 		BYTE chipInfo[16];
185876af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
185976af099aSliuyi 		if (iRet != ERR_SUCCESS) {
186076af099aSliuyi 			if (g_pLogObject)
186176af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
186232268622SAndreas Färber 			printf("Read Chip Info failed!\r\n");
186376af099aSliuyi 		} else {
186476af099aSliuyi 			string strChipInfo;
186576af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
186676af099aSliuyi 			printf("Chip Info: %s\r\n", strChipInfo.c_str());
186776af099aSliuyi 			bSuccess = true;
186876af099aSliuyi 		}
186976af099aSliuyi 	} else {
187032268622SAndreas Färber 		printf("Read Chip Info quit, creating comm object failed!\r\n");
187176af099aSliuyi 	}
187276af099aSliuyi 	if (pComm) {
187376af099aSliuyi 		delete pComm;
187476af099aSliuyi 		pComm = NULL;
187576af099aSliuyi 	}
187676af099aSliuyi 	return bSuccess;
187776af099aSliuyi }
187876af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
187976af099aSliuyi {
188076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
188176af099aSliuyi 		return false;
188276af099aSliuyi 	CRKUsbComm *pComm = NULL;
188376af099aSliuyi 	FILE *file = NULL;
188476af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
188576af099aSliuyi 	int iRet;
188676af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
188776af099aSliuyi 	int nSectorSize = 512;
188876af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
188976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
189076af099aSliuyi 	if (bRet) {
189176af099aSliuyi 		if(szFile) {
189276af099aSliuyi 			file = fopen(szFile, "wb+");
189376af099aSliuyi 			if( !file ) {
189476af099aSliuyi 				printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
189576af099aSliuyi 				goto Exit_ReadLBA;
189676af099aSliuyi 			}
189776af099aSliuyi 		}
189876af099aSliuyi 
189976af099aSliuyi 		while(uiLen > 0) {
190076af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
190176af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
190276af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
190376af099aSliuyi 			if(ERR_SUCCESS == iRet) {
190476af099aSliuyi 				uiLen -= iRead;
190576af099aSliuyi 				iTotalRead += iRead;
190676af099aSliuyi 
190776af099aSliuyi 				if(szFile) {
190876af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
190976af099aSliuyi 					if (bFirst){
191076af099aSliuyi 						if (iTotalRead >= 1024)
191132268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
191276af099aSliuyi 						else
191332268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
191476af099aSliuyi 						bFirst = false;
191576af099aSliuyi 					} else {
191676af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
191776af099aSliuyi 						CURSOR_DEL_LINE;
191876af099aSliuyi 						if (iTotalRead >= 1024)
191932268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
192076af099aSliuyi 						else
192132268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
192276af099aSliuyi 					}
192376af099aSliuyi 				}
192476af099aSliuyi 				else
192576af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
192676af099aSliuyi 			} else {
192776af099aSliuyi 				if (g_pLogObject)
192876af099aSliuyi 					g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
192976af099aSliuyi 
193076af099aSliuyi 				printf("Read LBA failed!\r\n");
193176af099aSliuyi 				goto Exit_ReadLBA;
193276af099aSliuyi 			}
193376af099aSliuyi 		}
193476af099aSliuyi 		bSuccess = true;
193576af099aSliuyi 	} else {
193632268622SAndreas Färber 		printf("Read LBA quit, creating comm object failed!\r\n");
193776af099aSliuyi 	}
193876af099aSliuyi Exit_ReadLBA:
193976af099aSliuyi 	if (pComm) {
194076af099aSliuyi 		delete pComm;
194176af099aSliuyi 		pComm = NULL;
194276af099aSliuyi 	}
194376af099aSliuyi 	if (file)
194476af099aSliuyi 		fclose(file);
194576af099aSliuyi 	return bSuccess;
194676af099aSliuyi }
194776af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
194876af099aSliuyi {
194976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
195076af099aSliuyi 		return false;
195176af099aSliuyi 	CRKUsbComm *pComm = NULL;
195276af099aSliuyi 	FILE *file = NULL;
195376af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
195476af099aSliuyi 	int iRet;
195576af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
195676af099aSliuyi 	UINT iWrite = 0, iRead = 0;
195776af099aSliuyi 	UINT uiLen;
195876af099aSliuyi 	int nSectorSize = 512;
195976af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
196076af099aSliuyi 
196176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
196276af099aSliuyi 	if (bRet) {
196376af099aSliuyi 		file = fopen(szFile, "rb");
196476af099aSliuyi 		if( !file ) {
196576af099aSliuyi 			printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
196676af099aSliuyi 			goto Exit_WriteLBA;
196776af099aSliuyi 		}
196876af099aSliuyi 
196976af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
197076af099aSliuyi 		iFileSize = ftello(file);
197176af099aSliuyi 		fseeko(file, 0, SEEK_SET);
197276af099aSliuyi 		while(iTotalWrite < iFileSize) {
197376af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
197476af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
197576af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
197676af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
197776af099aSliuyi 			if(ERR_SUCCESS == iRet) {
197876af099aSliuyi 				uiBegin += uiLen;
197976af099aSliuyi 				iTotalWrite += iWrite;
198076af099aSliuyi 				if (bFirst) {
198176af099aSliuyi 					if (iTotalWrite >= 1024)
198276af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
198376af099aSliuyi 					else
198432268622SAndreas Färber 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
198576af099aSliuyi 					bFirst = false;
198676af099aSliuyi 				} else {
198776af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
198876af099aSliuyi 					CURSOR_DEL_LINE;
198976af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
199076af099aSliuyi 				}
199176af099aSliuyi 			} else {
199276af099aSliuyi 				if (g_pLogObject)
199376af099aSliuyi 					g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
199476af099aSliuyi 
199576af099aSliuyi 				printf("Write LBA failed!\r\n");
199676af099aSliuyi 				goto Exit_WriteLBA;
199776af099aSliuyi 			}
199876af099aSliuyi 		}
199976af099aSliuyi 		bSuccess = true;
200076af099aSliuyi 	} else {
200132268622SAndreas Färber 		printf("Write LBA quit, creating comm object failed!\r\n");
200276af099aSliuyi 	}
200376af099aSliuyi Exit_WriteLBA:
200476af099aSliuyi 	if (pComm) {
200576af099aSliuyi 		delete pComm;
200676af099aSliuyi 		pComm = NULL;
200776af099aSliuyi 	}
200876af099aSliuyi 	if (file)
200976af099aSliuyi 		fclose(file);
201076af099aSliuyi 	return bSuccess;
201176af099aSliuyi }
201276af099aSliuyi 
201376af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
201476af099aSliuyi {
201576af099aSliuyi 	string strItem;
201676af099aSliuyi 	char szItem[100];
201776af099aSliuyi 	char *pos = NULL, *pStart;
201876af099aSliuyi 	pStart = pszItems;
201976af099aSliuyi 	pos = strchr(pStart, ',');
202076af099aSliuyi 	while(pos != NULL) {
202176af099aSliuyi 		memset(szItem, 0, 100);
202276af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
202376af099aSliuyi 		strItem = szItem;
202476af099aSliuyi 		vecItems.push_back(strItem);
202576af099aSliuyi 		pStart = pos + 1;
202676af099aSliuyi 		if (*pStart == 0)
202776af099aSliuyi 			break;
202876af099aSliuyi 		pos = strchr(pStart, ',');
202976af099aSliuyi 	}
203076af099aSliuyi 	if (strlen(pStart) > 0) {
203176af099aSliuyi 		memset(szItem, 0, 100);
203276af099aSliuyi 		strncpy(szItem, pStart, strlen(pStart));
203376af099aSliuyi 		strItem = szItem;
203476af099aSliuyi 		vecItems.push_back(strItem);
203576af099aSliuyi 	}
203676af099aSliuyi }
2037c30d921cSKever Yang 
2038d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
2039d71e8c20SEddie Cai {
2040d71e8c20SEddie Cai 	FILE *file = NULL;
2041d71e8c20SEddie Cai 	int len;
2042d71e8c20SEddie Cai 
2043d71e8c20SEddie Cai 	if(!tag || !spl)
2044d71e8c20SEddie Cai 		return;
2045d71e8c20SEddie Cai 	len = strlen(tag);
2046d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
2047d71e8c20SEddie Cai 	file = fopen(spl, "rb");
2048d71e8c20SEddie Cai 	if( !file ){
2049d71e8c20SEddie Cai 		return;
2050d71e8c20SEddie Cai 	}
2051d71e8c20SEddie Cai 	int iFileSize;
2052d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
2053d71e8c20SEddie Cai 	iFileSize = ftell(file);
2054d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
2055d71e8c20SEddie Cai 	char *Buf = NULL;
2056d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
2057d71e8c20SEddie Cai 	if (!Buf){
2058d71e8c20SEddie Cai 		fclose(file);
2059d71e8c20SEddie Cai 		return;
2060d71e8c20SEddie Cai 	}
2061d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
2062d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
2063d71e8c20SEddie Cai 	int iRead;
2064d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
2065d71e8c20SEddie Cai 	if (iRead != iFileSize){
2066d71e8c20SEddie Cai 		fclose(file);
2067d71e8c20SEddie Cai 		delete []Buf;
2068d71e8c20SEddie Cai 		return;
2069d71e8c20SEddie Cai 	}
2070d71e8c20SEddie Cai 	fclose(file);
2071d71e8c20SEddie Cai 
2072d71e8c20SEddie Cai 	len = strlen(spl);
207332268622SAndreas Färber 	char *taggedspl = new char[len + 5];
207432268622SAndreas Färber 	strcpy(taggedspl, spl);
207532268622SAndreas Färber 	strcpy(taggedspl + len, ".tag");
207632268622SAndreas Färber 	taggedspl[len+4] = 0;
207732268622SAndreas Färber 	printf("Writing tagged spl to %s\n", taggedspl);
2078d71e8c20SEddie Cai 
207932268622SAndreas Färber 	file = fopen(taggedspl, "wb");
2080d71e8c20SEddie Cai 	if( !file ){
208132268622SAndreas Färber 		delete []taggedspl;
2082d71e8c20SEddie Cai 		delete []Buf;
2083d71e8c20SEddie Cai 		return;
2084d71e8c20SEddie Cai 	}
2085d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
2086d71e8c20SEddie Cai 	fclose(file);
208732268622SAndreas Färber 	delete []taggedspl;
2088d71e8c20SEddie Cai 	delete []Buf;
2089d71e8c20SEddie Cai 	printf("done\n");
2090d71e8c20SEddie Cai 	return;
2091d71e8c20SEddie Cai }
2092d71e8c20SEddie Cai 
209376af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
209476af099aSliuyi {
209576af099aSliuyi 	string strCmd;
209676af099aSliuyi 	strCmd = argv[1];
209776af099aSliuyi 	ssize_t cnt;
209876af099aSliuyi 	bool bRet,bSuccess = false;
20998df2d64aSEddie Cai 	char *s;
21008df2d64aSEddie Cai 	int i, ret;
210176af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
210276af099aSliuyi 
210376af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
21048df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
21058df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
21068df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
210778884ef4SEddie Cai 
21088df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
210976af099aSliuyi 		usage();
211076af099aSliuyi 		return true;
21118df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
2112c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
211376af099aSliuyi 		return true;
211478884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
211578884ef4SEddie Cai 		mergeBoot();
211678884ef4SEddie Cai 
211778884ef4SEddie Cai 		return true;
211878884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
211978884ef4SEddie Cai 		string strLoader = argv[2];
212078884ef4SEddie Cai 
212178884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
212278884ef4SEddie Cai 		return true;
2123d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
2124d71e8c20SEddie Cai 		if (argc == 4) {
2125d71e8c20SEddie Cai 			string tag = argv[2];
2126d71e8c20SEddie Cai 			string spl = argv[3];
2127d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
2128d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
2129d71e8c20SEddie Cai 			return true;
2130d71e8c20SEddie Cai 		}
2131d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
2132d71e8c20SEddie Cai 		usage();
213376af099aSliuyi 	}
213476af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
213576af099aSliuyi 	if (cnt < 1) {
213676af099aSliuyi 		ERROR_COLOR_ATTR;
213732268622SAndreas Färber 		printf("Did not find any rockusb device, please plug device in!");
213876af099aSliuyi 		NORMAL_COLOR_ATTR;
213976af099aSliuyi 		printf("\r\n");
214076af099aSliuyi 		return bSuccess;
214176af099aSliuyi 	} else if (cnt > 1) {
214276af099aSliuyi 		ERROR_COLOR_ATTR;
214332268622SAndreas Färber 		printf("Found too many rockusb devices, please plug devices out!");
214476af099aSliuyi 		NORMAL_COLOR_ATTR;
214576af099aSliuyi 		printf("\r\n");
214676af099aSliuyi 		return bSuccess;
214776af099aSliuyi 	}
214876af099aSliuyi 
214976af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
215076af099aSliuyi 	if (!bRet) {
215176af099aSliuyi 		ERROR_COLOR_ATTR;
215232268622SAndreas Färber 		printf("Getting information about rockusb device failed!");
215376af099aSliuyi 		NORMAL_COLOR_ATTR;
215476af099aSliuyi 		printf("\r\n");
215576af099aSliuyi 		return bSuccess;
215676af099aSliuyi 	}
215776af099aSliuyi 
215876af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
215976af099aSliuyi 		if ((argc != 2) && (argc != 3))
216076af099aSliuyi 			printf("Parameter of [RD] command is invalid, please check help!\r\n");
216176af099aSliuyi 		else {
216276af099aSliuyi 			if (argc == 2)
216376af099aSliuyi 				bSuccess = reset_device(dev);
216476af099aSliuyi 			else {
216576af099aSliuyi 				UINT uiSubCode;
216676af099aSliuyi 				char *pszEnd;
216776af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
216876af099aSliuyi 				if (*pszEnd)
216976af099aSliuyi 					printf("Subcode is invalid, please check!\r\n");
217076af099aSliuyi 				else {
217176af099aSliuyi 					if (uiSubCode <= 5)
217276af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
217376af099aSliuyi 					else
217476af099aSliuyi 						printf("Subcode is invalid, please check!\r\n");
217576af099aSliuyi 				}
217676af099aSliuyi 			}
217776af099aSliuyi 		}
217876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
217976af099aSliuyi 		bSuccess = test_device(dev);
218076af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
218176af099aSliuyi 		bSuccess = read_flash_id(dev);
218276af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
218376af099aSliuyi 		bSuccess = read_flash_info(dev);
218476af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
218576af099aSliuyi 		bSuccess = read_chip_info(dev);
218676af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
218776af099aSliuyi 		if (argc > 2) {
218876af099aSliuyi 			string strLoader;
218976af099aSliuyi 			strLoader = argv[2];
219076af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
219176af099aSliuyi 		} else if (argc == 2) {
219276af099aSliuyi 			ret = find_config_item("loader");
219376af099aSliuyi 			if (ret == -1)
219432268622SAndreas Färber 				printf("Did not find loader item in config!\r\n");
219576af099aSliuyi 			else
219676af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
219776af099aSliuyi 		} else
219876af099aSliuyi 			printf("Parameter of [DB] command is invalid, please check help!\r\n");
2199c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
2200c30d921cSKever Yang 		if (argc > 2) {
2201c30d921cSKever Yang 			string strParameter;
2202c30d921cSKever Yang 			strParameter = argv[2];
2203c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
2204c30d921cSKever Yang 		} else
2205c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid, please check help!\r\n");
2206c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
2207c30d921cSKever Yang 		if (argc > 2) {
2208c30d921cSKever Yang 			string strLoader;
2209c30d921cSKever Yang 			strLoader = argv[2];
2210c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
2211c30d921cSKever Yang 		} else
2212c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid, please check help!\r\n");
221376af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
221476af099aSliuyi 		if (argc == 2) {
221576af099aSliuyi 			bSuccess = erase_flash(dev);
221676af099aSliuyi 		} else
221776af099aSliuyi 			printf("Parameter of [EF] command is invalid, please check help!\r\n");
221876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
221976af099aSliuyi 		if (argc == 4) {
222076af099aSliuyi 			UINT uiBegin;
222176af099aSliuyi 			char *pszEnd;
222276af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
222376af099aSliuyi 			if (*pszEnd)
222476af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
222576af099aSliuyi 			else
222676af099aSliuyi 				bSuccess = write_lba(dev, uiBegin, argv[3]);
222776af099aSliuyi 		} else
222876af099aSliuyi 			printf("Parameter of [WL] command is invalid, please check help!\r\n");
222976af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
223076af099aSliuyi 		char *pszEnd;
223176af099aSliuyi 		UINT uiBegin, uiLen;
223276af099aSliuyi 		if (argc != 5)
223376af099aSliuyi 			printf("Parameter of [RL] command is invalid, please check help!\r\n");
223476af099aSliuyi 		else {
223576af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
223676af099aSliuyi 			if (*pszEnd)
223776af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
223876af099aSliuyi 			else {
223976af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
224076af099aSliuyi 				if (*pszEnd)
224176af099aSliuyi 					printf("Len is invalid, please check!\r\n");
224276af099aSliuyi 				else {
224376af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
224476af099aSliuyi 				}
224576af099aSliuyi 			}
224676af099aSliuyi 		}
224776af099aSliuyi 	} else {
22489bc231bdSAndreas Färber 		printf("command is invalid!\r\n");
22499bc231bdSAndreas Färber 		usage();
225076af099aSliuyi 	}
225176af099aSliuyi 	return bSuccess;
225276af099aSliuyi }
225376af099aSliuyi 
225476af099aSliuyi 
225576af099aSliuyi int main(int argc, char* argv[])
225676af099aSliuyi {
225776af099aSliuyi 	CRKScan *pScan = NULL;
225876af099aSliuyi 	int ret;
225976af099aSliuyi 	char szProgramProcPath[100];
226076af099aSliuyi 	char szProgramDir[256];
226176af099aSliuyi 	string strLogDir,strConfigFile;
226276af099aSliuyi 	struct stat statBuf;
226376af099aSliuyi 
226476af099aSliuyi 	g_ConfigItemVec.clear();
226576af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
226676af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
226776af099aSliuyi 		strcpy(szProgramDir, ".");
226876af099aSliuyi 	else {
226976af099aSliuyi 		char *pSlash;
227076af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
227176af099aSliuyi 		if (pSlash)
227276af099aSliuyi 			*pSlash = '\0';
227376af099aSliuyi 	}
227476af099aSliuyi 	strLogDir = szProgramDir;
227576af099aSliuyi 	strLogDir +=  "/log/";
227676af099aSliuyi 	strConfigFile = szProgramDir;
227776af099aSliuyi 	strConfigFile += "/config.ini";
227876af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
227976af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
2280e5ee8cc0Sliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
228176af099aSliuyi 
228276af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
228376af099aSliuyi 		if (g_pLogObject) {
228476af099aSliuyi 			g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
228576af099aSliuyi 		}
228676af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
228776af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
228876af099aSliuyi 	}
228976af099aSliuyi 
229076af099aSliuyi 	ret = libusb_init(NULL);
229176af099aSliuyi 	if (ret < 0) {
229276af099aSliuyi 		if (g_pLogObject) {
229376af099aSliuyi 			g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
229476af099aSliuyi 			delete g_pLogObject;
229576af099aSliuyi 		}
229676af099aSliuyi 		return -1;
229776af099aSliuyi 	}
229876af099aSliuyi 
229976af099aSliuyi 	pScan = new CRKScan();
230076af099aSliuyi 	if (!pScan) {
230176af099aSliuyi 		if (g_pLogObject) {
230232268622SAndreas Färber 			g_pLogObject->Record("Error: failed to create object for searching device");
230376af099aSliuyi 			delete g_pLogObject;
230476af099aSliuyi 		}
230576af099aSliuyi 		libusb_exit(NULL);
230676af099aSliuyi 		return -2;
230776af099aSliuyi 	}
230876af099aSliuyi 	pScan->SetVidPid();
230976af099aSliuyi 
231076af099aSliuyi 	if (argc == 1)
231176af099aSliuyi 		usage();
231276af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
231376af099aSliuyi 			return -0xFF;
231476af099aSliuyi 	if (pScan)
231576af099aSliuyi 		delete pScan;
231676af099aSliuyi 	if (g_pLogObject)
231776af099aSliuyi 		delete g_pLogObject;
231876af099aSliuyi 	libusb_exit(NULL);
231976af099aSliuyi 	return 0;
232076af099aSliuyi }
2321