xref: /rkdeveloptool/main.cpp (revision 6502326d4d447d9145c16c46a9ed9887cdd7302f)
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");
516ae612beSliuyi 	printf("WriteLBA:\t\twlx  <PartitionName> <File>\r\n");
52154ee062SEddie Cai 	printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
53154ee062SEddie Cai 	printf("EraseFlash:\t\tef \r\n");
54154ee062SEddie Cai 	printf("TestDevice:\t\ttd\r\n");
55154ee062SEddie Cai 	printf("ResetDevice:\t\trd [subcode]\r\n");
56154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
57154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
58154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
5978884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
6078884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
61d71e8c20SEddie Cai 	printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
6276af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6376af099aSliuyi }
6476af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6576af099aSliuyi {
6676af099aSliuyi 	string strInfoText="";
6776af099aSliuyi 	char szText[256];
6876af099aSliuyi 	switch (promptID) {
6976af099aSliuyi 	case TESTDEVICE_PROGRESS:
7032268622SAndreas Färber 		sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue);
7176af099aSliuyi 		strInfoText = szText;
7276af099aSliuyi 		break;
7376af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7432268622SAndreas Färber 		sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue);
7576af099aSliuyi 		strInfoText = szText;
7676af099aSliuyi 		break;
7776af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
7832268622SAndreas Färber 		sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
7976af099aSliuyi 		strInfoText = szText;
8076af099aSliuyi 		break;
8176af099aSliuyi 	case CHECKIMAGE_PROGRESS:
8232268622SAndreas Färber 		sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8376af099aSliuyi 		strInfoText = szText;
8476af099aSliuyi 		break;
8576af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
8632268622SAndreas Färber 		sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue);
8776af099aSliuyi 		strInfoText = szText;
8876af099aSliuyi 		break;
8976af099aSliuyi 	case TESTBLOCK_PROGRESS:
9032268622SAndreas Färber 		sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue);
9176af099aSliuyi 		strInfoText = szText;
9276af099aSliuyi 		break;
9376af099aSliuyi 	case ERASEFLASH_PROGRESS:
9432268622SAndreas Färber 		sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue);
9576af099aSliuyi 		strInfoText = szText;
9676af099aSliuyi 		break;
9776af099aSliuyi 	case ERASESYSTEM_PROGRESS:
9832268622SAndreas Färber 		sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue);
9976af099aSliuyi 		strInfoText = szText;
10076af099aSliuyi 		break;
10176af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
10232268622SAndreas Färber 		sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue);
10376af099aSliuyi 		strInfoText = szText;
10476af099aSliuyi 		break;
10576af099aSliuyi 	}
10676af099aSliuyi 	if (strInfoText.size() > 0){
10776af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
10876af099aSliuyi 		CURSOR_DEL_LINE;
10976af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
11076af099aSliuyi 	}
11176af099aSliuyi 	if (emCall == CALL_LAST)
11276af099aSliuyi 		deviceLayer = 0;
11376af099aSliuyi }
11476af099aSliuyi 
11576af099aSliuyi char *strupr(char *szSrc)
11676af099aSliuyi {
11776af099aSliuyi 	char *p = szSrc;
11876af099aSliuyi 	while(*p){
11976af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
12076af099aSliuyi 			*p = *p - 'a' + 'A';
12176af099aSliuyi 		p++;
12276af099aSliuyi 	}
12376af099aSliuyi 	return szSrc;
12476af099aSliuyi }
12576af099aSliuyi void PrintData(PBYTE pData, int nSize)
12676af099aSliuyi {
12776af099aSliuyi 	char szPrint[17] = "\0";
12876af099aSliuyi 	int i;
12976af099aSliuyi 	for( i = 0; i < nSize; i++){
13076af099aSliuyi 		if(i % 16 == 0){
13176af099aSliuyi 			if(i / 16 > 0)
13276af099aSliuyi 				printf("     %s\r\n", szPrint);
13376af099aSliuyi 			printf("%08d ", i / 16);
13476af099aSliuyi 		}
13576af099aSliuyi 		printf("%02X ", pData[i]);
13676af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
13776af099aSliuyi 	}
13876af099aSliuyi 	if(i / 16 > 0)
13976af099aSliuyi 		printf("     %s\r\n", szPrint);
14076af099aSliuyi }
14176af099aSliuyi 
14276af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
14376af099aSliuyi {
14476af099aSliuyi 	if (!pszSrc)
14576af099aSliuyi 		return false;
14676af099aSliuyi 	int nSrcLen = strlen(pszSrc);
14776af099aSliuyi 	int nDestLen = nSrcLen * 2;
14876af099aSliuyi 
14976af099aSliuyi 	pszDest = NULL;
15076af099aSliuyi 	pszDest = new wchar_t[nDestLen];
15176af099aSliuyi 	if (!pszDest)
15276af099aSliuyi 		return false;
15376af099aSliuyi 	nDestLen = nDestLen * sizeof(wchar_t);
15476af099aSliuyi 	memset(pszDest, 0, nDestLen);
15576af099aSliuyi 	int iRet;
15676af099aSliuyi 	iconv_t cd;
15776af099aSliuyi 	cd = iconv_open("UTF-32", "UTF-8");
15876af099aSliuyi 	if((iconv_t)-1 == cd) {
15976af099aSliuyi 		delete []pszDest;
16076af099aSliuyi 		pszDest = NULL;
16176af099aSliuyi 	      return false;
16276af099aSliuyi 	 }
16376af099aSliuyi 	char *pIn, *pOut;
16476af099aSliuyi 	pIn = (char *)pszSrc;
16576af099aSliuyi 	pOut = (char *)pszDest;
16676af099aSliuyi 
16776af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
16876af099aSliuyi 
16976af099aSliuyi 	if(iRet == -1) {
17076af099aSliuyi 		delete []pszDest;
17176af099aSliuyi 		pszDest = NULL;
17276af099aSliuyi 		iconv_close(cd);
17376af099aSliuyi 		return false;
17476af099aSliuyi 	 }
17576af099aSliuyi 
17676af099aSliuyi 	 iconv_close(cd);
17776af099aSliuyi 
17876af099aSliuyi 	 return true;
17976af099aSliuyi }
18076af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
18176af099aSliuyi {
18276af099aSliuyi 	if (!pszSrc)
18376af099aSliuyi 		return false;
18476af099aSliuyi 	int nSrcLen = wcslen(pszSrc);
18576af099aSliuyi 	int nDestLen = nSrcLen * 2;
18676af099aSliuyi 	nSrcLen = nSrcLen * sizeof(wchar_t);
18776af099aSliuyi 	pszDest = NULL;
18876af099aSliuyi 	pszDest = new char[nDestLen];
18976af099aSliuyi 	if (!pszDest)
19076af099aSliuyi 		return false;
19176af099aSliuyi 	memset(pszDest, 0, nDestLen);
19276af099aSliuyi 	int iRet;
19376af099aSliuyi 	iconv_t cd;
19476af099aSliuyi 	cd = iconv_open("UTF-8", "UTF-32");
19576af099aSliuyi 
19676af099aSliuyi 	if((iconv_t)-1 == cd) {
19776af099aSliuyi 		delete []pszDest;
19876af099aSliuyi 		pszDest = NULL;
19976af099aSliuyi 	      return false;
20076af099aSliuyi 	 }
20176af099aSliuyi 	char *pIn, *pOut;
20276af099aSliuyi 	pIn = (char *)pszSrc;
20376af099aSliuyi 	pOut = (char *)pszDest;
20476af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
20576af099aSliuyi 
20676af099aSliuyi 	if(iRet == -1) {
20776af099aSliuyi 		delete []pszDest;
20876af099aSliuyi 		pszDest = NULL;
20976af099aSliuyi 		iconv_close(cd);
21076af099aSliuyi 		return false;
21176af099aSliuyi 	 }
21276af099aSliuyi 
21376af099aSliuyi 	 iconv_close(cd);
21476af099aSliuyi 
21576af099aSliuyi 	 return true;
21676af099aSliuyi }
217c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName)
21876af099aSliuyi {
21976af099aSliuyi 	unsigned int i;
220c29e5f0fSliuyi 	for(i = 0; i < vecItems.size(); i++){
221c29e5f0fSliuyi 		if (strcasecmp(pszName, vecItems[i].szItemName) == 0){
22276af099aSliuyi 			return i;
22376af099aSliuyi 		}
22476af099aSliuyi 	}
22576af099aSliuyi 	return -1;
22676af099aSliuyi }
227c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid)
228c29e5f0fSliuyi {
229c29e5f0fSliuyi 	unsigned int i;
230c29e5f0fSliuyi 	char value;
231c29e5f0fSliuyi 	memset(uuid, 0, 16);
232c29e5f0fSliuyi 	for (i =0; i < strUUid.size(); i++) {
233c29e5f0fSliuyi 		value = 0;
234c29e5f0fSliuyi 		if ((strUUid[i] >= '0')&&(strUUid[i] <= '9'))
235c29e5f0fSliuyi 			value = strUUid[i] - '0';
236c29e5f0fSliuyi 		if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f'))
237c29e5f0fSliuyi 			value = strUUid[i] - 'a' + 10;
238c29e5f0fSliuyi 		if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F'))
239c29e5f0fSliuyi 			value = strUUid[i] - 'A' + 10;
240c29e5f0fSliuyi 		if ((i % 2) == 0)
241c29e5f0fSliuyi 			uuid[i / 2] += (value << 4);
242c29e5f0fSliuyi 		else
243c29e5f0fSliuyi 			uuid[i / 2] += value;
244c29e5f0fSliuyi 	}
245c29e5f0fSliuyi 	unsigned int *p32;
246c29e5f0fSliuyi 	unsigned short *p16;
247c29e5f0fSliuyi 	p32 = (unsigned int*)uuid;
248c29e5f0fSliuyi 	*p32 = cpu_to_be32(*p32);
249c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 4);
250c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
251c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 6);
252c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
253c29e5f0fSliuyi }
25476af099aSliuyi 
25576af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
25676af099aSliuyi {
25776af099aSliuyi 
25876af099aSliuyi 	stringstream configStream(pConfig);
25976af099aSliuyi 	string strLine, strItemName, strItemValue;
26076af099aSliuyi 	string::size_type line_size,pos;
26176af099aSliuyi 	STRUCT_CONFIG_ITEM item;
26276af099aSliuyi 	vecItem.clear();
26376af099aSliuyi 	while (!configStream.eof()){
26476af099aSliuyi 		getline(configStream, strLine);
26576af099aSliuyi 		line_size = strLine.size();
26676af099aSliuyi 		if (line_size == 0)
26776af099aSliuyi 			continue;
26876af099aSliuyi 		if (strLine[line_size-1] == '\r'){
26976af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
27076af099aSliuyi 		}
271c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
272c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
273c30d921cSKever Yang 		if (strLine.size()==0 )
274c30d921cSKever Yang 			continue;
275c30d921cSKever Yang 		if (strLine[0] == '#')
276c30d921cSKever Yang 			continue;
27776af099aSliuyi 		pos = strLine.find("=");
27876af099aSliuyi 		if (pos == string::npos){
27976af099aSliuyi 			continue;
28076af099aSliuyi 		}
28176af099aSliuyi 		strItemName = strLine.substr(0, pos);
28276af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
28376af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
28476af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
28576af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
28676af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
28776af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
28876af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
28976af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
29076af099aSliuyi 			vecItem.push_back(item);
29176af099aSliuyi 		}
29276af099aSliuyi 	}
29376af099aSliuyi 	return true;
29476af099aSliuyi 
29576af099aSliuyi }
29676af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
29776af099aSliuyi {
29876af099aSliuyi 	FILE *file = NULL;
29976af099aSliuyi 	file = fopen(pConfigFile, "rb");
30076af099aSliuyi 	if( !file ){
30176af099aSliuyi 		if (g_pLogObject)
30232268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile);
30376af099aSliuyi 		return false;
30476af099aSliuyi 	}
30576af099aSliuyi 	int iFileSize;
30676af099aSliuyi 	fseek(file, 0, SEEK_END);
30776af099aSliuyi 	iFileSize = ftell(file);
30876af099aSliuyi 	fseek(file, 0, SEEK_SET);
30976af099aSliuyi 	char *pConfigBuf = NULL;
31076af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
31176af099aSliuyi 	if (!pConfigBuf){
31276af099aSliuyi 		fclose(file);
31376af099aSliuyi 		return false;
31476af099aSliuyi 	}
31576af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
31676af099aSliuyi 	int iRead;
31776af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
31876af099aSliuyi 	if (iRead != iFileSize){
31976af099aSliuyi 		if (g_pLogObject)
32032268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize);
32176af099aSliuyi 		fclose(file);
32276af099aSliuyi 		delete []pConfigBuf;
32376af099aSliuyi 		return false;
32476af099aSliuyi 	}
32576af099aSliuyi 	fclose(file);
32676af099aSliuyi 	bool bRet;
32776af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
32876af099aSliuyi 	delete []pConfigBuf;
32976af099aSliuyi 	return bRet;
33076af099aSliuyi }
331c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
332c30d921cSKever Yang {
333c30d921cSKever Yang 	string::size_type pos,prevPos;
334c30d921cSKever Yang 	string strOffset,strLen;
335c30d921cSKever Yang 	int iCount;
336c30d921cSKever Yang 	prevPos = pos = 0;
337c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
338c30d921cSKever Yang 		return false;
339c30d921cSKever Yang 	}
340c30d921cSKever Yang 	pos = strPartInfo.find('@');
341c30d921cSKever Yang 	if (pos == string::npos) {
342c30d921cSKever Yang 		return false;
343c30d921cSKever Yang 	}
344c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
345c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
346c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
347c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
348c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
349c30d921cSKever Yang 	} else {
350c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
351c30d921cSKever Yang 		if (iCount != 1) {
352c30d921cSKever Yang 			return false;
353c30d921cSKever Yang 		}
354c30d921cSKever Yang 	}
355c30d921cSKever Yang 
356c30d921cSKever Yang 	prevPos = pos + 1;
357c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
358c30d921cSKever Yang 	if (pos == string::npos) {
359c30d921cSKever Yang 		return false;
360c30d921cSKever Yang 	}
361c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
362c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
363c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
364c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
365c30d921cSKever Yang 	if (iCount != 1) {
366c30d921cSKever Yang 		return false;
367c30d921cSKever Yang 	}
368c30d921cSKever Yang 	prevPos = pos + 1;
369c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
370c30d921cSKever Yang 	if (pos == string::npos) {
371c30d921cSKever Yang 		return false;
372c30d921cSKever Yang 	}
373c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
374c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
375c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
376c30d921cSKever Yang 
377c30d921cSKever Yang 	return true;
378c30d921cSKever Yang }
379c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid)
380c29e5f0fSliuyi {
381c29e5f0fSliuyi 	string::size_type pos(0);
382c30d921cSKever Yang 
383c29e5f0fSliuyi 	if (strUuidInfo.size() <= 0) {
384c29e5f0fSliuyi 		return false;
385c29e5f0fSliuyi 	}
386c29e5f0fSliuyi 	pos = strUuidInfo.find('=');
387c29e5f0fSliuyi 	if (pos == string::npos) {
388c29e5f0fSliuyi 		return false;
389c29e5f0fSliuyi 	}
390c29e5f0fSliuyi 	strName = strUuidInfo.substr(0, pos);
391c29e5f0fSliuyi 	strName.erase(0, strName.find_first_not_of(" "));
392c29e5f0fSliuyi 	strName.erase(strName.find_last_not_of(" ") + 1);
393c29e5f0fSliuyi 
394c29e5f0fSliuyi 	strUUid = strUuidInfo.substr(pos+1);
395c29e5f0fSliuyi 	strUUid.erase(0, strUUid.find_first_not_of(" "));
396c29e5f0fSliuyi 	strUUid.erase(strUUid.find_last_not_of(" ") + 1);
397c29e5f0fSliuyi 
398c29e5f0fSliuyi 	while(true) {
399c29e5f0fSliuyi 		pos = 0;
400c29e5f0fSliuyi 		if( (pos = strUUid.find("-")) != string::npos)
401c29e5f0fSliuyi 			strUUid.replace(pos,1,"");
402c29e5f0fSliuyi 		else
403c29e5f0fSliuyi 			break;
404c29e5f0fSliuyi 	}
405c29e5f0fSliuyi 	if (strUUid.size() != 32)
406c29e5f0fSliuyi 		return false;
407c29e5f0fSliuyi 	return true;
408c29e5f0fSliuyi }
409c29e5f0fSliuyi 
410c29e5f0fSliuyi 
411c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
412c30d921cSKever Yang {
413c30d921cSKever Yang 	stringstream paramStream(pParameter);
414c30d921cSKever Yang 	bool bRet,bFind = false;
415c29e5f0fSliuyi 	string strLine, strPartition, strPartInfo, strPartName, strUUid;
416c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
417c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
418c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
419c29e5f0fSliuyi 	STRUCT_CONFIG_ITEM uuid_item;
420c30d921cSKever Yang 	vecItem.clear();
421c29e5f0fSliuyi 	vecUuidItem.clear();
422c30d921cSKever Yang 	while (!paramStream.eof()) {
423c30d921cSKever Yang 		getline(paramStream,strLine);
424c30d921cSKever Yang 		line_size = strLine.size();
425c30d921cSKever Yang 		if (line_size == 0)
426c30d921cSKever Yang 			continue;
427c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
428c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
429c30d921cSKever Yang 		}
430c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
431c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
432c30d921cSKever Yang 		if (strLine.size()==0 )
433c30d921cSKever Yang 			continue;
434c30d921cSKever Yang 		if (strLine[0] == '#')
435c30d921cSKever Yang 			continue;
436c29e5f0fSliuyi 		pos = strLine.find("uuid:");
437c29e5f0fSliuyi 		if (pos != string::npos) {
438c29e5f0fSliuyi 			strPartInfo = strLine.substr(pos+5);
439c29e5f0fSliuyi 			bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid);
440c29e5f0fSliuyi 			if (bRet) {
441c29e5f0fSliuyi 				strcpy(uuid_item.szItemName, strPartName.c_str());
442c29e5f0fSliuyi 				string_to_uuid(strUUid,uuid_item.szItemValue);
443c29e5f0fSliuyi 				vecUuidItem.push_back(uuid_item);
444c29e5f0fSliuyi 			}
445c29e5f0fSliuyi 			continue;
446c29e5f0fSliuyi 		}
447c29e5f0fSliuyi 
448c30d921cSKever Yang 		pos = strLine.find("mtdparts");
449c30d921cSKever Yang 		if (pos == string::npos) {
450c30d921cSKever Yang 			continue;
451c30d921cSKever Yang 		}
452c30d921cSKever Yang 		bFind = true;
453c30d921cSKever Yang 		posColon = strLine.find(':', pos);
454c30d921cSKever Yang 		if (posColon == string::npos) {
455c30d921cSKever Yang 			continue;
456c30d921cSKever Yang 		}
457c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
458c30d921cSKever Yang 		pos = 0;
459c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
460c30d921cSKever Yang 		while (posComma != string::npos) {
461c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
462c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
463c30d921cSKever Yang 			if (bRet) {
464c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
465c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
466c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
467c30d921cSKever Yang 				vecItem.push_back(item);
468c30d921cSKever Yang 			}
469c30d921cSKever Yang 			pos = posComma + 1;
470c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
471c30d921cSKever Yang 		}
472c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
473c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
474c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
475c30d921cSKever Yang 			if (bRet) {
476c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
477c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
478c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
479c30d921cSKever Yang 				vecItem.push_back(item);
480c30d921cSKever Yang 			}
481c30d921cSKever Yang 		}
482c30d921cSKever Yang 		break;
483c30d921cSKever Yang 	}
484c30d921cSKever Yang 	return bFind;
485c30d921cSKever Yang 
486c30d921cSKever Yang }
487c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
488c30d921cSKever Yang {
489c30d921cSKever Yang 	FILE *file = NULL;
490c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
491c30d921cSKever Yang 	if( !file ) {
492c30d921cSKever Yang 		if (g_pLogObject)
49332268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
494c30d921cSKever Yang 		return false;
495c30d921cSKever Yang 	}
496c30d921cSKever Yang 	int iFileSize;
497c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
498c30d921cSKever Yang 	iFileSize = ftell(file);
499c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
500c30d921cSKever Yang 	char *pParamBuf = NULL;
501c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
502c30d921cSKever Yang 	if (!pParamBuf) {
503c30d921cSKever Yang 		fclose(file);
504c30d921cSKever Yang 		return false;
505c30d921cSKever Yang 	}
506c30d921cSKever Yang 	int iRead;
507c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
508c30d921cSKever Yang 	if (iRead != iFileSize) {
509c30d921cSKever Yang 		if (g_pLogObject)
51032268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
511c30d921cSKever Yang 		fclose(file);
512c30d921cSKever Yang 		delete []pParamBuf;
513c30d921cSKever Yang 		return false;
514c30d921cSKever Yang 	}
515c30d921cSKever Yang 	fclose(file);
516c30d921cSKever Yang 	bool bRet;
517c29e5f0fSliuyi 	bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem);
518c30d921cSKever Yang 	delete []pParamBuf;
519c30d921cSKever Yang 	return bRet;
520c30d921cSKever Yang }
5216ae612beSliuyi bool is_sparse_image(char *szImage)
5226ae612beSliuyi {
5236ae612beSliuyi 	FILE *file = NULL;
5246ae612beSliuyi 	sparse_header head;
5256ae612beSliuyi 	u32 uiRead;
5266ae612beSliuyi 	file = fopen(szImage, "rb");
5276ae612beSliuyi 	if( !file ) {
5286ae612beSliuyi 		if (g_pLogObject)
5296ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
5306ae612beSliuyi 		return false;
5316ae612beSliuyi 	}
5326ae612beSliuyi 	uiRead = fread(&head, 1, sizeof(head), file);
5336ae612beSliuyi 	if (uiRead != sizeof(head)) {
5346ae612beSliuyi 		if (g_pLogObject)
5356ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head));
5366ae612beSliuyi 		fclose(file);
5376ae612beSliuyi 		return false;
5386ae612beSliuyi 	}
5396ae612beSliuyi 	fclose(file);
5406ae612beSliuyi 	if (head.magic!=SPARSE_HEADER_MAGIC)
5416ae612beSliuyi 	{
5426ae612beSliuyi 		return false;
5436ae612beSliuyi 	}
5446ae612beSliuyi 	return true;
5456ae612beSliuyi 
5466ae612beSliuyi }
547c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
548c30d921cSKever Yang {
549c30d921cSKever Yang 	efi_guid_t id;
550c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
551c30d921cSKever Yang 	unsigned int i;
552c30d921cSKever Yang 
553c30d921cSKever Yang 	/* Set all fields randomly */
554c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
555c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
556c30d921cSKever Yang 
557c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
558c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
559c30d921cSKever Yang 
560c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
561c30d921cSKever Yang }
562c30d921cSKever Yang 
563c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup)
564c29e5f0fSliuyi {
565c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
566c29e5f0fSliuyi 	gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
567c29e5f0fSliuyi 	u32 calc_crc32;
568c29e5f0fSliuyi 	u64 val;
569c29e5f0fSliuyi 
570c29e5f0fSliuyi 	/* recalculate the values for the Backup GPT Header */
571c29e5f0fSliuyi 	val = le64_to_cpu(gptMasterHead->my_lba);
572c29e5f0fSliuyi 	gptBackupHead->my_lba = gptMasterHead->alternate_lba;
573c29e5f0fSliuyi 	gptBackupHead->alternate_lba = cpu_to_le64(val);
574c29e5f0fSliuyi 	gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
575c29e5f0fSliuyi 	gptBackupHead->header_crc32 = 0;
576c29e5f0fSliuyi 
577c29e5f0fSliuyi 	calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
578c29e5f0fSliuyi 	gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
579c29e5f0fSliuyi }
5806ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end)
5816ae612beSliuyi {
5826ae612beSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
5836ae612beSliuyi 	gpt_entry  *gptEntry  = NULL;
5846ae612beSliuyi 	u32 i,j;
5856ae612beSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
5866ae612beSliuyi 	bool bFound = false;
5876ae612beSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
5886ae612beSliuyi 
5896ae612beSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
5906ae612beSliuyi 		gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
5916ae612beSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
5926ae612beSliuyi 			break;
5936ae612beSliuyi 		for (j = 0; j < strlen(pszName); j++)
5946ae612beSliuyi 			if (gptEntry->partition_name[j] != pszName[j])
5956ae612beSliuyi 				break;
5966ae612beSliuyi 		if (gptEntry->partition_name[j] != 0)
5976ae612beSliuyi 			continue;
5986ae612beSliuyi 		if (j == strlen(pszName)) {
5996ae612beSliuyi 			bFound = true;
6006ae612beSliuyi 			break;
6016ae612beSliuyi 		}
6026ae612beSliuyi 	}
6036ae612beSliuyi 	if (bFound) {
6046ae612beSliuyi 		*lba = le64_to_cpu(gptEntry->starting_lba);
6056ae612beSliuyi 		*lba_end =  le64_to_cpu(gptEntry->ending_lba);
6066ae612beSliuyi 		return true;
6076ae612beSliuyi 	}
6086ae612beSliuyi 	return false;
6096ae612beSliuyi }
610c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector)
611c29e5f0fSliuyi {
612c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
613c29e5f0fSliuyi 	gpt_entry  *gptLastPartEntry  = NULL;
614c29e5f0fSliuyi 	u32 i;
615c29e5f0fSliuyi 	u64 old_disksize;
616c29e5f0fSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
617c29e5f0fSliuyi 
618c29e5f0fSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
619c29e5f0fSliuyi 	old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1;
620c29e5f0fSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
621c29e5f0fSliuyi 		gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
622c29e5f0fSliuyi 		if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0)
623c29e5f0fSliuyi 			break;
624c29e5f0fSliuyi 	}
625c29e5f0fSliuyi 	i--;
626c29e5f0fSliuyi 	gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry));
627c29e5f0fSliuyi 
628c29e5f0fSliuyi 	gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1);
629c29e5f0fSliuyi 	gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34);
630c29e5f0fSliuyi 
631c29e5f0fSliuyi 	if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition
632c29e5f0fSliuyi 		gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34);
633c29e5f0fSliuyi 		gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
634c29e5f0fSliuyi 	}
635c29e5f0fSliuyi 	gptMasterHead->header_crc32 = 0;
636c29e5f0fSliuyi 	gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header)));
637c29e5f0fSliuyi 	memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS);
638c29e5f0fSliuyi 	memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE);
639c29e5f0fSliuyi 	prepare_gpt_backup(master, backup);
640c29e5f0fSliuyi 
641c29e5f0fSliuyi }
642c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup)
643c29e5f0fSliuyi {
644c29e5f0fSliuyi 	FILE *file = NULL;
645c29e5f0fSliuyi 	file = fopen(pParamFile, "rb");
646c29e5f0fSliuyi 	if( !file ) {
647c29e5f0fSliuyi 		if (g_pLogObject)
648c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
649c29e5f0fSliuyi 		return false;
650c29e5f0fSliuyi 	}
651c29e5f0fSliuyi 	int iFileSize;
652c29e5f0fSliuyi 	fseek(file, 0, SEEK_END);
653c29e5f0fSliuyi 	iFileSize = ftell(file);
654c29e5f0fSliuyi 	fseek(file, 0, SEEK_SET);
655c29e5f0fSliuyi 	if (iFileSize != 67 * SECTOR_SIZE) {
656c29e5f0fSliuyi 		if (g_pLogObject)
657c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile);
658c29e5f0fSliuyi 		fclose(file);
659c29e5f0fSliuyi 		return false;
660c29e5f0fSliuyi 	}
661c29e5f0fSliuyi 
662c29e5f0fSliuyi 	int iRead;
663c29e5f0fSliuyi 	iRead = fread(master, 1, 34 * SECTOR_SIZE, file);
664c29e5f0fSliuyi 	if (iRead != 34 * SECTOR_SIZE) {
665c29e5f0fSliuyi 		if (g_pLogObject)
666c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE);
667c29e5f0fSliuyi 		fclose(file);
668c29e5f0fSliuyi 		return false;
669c29e5f0fSliuyi 	}
670c29e5f0fSliuyi 	iRead = fread(backup, 1, 33 * SECTOR_SIZE, file);
671c29e5f0fSliuyi 	if (iRead != 33 * SECTOR_SIZE) {
672c29e5f0fSliuyi 		if (g_pLogObject)
673c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE);
674c29e5f0fSliuyi 		fclose(file);
675c29e5f0fSliuyi 		return false;
676c29e5f0fSliuyi 	}
677c29e5f0fSliuyi 	fclose(file);
678c29e5f0fSliuyi 	return true;
679c29e5f0fSliuyi }
680c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
681c30d921cSKever Yang {
682c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
683c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
684c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
685c30d921cSKever Yang 	u32 i,j;
686c29e5f0fSliuyi 	int pos;
687c30d921cSKever Yang 	string strPartName;
688c30d921cSKever Yang 	string::size_type colonPos;
689c30d921cSKever Yang 	/*1.protective mbr*/
690c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
691c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
692c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
693c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
694c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
695c30d921cSKever Yang 	/*2.gpt header*/
696c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
697c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
698c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
699c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
700c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
701c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
702c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
703c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
704c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
705c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
706c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
707c30d921cSKever Yang 	gptHead->header_crc32 = 0;
708c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
709c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
710c30d921cSKever Yang 
711c30d921cSKever Yang 	/*3.gpt partition entry*/
712c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
713c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
714c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
715c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
716c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
717c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
718c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
719c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
720c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
721c30d921cSKever Yang 		if (colonPos != string::npos) {
722c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
723c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
724c29e5f0fSliuyi 			if (strPartName.find("grow") != string::npos)
725c29e5f0fSliuyi 				gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
726c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
727c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
728c30d921cSKever Yang 		}
729c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
730c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
731c29e5f0fSliuyi 		if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1)
732c29e5f0fSliuyi 			memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
733c30d921cSKever Yang 		gptEntry++;
734c30d921cSKever Yang 	}
735c30d921cSKever Yang 
736c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
737c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
738c30d921cSKever Yang 
739c30d921cSKever Yang }
740b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
741c30d921cSKever Yang {
742c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
743c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
744c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
745c30d921cSKever Yang 
746c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
747b38fe5fcSliuyi 	pSec0->uiRc4Flag = rc4Flag;
748c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
749c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
750c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
751c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
752c30d921cSKever Yang 	return true;
753c30d921cSKever Yang }
754c30d921cSKever Yang 
755c30d921cSKever Yang 
756c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
757c30d921cSKever Yang {
758c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
759c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
760c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
761c30d921cSKever Yang 
762c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
763c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
764c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
765c30d921cSKever Yang 	return true;
766c30d921cSKever Yang }
767c30d921cSKever Yang 
768c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
769c30d921cSKever Yang {
770c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
771c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
772c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
773c30d921cSKever Yang 
774c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
775c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
776c30d921cSKever Yang 	return true;
777c30d921cSKever Yang }
778c30d921cSKever Yang 
779c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
780c30d921cSKever Yang {
781c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
782c30d921cSKever Yang 	return true;
783c30d921cSKever Yang }
784c30d921cSKever Yang 
785b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
786c30d921cSKever Yang {
787c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
788c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
789c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
790c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
791c30d921cSKever Yang 	UINT i;
792b38fe5fcSliuyi 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
793c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
794c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
795c30d921cSKever Yang 		return -6;
796c30d921cSKever Yang 	}
797c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
798c30d921cSKever Yang 		return -7;
799c30d921cSKever Yang 	}
800c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
801c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
802c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
803c30d921cSKever Yang 
804c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
805c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
806c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
807b38fe5fcSliuyi 
808b38fe5fcSliuyi 	if (rc4Flag) {
809b38fe5fcSliuyi 		for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
810b38fe5fcSliuyi 			P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
811b38fe5fcSliuyi 		for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
812b38fe5fcSliuyi 			P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
813b38fe5fcSliuyi 	}
814b38fe5fcSliuyi 
815c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
816c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
817c30d921cSKever Yang 
818c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
819c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
820c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
821c30d921cSKever Yang 		if(i == 1) {
822c30d921cSKever Yang 			continue;
823c30d921cSKever Yang 		} else {
824c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
825c30d921cSKever Yang 		}
826c30d921cSKever Yang 	}
827c30d921cSKever Yang 	return 0;
828c30d921cSKever Yang }
829c30d921cSKever Yang 
830c30d921cSKever Yang 
83176af099aSliuyi 
83276af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
83376af099aSliuyi {
83476af099aSliuyi 	if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
83576af099aSliuyi 		return true;
83676af099aSliuyi 	else
83776af099aSliuyi 	{
83876af099aSliuyi 		ERROR_COLOR_ATTR;
83932268622SAndreas Färber 		printf("The device does not support this operation!");
84076af099aSliuyi 		NORMAL_COLOR_ATTR;
84176af099aSliuyi 		printf("\r\n");
84276af099aSliuyi 		return false;
84376af099aSliuyi 	}
84476af099aSliuyi }
845c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
846c30d921cSKever Yang {
847c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
848c30d921cSKever Yang 	u32 total_size_sector;
849c30d921cSKever Yang 	CRKComm *pComm = NULL;
850c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
851c29e5f0fSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
852c30d921cSKever Yang 	int iRet;
853c30d921cSKever Yang 	bool bRet, bSuccess = false;
854c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
855c30d921cSKever Yang 		return false;
856c30d921cSKever Yang 
857c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
858c30d921cSKever Yang 	if (!bRet) {
859c30d921cSKever Yang 		ERROR_COLOR_ATTR;
860c30d921cSKever Yang 		printf("Creating Comm Object failed!");
861c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
862c30d921cSKever Yang 		printf("\r\n");
863c30d921cSKever Yang 		return bSuccess;
864c30d921cSKever Yang 	}
86532268622SAndreas Färber 	printf("Writing gpt...\r\n");
866c30d921cSKever Yang 	//1.get flash info
867c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
868c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
869c30d921cSKever Yang 		ERROR_COLOR_ATTR;
870c30d921cSKever Yang 		printf("Reading Flash Info failed!");
871c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
872c30d921cSKever Yang 		printf("\r\n");
873c30d921cSKever Yang 		return bSuccess;
874c30d921cSKever Yang 	}
875c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
876c29e5f0fSliuyi 	if (strstr(szParameter, ".img")) {
877c29e5f0fSliuyi 		if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) {
878c29e5f0fSliuyi 			ERROR_COLOR_ATTR;
879c29e5f0fSliuyi 			printf("Loading partition image failed!");
880c29e5f0fSliuyi 			NORMAL_COLOR_ATTR;
881c29e5f0fSliuyi 			printf("\r\n");
882c29e5f0fSliuyi 			return bSuccess;
883c29e5f0fSliuyi 		}
884c29e5f0fSliuyi 		update_gpt_disksize(master_gpt, backup_gpt, total_size_sector);
885c29e5f0fSliuyi 	} else {
886c30d921cSKever Yang 		//2.get partition from parameter
887c29e5f0fSliuyi 		bRet = parse_parameter_file(szParameter, vecItems, vecUuid);
888c30d921cSKever Yang 		if (!bRet) {
889c30d921cSKever Yang 			ERROR_COLOR_ATTR;
890c30d921cSKever Yang 			printf("Parsing parameter failed!");
891c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
892c30d921cSKever Yang 			printf("\r\n");
893c30d921cSKever Yang 			return bSuccess;
894c30d921cSKever Yang 		}
895c29e5f0fSliuyi 		vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33;
896c30d921cSKever Yang 		//3.generate gpt info
897c29e5f0fSliuyi 		create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector);
898c30d921cSKever Yang 		memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
899c30d921cSKever Yang 		memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
900c29e5f0fSliuyi 		prepare_gpt_backup(master_gpt, backup_gpt);
901c29e5f0fSliuyi 	}
902c29e5f0fSliuyi 
903c30d921cSKever Yang 	//4. write gpt
904c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
905c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
906c30d921cSKever Yang 		ERROR_COLOR_ATTR;
907c30d921cSKever Yang 		printf("Writing master gpt failed!");
908c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
909c30d921cSKever Yang 		printf("\r\n");
910c30d921cSKever Yang 		return bSuccess;
911c30d921cSKever Yang 	}
912c29e5f0fSliuyi 	iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt);
913c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
914c30d921cSKever Yang 		ERROR_COLOR_ATTR;
915c30d921cSKever Yang 		printf("Writing backup gpt failed!");
916c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
917c30d921cSKever Yang 		printf("\r\n");
918c30d921cSKever Yang 		return bSuccess;
919c30d921cSKever Yang 	}
920c29e5f0fSliuyi 
921c30d921cSKever Yang 	bSuccess = true;
922c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
923c30d921cSKever Yang 	CURSOR_DEL_LINE;
92432268622SAndreas Färber 	printf("Writing gpt succeeded.\r\n");
925c30d921cSKever Yang 	return bSuccess;
926c30d921cSKever Yang }
92776af099aSliuyi 
92878884ef4SEddie Cai #include "boot_merger.h"
92978884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
93078884ef4SEddie Cai options gOpts;
93178884ef4SEddie Cai 
93278884ef4SEddie Cai 
93378884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
93478884ef4SEddie Cai char* gConfigPath;
93578884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
93678884ef4SEddie Cai 
93778884ef4SEddie Cai static inline void fixPath(char* path) {
93878884ef4SEddie Cai 	int i, len = strlen(path);
93978884ef4SEddie Cai 	for(i=0; i<len; i++) {
94078884ef4SEddie Cai 		if (path[i] == '\\')
94178884ef4SEddie Cai 			path[i] = '/';
94278884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
94378884ef4SEddie Cai 			path[i] = '\0';
94478884ef4SEddie Cai 	}
94578884ef4SEddie Cai }
94678884ef4SEddie Cai 
94778884ef4SEddie Cai static bool parseChip(FILE* file) {
94878884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
94978884ef4SEddie Cai 		return false;
95078884ef4SEddie Cai 	}
95178884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
95278884ef4SEddie Cai 		return false;
95378884ef4SEddie Cai 	}
95478884ef4SEddie Cai 	printf("chip: %s\n", gOpts.chip);
95578884ef4SEddie Cai 	return true;
95678884ef4SEddie Cai }
95778884ef4SEddie Cai 
95878884ef4SEddie Cai static bool parseVersion(FILE* file) {
95978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
96078884ef4SEddie Cai 		return false;
96178884ef4SEddie Cai 	}
96278884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
96378884ef4SEddie Cai 		return false;
96478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
96578884ef4SEddie Cai 		return false;
96678884ef4SEddie Cai 	}
96778884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
96878884ef4SEddie Cai 		return false;
96978884ef4SEddie Cai 	printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
97078884ef4SEddie Cai 	return true;
97178884ef4SEddie Cai }
97278884ef4SEddie Cai 
97378884ef4SEddie Cai static bool parse471(FILE* file) {
97478884ef4SEddie Cai 	int i, index, pos;
97578884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
97678884ef4SEddie Cai 
97778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
97878884ef4SEddie Cai 		return false;
97978884ef4SEddie Cai 	}
98078884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
98178884ef4SEddie Cai 		return false;
98278884ef4SEddie Cai 	printf("num: %d\n", gOpts.code471Num);
98378884ef4SEddie Cai 	if (!gOpts.code471Num)
98478884ef4SEddie Cai 		return true;
98578884ef4SEddie Cai 	if (gOpts.code471Num < 0)
98678884ef4SEddie Cai 		return false;
98778884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
98878884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
98978884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
99078884ef4SEddie Cai 			return false;
99178884ef4SEddie Cai 		}
99278884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
99378884ef4SEddie Cai 				!= 2)
99478884ef4SEddie Cai 			return false;
99578884ef4SEddie Cai 		index--;
99678884ef4SEddie Cai 		fixPath(buf);
99778884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
99878884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code471Path[index]);
99978884ef4SEddie Cai 	}
100078884ef4SEddie Cai 	pos = ftell(file);
100178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
100278884ef4SEddie Cai 		return false;
100378884ef4SEddie Cai 	}
100478884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
100578884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
100678884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code471Sleep);
100778884ef4SEddie Cai 	return true;
100878884ef4SEddie Cai }
100978884ef4SEddie Cai 
101078884ef4SEddie Cai static bool parse472(FILE* file) {
101178884ef4SEddie Cai 	int i, index, pos;
101278884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
101378884ef4SEddie Cai 
101478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
101578884ef4SEddie Cai 		return false;
101678884ef4SEddie Cai 	}
101778884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
101878884ef4SEddie Cai 		return false;
101978884ef4SEddie Cai 	printf("num: %d\n", gOpts.code472Num);
102078884ef4SEddie Cai 	if (!gOpts.code472Num)
102178884ef4SEddie Cai 		return true;
102278884ef4SEddie Cai 	if (gOpts.code472Num < 0)
102378884ef4SEddie Cai 		return false;
102478884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
102578884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
102678884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
102778884ef4SEddie Cai 			return false;
102878884ef4SEddie Cai 		}
102978884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
103078884ef4SEddie Cai 				!= 2)
103178884ef4SEddie Cai 			return false;
103278884ef4SEddie Cai 		fixPath(buf);
103378884ef4SEddie Cai 		index--;
103478884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
103578884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code472Path[index]);
103678884ef4SEddie Cai 	}
103778884ef4SEddie Cai 	pos = ftell(file);
103878884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
103978884ef4SEddie Cai 		return false;
104078884ef4SEddie Cai 	}
104178884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
104278884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
104378884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code472Sleep);
104478884ef4SEddie Cai 	return true;
104578884ef4SEddie Cai }
104678884ef4SEddie Cai 
104778884ef4SEddie Cai static bool parseLoader(FILE* file) {
104878884ef4SEddie Cai 	int i, j, index, pos;
104978884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
105078884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
105178884ef4SEddie Cai 
105278884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
105378884ef4SEddie Cai 		return false;
105478884ef4SEddie Cai 	}
105578884ef4SEddie Cai 	pos = ftell(file);
105678884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
105778884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
105878884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
105978884ef4SEddie Cai 			return false;
106078884ef4SEddie Cai 		}
106178884ef4SEddie Cai 	}
106278884ef4SEddie Cai 	printf("num: %d\n", gOpts.loaderNum);
106378884ef4SEddie Cai 	if (!gOpts.loaderNum)
106478884ef4SEddie Cai 		return false;
106578884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
106678884ef4SEddie Cai 		return false;
106778884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
106878884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
106978884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
107078884ef4SEddie Cai 			return false;
107178884ef4SEddie Cai 		}
107278884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
107378884ef4SEddie Cai 				!= 2)
107478884ef4SEddie Cai 			return false;
107578884ef4SEddie Cai 		index--;
107678884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
107778884ef4SEddie Cai 		printf("name%d: %s\n", index, gOpts.loader[index].name);
107878884ef4SEddie Cai 	}
107978884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
108078884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
108178884ef4SEddie Cai 			return false;
108278884ef4SEddie Cai 		}
108378884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
108478884ef4SEddie Cai 				!= 2)
108578884ef4SEddie Cai 			return false;
108678884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
108778884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
108878884ef4SEddie Cai 				fixPath(buf2);
108978884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
109078884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
109178884ef4SEddie Cai 				break;
109278884ef4SEddie Cai 			}
109378884ef4SEddie Cai 		}
109478884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
109578884ef4SEddie Cai 			return false;
109678884ef4SEddie Cai 		}
109778884ef4SEddie Cai 	}
109878884ef4SEddie Cai 	return true;
109978884ef4SEddie Cai }
110078884ef4SEddie Cai 
110178884ef4SEddie Cai static bool parseOut(FILE* file) {
110278884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
110378884ef4SEddie Cai 		return false;
110478884ef4SEddie Cai 	}
110578884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
110678884ef4SEddie Cai 		return false;
110778884ef4SEddie Cai 	fixPath(gOpts.outPath);
110878884ef4SEddie Cai 	printf("out: %s\n", gOpts.outPath);
110978884ef4SEddie Cai 	return true;
111078884ef4SEddie Cai }
111178884ef4SEddie Cai 
111278884ef4SEddie Cai 
111378884ef4SEddie Cai void printOpts(FILE* out) {
111478884ef4SEddie Cai 	int i;
111578884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
111678884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
111778884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
111878884ef4SEddie Cai 
111978884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
112078884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
112178884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
112278884ef4SEddie Cai 	}
112378884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
112478884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
112578884ef4SEddie Cai 
112678884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
112778884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
112878884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
112978884ef4SEddie Cai 	}
113078884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
113178884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
113278884ef4SEddie Cai 
113378884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
113478884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
113578884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
113678884ef4SEddie Cai 	}
113778884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
113878884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
113978884ef4SEddie Cai 	}
114078884ef4SEddie Cai 
114178884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
114278884ef4SEddie Cai }
114378884ef4SEddie Cai 
114478884ef4SEddie Cai static bool parseOpts(void) {
114578884ef4SEddie Cai 	bool ret = false;
114678884ef4SEddie Cai 	bool chipOk = false;
114778884ef4SEddie Cai 	bool versionOk = false;
114878884ef4SEddie Cai 	bool code471Ok = true;
114978884ef4SEddie Cai 	bool code472Ok = true;
115078884ef4SEddie Cai 	bool loaderOk = false;
115178884ef4SEddie Cai 	bool outOk = false;
115278884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
115378884ef4SEddie Cai 
115478884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
115578884ef4SEddie Cai 	FILE* file;
115678884ef4SEddie Cai 	file = fopen(configPath, "r");
115778884ef4SEddie Cai 	if (!file) {
115878884ef4SEddie Cai 		fprintf(stderr, "config (%s) not found!\n", configPath);
115978884ef4SEddie Cai 		if (configPath == (char*)DEF_CONFIG_FILE) {
116078884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
116178884ef4SEddie Cai 			if (file) {
116232268622SAndreas Färber 				fprintf(stderr, "creating defconfig\n");
116378884ef4SEddie Cai 				printOpts(file);
116478884ef4SEddie Cai 			}
116578884ef4SEddie Cai 		}
116678884ef4SEddie Cai 		goto end;
116778884ef4SEddie Cai 	}
116878884ef4SEddie Cai 
116932268622SAndreas Färber 	printf("Starting to parse...\n");
117078884ef4SEddie Cai 
117178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
117278884ef4SEddie Cai 		goto end;
117378884ef4SEddie Cai 	}
117478884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
117578884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
117678884ef4SEddie Cai 			chipOk = parseChip(file);
117778884ef4SEddie Cai 			if (!chipOk) {
117878884ef4SEddie Cai 				printf("parseChip failed!\n");
117978884ef4SEddie Cai 				goto end;
118078884ef4SEddie Cai 			}
118178884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
118278884ef4SEddie Cai 			versionOk = parseVersion(file);
118378884ef4SEddie Cai 			if (!versionOk) {
118478884ef4SEddie Cai 				printf("parseVersion failed!\n");
118578884ef4SEddie Cai 				goto end;
118678884ef4SEddie Cai 			}
118778884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
118878884ef4SEddie Cai 			code471Ok = parse471(file);
118978884ef4SEddie Cai 			if (!code471Ok) {
119078884ef4SEddie Cai 				printf("parse471 failed!\n");
119178884ef4SEddie Cai 				goto end;
119278884ef4SEddie Cai 			}
119378884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
119478884ef4SEddie Cai 			code472Ok = parse472(file);
119578884ef4SEddie Cai 			if (!code472Ok) {
119678884ef4SEddie Cai 				printf("parse472 failed!\n");
119778884ef4SEddie Cai 				goto end;
119878884ef4SEddie Cai 			}
119978884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
120078884ef4SEddie Cai 			loaderOk = parseLoader(file);
120178884ef4SEddie Cai 			if (!loaderOk) {
120278884ef4SEddie Cai 				printf("parseLoader failed!\n");
120378884ef4SEddie Cai 				goto end;
120478884ef4SEddie Cai 			}
120578884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
120678884ef4SEddie Cai 			outOk = parseOut(file);
120778884ef4SEddie Cai 			if (!outOk) {
120878884ef4SEddie Cai 				printf("parseOut failed!\n");
120978884ef4SEddie Cai 				goto end;
121078884ef4SEddie Cai 			}
121178884ef4SEddie Cai 		} else if (buf[0] == '#') {
121278884ef4SEddie Cai 			continue;
121378884ef4SEddie Cai 		} else {
121478884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
121578884ef4SEddie Cai 			goto end;
121678884ef4SEddie Cai 		}
121778884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
121878884ef4SEddie Cai 			goto end;
121978884ef4SEddie Cai 		}
122078884ef4SEddie Cai 	}
122178884ef4SEddie Cai 
122278884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
122378884ef4SEddie Cai 			&& loaderOk && outOk)
122478884ef4SEddie Cai 		ret = true;
122578884ef4SEddie Cai end:
122678884ef4SEddie Cai 	if (file)
122778884ef4SEddie Cai 		fclose(file);
122878884ef4SEddie Cai 	return ret;
122978884ef4SEddie Cai }
123078884ef4SEddie Cai 
123178884ef4SEddie Cai bool initOpts(void) {
123278884ef4SEddie Cai 	//set default opts
123378884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
123478884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
123578884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
123678884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
123778884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
123878884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
123978884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
124078884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
124178884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
124278884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
124378884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
124478884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
124578884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
124678884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
124778884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
124878884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
124978884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
125078884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
125178884ef4SEddie Cai 
125278884ef4SEddie Cai 	return parseOpts();
125378884ef4SEddie Cai }
125478884ef4SEddie Cai 
125578884ef4SEddie Cai /************merge code****************/
125678884ef4SEddie Cai 
125778884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
125878884ef4SEddie Cai 	uint8_t tmp[2] = {0};
125978884ef4SEddie Cai 	int i;
126078884ef4SEddie Cai 	uint32_t ret;
126178884ef4SEddie Cai 	//if (value > 0xFFFF) {
126278884ef4SEddie Cai 	//	return 0;
126378884ef4SEddie Cai 	//}
126478884ef4SEddie Cai 	for(i=0; i < 2; i++) {
126578884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
126678884ef4SEddie Cai 		value /= 100;
126778884ef4SEddie Cai 	}
126878884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
126978884ef4SEddie Cai 
127078884ef4SEddie Cai 	printf("ret: %x\n",ret);
127178884ef4SEddie Cai 	return ret&0xFF;
127278884ef4SEddie Cai }
127378884ef4SEddie Cai 
127478884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
127578884ef4SEddie Cai {
127678884ef4SEddie Cai 	int i;
127778884ef4SEddie Cai 	for (i = 0; i < len; i++) {
127878884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
127978884ef4SEddie Cai 	}
128078884ef4SEddie Cai 	wide[len] = 0;
128178884ef4SEddie Cai }
128278884ef4SEddie Cai 
128378884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
128478884ef4SEddie Cai 	char* end;
128578884ef4SEddie Cai 	char* start;
128678884ef4SEddie Cai 	int len;
128778884ef4SEddie Cai 	if (!path || !dst)
128878884ef4SEddie Cai 		return;
128978884ef4SEddie Cai 	start = strrchr(path, '/');
129078884ef4SEddie Cai 	if (!start)
129178884ef4SEddie Cai 		start = path;
129278884ef4SEddie Cai 	else
129378884ef4SEddie Cai 		start++;
129478884ef4SEddie Cai 	end = strrchr(path, '.');
1295641cfa16SEddie Cai 	if (!end || (end < start))
129678884ef4SEddie Cai 		end = path + strlen(path);
129778884ef4SEddie Cai 	len = end - start;
129878884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
129978884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
130078884ef4SEddie Cai 	str2wide(start, dst, len);
130178884ef4SEddie Cai 
130278884ef4SEddie Cai 
130378884ef4SEddie Cai 		char name[MAX_NAME_LEN];
130478884ef4SEddie Cai 		memset(name, 0, sizeof(name));
130578884ef4SEddie Cai 		memcpy(name, start, len);
130678884ef4SEddie Cai 		printf("path: %s, name: %s\n", path, name);
130778884ef4SEddie Cai 
130878884ef4SEddie Cai }
130978884ef4SEddie Cai 
131078884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
131178884ef4SEddie Cai 	struct stat st;
131278884ef4SEddie Cai 	if(stat(path, &st) < 0)
131378884ef4SEddie Cai 		return false;
131478884ef4SEddie Cai 	*size = st.st_size;
131578884ef4SEddie Cai 	printf("path: %s, size: %d\n", path, *size);
131678884ef4SEddie Cai 	return true;
131778884ef4SEddie Cai }
131878884ef4SEddie Cai 
131978884ef4SEddie Cai static inline rk_time getTime(void) {
132078884ef4SEddie Cai 	rk_time rkTime;
132178884ef4SEddie Cai 
132278884ef4SEddie Cai 	struct tm *tm;
132378884ef4SEddie Cai 	time_t tt = time(NULL);
132478884ef4SEddie Cai 	tm = localtime(&tt);
132578884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
132678884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
132778884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
132878884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
132978884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
133078884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
133178884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
133278884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
133378884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
133478884ef4SEddie Cai 	return rkTime;
133578884ef4SEddie Cai }
133678884ef4SEddie Cai 
133778884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
133878884ef4SEddie Cai 	bool ret = false;
133978884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
134078884ef4SEddie Cai 	uint8_t* buf;
134178884ef4SEddie Cai 
134278884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
134378884ef4SEddie Cai 	if (!inFile)
134478884ef4SEddie Cai 		goto end;
134578884ef4SEddie Cai 
134678884ef4SEddie Cai 	if (!getFileSize(path, &size))
134778884ef4SEddie Cai 		goto end;
134878884ef4SEddie Cai 	if (fix) {
134978884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
135078884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
135178884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
135278884ef4SEddie Cai 		fixSize +=tmp;
135378884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
135478884ef4SEddie Cai 	} else {
135578884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
135678884ef4SEddie Cai 	}
135778884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
135878884ef4SEddie Cai 		goto end;
135978884ef4SEddie Cai 
136078884ef4SEddie Cai 	if (fix) {
136178884ef4SEddie Cai 
136278884ef4SEddie Cai 		buf = gBuf;
136378884ef4SEddie Cai 		size = fixSize;
136478884ef4SEddie Cai 		while(1) {
136578884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
136678884ef4SEddie Cai 			buf += SMALL_PACKET;
136778884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
136878884ef4SEddie Cai 				break;
136978884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
137078884ef4SEddie Cai 		}
137178884ef4SEddie Cai 	} else {
137278884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
137378884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
137478884ef4SEddie Cai 		size +=tmp;
137578884ef4SEddie Cai 		P_RC4(gBuf, size);
137678884ef4SEddie Cai 	}
137778884ef4SEddie Cai 
137878884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
137978884ef4SEddie Cai 		goto end;
138078884ef4SEddie Cai 	ret = true;
138178884ef4SEddie Cai end:
138278884ef4SEddie Cai 	if (inFile)
138378884ef4SEddie Cai 		fclose(inFile);
138478884ef4SEddie Cai 	if (!ret)
138532268622SAndreas Färber 		printf("writing entry (%s) failed\n", path);
138678884ef4SEddie Cai 	return ret;
138778884ef4SEddie Cai }
138878884ef4SEddie Cai 
138978884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
139078884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
139178884ef4SEddie Cai 	uint32_t size;
139278884ef4SEddie Cai 	rk_boot_entry entry;
139378884ef4SEddie Cai 
139432268622SAndreas Färber 	printf("writing: %s\n", path);
1395641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
139678884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
139778884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
139878884ef4SEddie Cai 	entry.type = type;
139978884ef4SEddie Cai 	entry.dataOffset = *offset;
140078884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
140132268622SAndreas Färber 		printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
140278884ef4SEddie Cai 		return false;
140378884ef4SEddie Cai 	}
140478884ef4SEddie Cai 	if (fix)
140578884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
140678884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
140778884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
140832268622SAndreas Färber 	printf("alignment size: %d\n", size);
140978884ef4SEddie Cai 	entry.dataSize = size;
141078884ef4SEddie Cai 	entry.dataDelay = delay;
141178884ef4SEddie Cai 	*offset += size;
141278884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
141378884ef4SEddie Cai 	return true;
141478884ef4SEddie Cai }
141578884ef4SEddie Cai 
141678884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
141778884ef4SEddie Cai 	char buffer[5];
141878884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
141978884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
142078884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
142178884ef4SEddie Cai }
142278884ef4SEddie Cai 
142378884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
142478884ef4SEddie Cai 	printf("chip: %s\n", chip);
142578884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
142678884ef4SEddie Cai 	if(!chip) {
142778884ef4SEddie Cai 		goto end;
142878884ef4SEddie Cai 	}
142978884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
143078884ef4SEddie Cai 		chipType = RK28_DEVICE;
143178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
143278884ef4SEddie Cai 		chipType = RK28_DEVICE;
143378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
143478884ef4SEddie Cai 		chipType = RK281X_DEVICE;
143578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
143678884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
143778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
143878884ef4SEddie Cai 		chipType = RK27_DEVICE;
143978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
144078884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
144178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
144278884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
144378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
144478884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
144578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
144678884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
144778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
144878884ef4SEddie Cai 		chipType = RK29_DEVICE;
144978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
145078884ef4SEddie Cai 		chipType = RK292X_DEVICE;
145178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
145278884ef4SEddie Cai 		chipType = RK30_DEVICE;
145378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
145478884ef4SEddie Cai 		chipType = RK30B_DEVICE;
145578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
145678884ef4SEddie Cai 		chipType = RK31_DEVICE;
145778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
145878884ef4SEddie Cai 		chipType = RK32_DEVICE;
145978884ef4SEddie Cai 	} else {
146078884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
146178884ef4SEddie Cai 	}
146278884ef4SEddie Cai 
146378884ef4SEddie Cai end:
146478884ef4SEddie Cai 	printf("type: 0x%x\n", chipType);
146578884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
146632268622SAndreas Färber 		printf("chip type not supported!\n");
146778884ef4SEddie Cai 	}
146878884ef4SEddie Cai 	return chipType;
146978884ef4SEddie Cai }
147078884ef4SEddie Cai 
147178884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
147278884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
147378884ef4SEddie Cai 	hdr->tag = TAG;
147478884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
147578884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
147678884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
147778884ef4SEddie Cai 	hdr->releaseTime = getTime();
147878884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
147978884ef4SEddie Cai 
148078884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
148178884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
148278884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
148378884ef4SEddie Cai 
148478884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
148578884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
148678884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
148778884ef4SEddie Cai 
148878884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
148978884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
149078884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
149178884ef4SEddie Cai #ifndef USE_P_RC4
149278884ef4SEddie Cai 	hdr->rc4Flag = 1;
149378884ef4SEddie Cai #endif
149478884ef4SEddie Cai }
149578884ef4SEddie Cai 
149678884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
149778884ef4SEddie Cai 	uint32_t size = 0;
149878884ef4SEddie Cai 	uint32_t crc = 0;
149978884ef4SEddie Cai 
150078884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
150178884ef4SEddie Cai 	getFileSize(path, &size);
150278884ef4SEddie Cai 	if (!file)
150378884ef4SEddie Cai 		goto end;
150478884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
150578884ef4SEddie Cai 		goto end;
150678884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
150778884ef4SEddie Cai 	printf("crc: 0x%08x\n", crc);
150878884ef4SEddie Cai end:
150978884ef4SEddie Cai 	if (file)
151078884ef4SEddie Cai 		fclose(file);
151178884ef4SEddie Cai 	return crc;
151278884ef4SEddie Cai }
151378884ef4SEddie Cai 
151478884ef4SEddie Cai bool mergeBoot(void) {
151578884ef4SEddie Cai 	uint32_t dataOffset;
151678884ef4SEddie Cai 	bool ret = false;
151778884ef4SEddie Cai 	int i;
151878884ef4SEddie Cai 	FILE* outFile;
151978884ef4SEddie Cai 	uint32_t crc;
152078884ef4SEddie Cai 	rk_boot_header hdr;
152178884ef4SEddie Cai 
152278884ef4SEddie Cai 	if (!initOpts())
152378884ef4SEddie Cai 		return false;
152478884ef4SEddie Cai 	{
152578884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
152678884ef4SEddie Cai 		char version[MAX_LINE_LEN];
152778884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
152878884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
152978884ef4SEddie Cai 			subfix[0] = '\0';
153078884ef4SEddie Cai 		}
153178884ef4SEddie Cai 		strcat(gOpts.outPath, version);
153278884ef4SEddie Cai 		printf("fix opt: %s\n", gOpts.outPath);
153378884ef4SEddie Cai 	}
153478884ef4SEddie Cai 
153578884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
153678884ef4SEddie Cai 	printOpts(stdout);
153778884ef4SEddie Cai 	printf("---------------\n\n");
153878884ef4SEddie Cai 
153978884ef4SEddie Cai 
154078884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
154178884ef4SEddie Cai 	if (!outFile) {
154232268622SAndreas Färber 		printf("Opening output file (%s) failed\n", gOpts.outPath);
154378884ef4SEddie Cai 		goto end;
154478884ef4SEddie Cai 	}
154578884ef4SEddie Cai 
154678884ef4SEddie Cai 	getBoothdr(&hdr);
154732268622SAndreas Färber 	printf("Writing header...\n");
154878884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
154978884ef4SEddie Cai 
155078884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
155178884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
155278884ef4SEddie Cai 		sizeof(rk_boot_entry);
155378884ef4SEddie Cai 
155432268622SAndreas Färber 	printf("Writing code 471 entry...\n");
155578884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
155678884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
155778884ef4SEddie Cai 					&dataOffset, NULL, false))
155878884ef4SEddie Cai 			goto end;
155978884ef4SEddie Cai 	}
156032268622SAndreas Färber 	printf("Writing code 472 entry...\n");
156178884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
156278884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
156378884ef4SEddie Cai 					&dataOffset, NULL, false))
156478884ef4SEddie Cai 			goto end;
156578884ef4SEddie Cai 	}
156632268622SAndreas Färber 	printf("Writing loader entry...\n");
156778884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
156878884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
156978884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
157078884ef4SEddie Cai 			goto end;
157178884ef4SEddie Cai 	}
157278884ef4SEddie Cai 
157332268622SAndreas Färber 	printf("Writing code 471...\n");
157478884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
157578884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
157678884ef4SEddie Cai 			goto end;
157778884ef4SEddie Cai 	}
157832268622SAndreas Färber 	printf("Writing code 472...\n");
157978884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
158078884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
158178884ef4SEddie Cai 			goto end;
158278884ef4SEddie Cai 	}
158332268622SAndreas Färber 	printf("Writing loader...\n");
158478884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
158578884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
158678884ef4SEddie Cai 			goto end;
158778884ef4SEddie Cai 	}
158878884ef4SEddie Cai 	fflush(outFile);
158978884ef4SEddie Cai 
159032268622SAndreas Färber 	printf("Writing crc...\n");
159178884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
159278884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
159378884ef4SEddie Cai 		goto end;
159432268622SAndreas Färber 	printf("Done.\n");
159578884ef4SEddie Cai 	ret = true;
159678884ef4SEddie Cai end:
159778884ef4SEddie Cai 	if (outFile)
159878884ef4SEddie Cai 		fclose(outFile);
159978884ef4SEddie Cai 	return ret;
160078884ef4SEddie Cai }
160178884ef4SEddie Cai 
160278884ef4SEddie Cai /************merge code end************/
160378884ef4SEddie Cai /************unpack code***************/
160478884ef4SEddie Cai 
160578884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
160678884ef4SEddie Cai {
160778884ef4SEddie Cai 	int i;
160878884ef4SEddie Cai 	for (i = 0; i < len; i++) {
160978884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
161078884ef4SEddie Cai 	}
161178884ef4SEddie Cai 	str[len] = 0;
161278884ef4SEddie Cai }
161378884ef4SEddie Cai 
161478884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
161578884ef4SEddie Cai 		FILE* inFile) {
161678884ef4SEddie Cai 	bool ret = false;
161778884ef4SEddie Cai 	int size, i;
161878884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
161978884ef4SEddie Cai 	if (!outFile)
162078884ef4SEddie Cai 		goto end;
162132268622SAndreas Färber 	printf("unpacking entry (%s)\n", name);
162278884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
162378884ef4SEddie Cai 	size = entry->dataSize;
162478884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
162578884ef4SEddie Cai 		goto end;
162678884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
162778884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
162878884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
162978884ef4SEddie Cai 		if (size % SMALL_PACKET)
163078884ef4SEddie Cai 		{
163178884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
163278884ef4SEddie Cai 		}
163378884ef4SEddie Cai 	} else {
163478884ef4SEddie Cai 		P_RC4(gBuf, size);
163578884ef4SEddie Cai 	}
163678884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
163778884ef4SEddie Cai 		goto end;
163878884ef4SEddie Cai 	ret = true;
163978884ef4SEddie Cai end:
164078884ef4SEddie Cai 	if (outFile)
164178884ef4SEddie Cai 		fclose(outFile);
164278884ef4SEddie Cai 	return ret;
164378884ef4SEddie Cai }
164478884ef4SEddie Cai 
164578884ef4SEddie Cai bool unpackBoot(char* path) {
164678884ef4SEddie Cai 	bool ret = false;
164778884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
164878884ef4SEddie Cai 	int entryNum, i;
164978884ef4SEddie Cai 	char name[MAX_NAME_LEN];
165078884ef4SEddie Cai 	rk_boot_entry* entrys;
165178884ef4SEddie Cai 	if (!inFile) {
165278884ef4SEddie Cai 		fprintf(stderr, "loader (%s) not found\n", path);
165378884ef4SEddie Cai 		goto end;
165478884ef4SEddie Cai 	}
165578884ef4SEddie Cai 
165678884ef4SEddie Cai 	rk_boot_header hdr;
165778884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
165832268622SAndreas Färber 		fprintf(stderr, "reading header failed\n");
165978884ef4SEddie Cai 		goto end;
166078884ef4SEddie Cai 	}
166178884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
166278884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
166378884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
166478884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
166532268622SAndreas Färber 		fprintf(stderr, "reading data failed\n");
166678884ef4SEddie Cai 		goto end;
166778884ef4SEddie Cai 	}
166878884ef4SEddie Cai 
166978884ef4SEddie Cai 	printf("entry num: %d\n", entryNum);
167078884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
167178884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
167278884ef4SEddie Cai 
167378884ef4SEddie Cai 		printf("entry: t=%d, name=%s, off=%d, size=%d\n",
167478884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
167578884ef4SEddie Cai 				entrys[i].dataSize);
167678884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
167732268622SAndreas Färber 			fprintf(stderr, "unpacking entry (%s) failed\n", name);
167878884ef4SEddie Cai 			goto end;
167978884ef4SEddie Cai 		}
168078884ef4SEddie Cai 	}
168178884ef4SEddie Cai 	printf("done\n");
168278884ef4SEddie Cai 	ret = true;
168378884ef4SEddie Cai end:
168478884ef4SEddie Cai 	if (inFile)
168578884ef4SEddie Cai 		fclose(inFile);
168678884ef4SEddie Cai 	return ret;
168778884ef4SEddie Cai }
168878884ef4SEddie Cai 
168976af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
169076af099aSliuyi {
169176af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
169276af099aSliuyi 		return false;
169376af099aSliuyi 	CRKImage *pImage = NULL;
169476af099aSliuyi 	CRKBoot *pBoot = NULL;
169576af099aSliuyi 	bool bRet, bSuccess = false;
169676af099aSliuyi 	int iRet;
169776af099aSliuyi 
169876af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
169976af099aSliuyi 	if (!bRet){
170076af099aSliuyi 		ERROR_COLOR_ATTR;
170132268622SAndreas Färber 		printf("Opening loader failed, exiting download boot!");
170276af099aSliuyi 		NORMAL_COLOR_ATTR;
170376af099aSliuyi 		printf("\r\n");
170476af099aSliuyi 		return bSuccess;
170576af099aSliuyi 	} else {
170676af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
170776af099aSliuyi 		CRKComm *pComm = NULL;
170876af099aSliuyi 		CRKDevice *pDevice = NULL;
170976af099aSliuyi 
171076af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
171176af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
171276af099aSliuyi 		if (!bRet) {
171376af099aSliuyi 			if (pImage)
171476af099aSliuyi 				delete pImage;
171576af099aSliuyi 			ERROR_COLOR_ATTR;
171676af099aSliuyi 			printf("Creating Comm Object failed!");
171776af099aSliuyi 			NORMAL_COLOR_ATTR;
171876af099aSliuyi 			printf("\r\n");
171976af099aSliuyi 			return bSuccess;
172076af099aSliuyi 		}
172176af099aSliuyi 
172276af099aSliuyi 		pDevice = new CRKDevice(dev);
172376af099aSliuyi 		if (!pDevice) {
172476af099aSliuyi 			if (pImage)
172576af099aSliuyi 				delete pImage;
172676af099aSliuyi 			if (pComm)
172776af099aSliuyi 				delete pComm;
172876af099aSliuyi 			ERROR_COLOR_ATTR;
172976af099aSliuyi 			printf("Creating device object failed!");
173076af099aSliuyi 			NORMAL_COLOR_ATTR;
173176af099aSliuyi 			printf("\r\n");
173276af099aSliuyi 			return bSuccess;
173376af099aSliuyi 		}
173476af099aSliuyi 
173576af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
173632268622SAndreas Färber 		printf("Downloading bootloader...\r\n");
173776af099aSliuyi 		iRet = pDevice->DownloadBoot();
173876af099aSliuyi 
173976af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
174076af099aSliuyi 		CURSOR_DEL_LINE;
174176af099aSliuyi 		if (iRet == 0) {
174276af099aSliuyi 			bSuccess = true;
174332268622SAndreas Färber 			printf("Downloading bootloader succeeded.\r\n");
174476af099aSliuyi 		}
174576af099aSliuyi 		else
174632268622SAndreas Färber 			printf("Downloading bootloader failed!\r\n");
174776af099aSliuyi 
174876af099aSliuyi 		if (pImage)
174976af099aSliuyi 			delete pImage;
175076af099aSliuyi 		if(pDevice)
175176af099aSliuyi 			delete pDevice;
175276af099aSliuyi 	}
175376af099aSliuyi 	return bSuccess;
175476af099aSliuyi }
1755c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1756c30d921cSKever Yang {
1757c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1758c30d921cSKever Yang 		return false;
1759c30d921cSKever Yang 	CRKImage *pImage = NULL;
1760c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1761c30d921cSKever Yang 	CRKComm *pComm = NULL;
1762c30d921cSKever Yang 	bool bRet, bSuccess = false;
1763c30d921cSKever Yang 	int iRet;
1764c30d921cSKever Yang 	char index;
1765c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1766c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1767c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1768c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1769c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1770c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1771c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1772c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1773c30d921cSKever Yang 	if (!bRet){
1774c30d921cSKever Yang 		ERROR_COLOR_ATTR;
177532268622SAndreas Färber 		printf("Opening loader failed, exiting upgrade loader!");
1776c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1777c30d921cSKever Yang 		printf("\r\n");
1778c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1779c30d921cSKever Yang 	} else {
1780c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1781c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1782c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1783c30d921cSKever Yang 		if (!bRet) {
1784c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1785c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1786c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1787c30d921cSKever Yang 			printf("\r\n");
1788c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1789c30d921cSKever Yang 		}
1790c30d921cSKever Yang 
179132268622SAndreas Färber 		printf("Upgrading loader...\r\n");
1792c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1793c30d921cSKever Yang 		if (index == -1) {
1794c30d921cSKever Yang 			if (g_pLogObject) {
179532268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1796c30d921cSKever Yang 			}
1797c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1798c30d921cSKever Yang 		}
1799c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1800c30d921cSKever Yang 		if (!bRet) {
1801c30d921cSKever Yang 			if (g_pLogObject) {
180232268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1803c30d921cSKever Yang 			}
1804c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1805c30d921cSKever Yang 		}
1806c30d921cSKever Yang 
1807c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1808c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1809c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1810c30d921cSKever Yang 			if (g_pLogObject) {
181132268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1812c30d921cSKever Yang 			}
1813c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1814c30d921cSKever Yang 		}
1815c30d921cSKever Yang 
1816c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1817c30d921cSKever Yang 		if (index == -1) {
1818c30d921cSKever Yang 			if (g_pLogObject) {
181932268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1820c30d921cSKever Yang 			}
1821c30d921cSKever Yang 			delete []loaderCodeBuffer;
1822c30d921cSKever Yang 			return -4;
1823c30d921cSKever Yang 		}
1824c30d921cSKever Yang 
1825c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1826c30d921cSKever Yang 		if (!bRet) {
1827c30d921cSKever Yang 			if (g_pLogObject) {
182832268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1829c30d921cSKever Yang 			}
1830c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1831c30d921cSKever Yang 		}
1832c30d921cSKever Yang 
1833c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1834c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1835c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1836c30d921cSKever Yang 			if (g_pLogObject) {
183732268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1838c30d921cSKever Yang 			}
1839c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1840c30d921cSKever Yang 		}
1841c30d921cSKever Yang 
1842c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1843c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1844c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1845c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1846c30d921cSKever Yang 		if (!pIDBData) {
1847c30d921cSKever Yang 			ERROR_COLOR_ATTR;
184832268622SAndreas Färber 			printf("Allocating memory failed!");
1849c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1850c30d921cSKever Yang 			printf("\r\n");
1851c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1852c30d921cSKever Yang 		}
1853c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1854b38fe5fcSliuyi 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
1855c30d921cSKever Yang 		if (iRet != 0) {
1856c30d921cSKever Yang 			ERROR_COLOR_ATTR;
185732268622SAndreas Färber 			printf("Making idblock failed!");
1858c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1859c30d921cSKever Yang 			printf("\r\n");
1860c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1861c30d921cSKever Yang 		}
1862c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
1863c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
1864c30d921cSKever Yang 		CURSOR_DEL_LINE;
1865c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
1866b38fe5fcSliuyi 			//pComm->Reset_Usb_Device();
1867c30d921cSKever Yang 			bSuccess = true;
186832268622SAndreas Färber 			printf("Upgrading loader succeeded.\r\n");
1869c30d921cSKever Yang 		} else {
187032268622SAndreas Färber 			printf("Upgrading loader failed!\r\n");
1871c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1872c30d921cSKever Yang 		}
1873c30d921cSKever Yang 	}
1874c30d921cSKever Yang Exit_UpgradeLoader:
1875c30d921cSKever Yang 	if (pImage)
1876c30d921cSKever Yang 		delete pImage;
1877c30d921cSKever Yang 	if (pComm)
1878c30d921cSKever Yang 		delete pComm;
1879c30d921cSKever Yang 	if (loaderCodeBuffer)
1880c30d921cSKever Yang 		delete []loaderCodeBuffer;
1881c30d921cSKever Yang 	if (loaderDataBuffer)
1882c30d921cSKever Yang 		delete []loaderDataBuffer;
1883c30d921cSKever Yang 	if (pIDBData)
1884c30d921cSKever Yang 		delete []pIDBData;
1885c30d921cSKever Yang 	return bSuccess;
1886c30d921cSKever Yang }
1887c30d921cSKever Yang 
188876af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
188976af099aSliuyi {
189076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
189176af099aSliuyi 		return false;
189276af099aSliuyi 	CRKImage *pImage = NULL;
189376af099aSliuyi 	bool bRet, bSuccess = false;
189476af099aSliuyi 	int iRet;
189576af099aSliuyi 	CRKScan *pScan = NULL;
189676af099aSliuyi 	pScan = new CRKScan();
189776af099aSliuyi 	pScan->SetVidPid();
189876af099aSliuyi 
189976af099aSliuyi 	CRKComm *pComm = NULL;
190076af099aSliuyi 	CRKDevice *pDevice = NULL;
190176af099aSliuyi 
190276af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
190376af099aSliuyi 	if (!bRet) {
190476af099aSliuyi 		if (pScan)
190576af099aSliuyi 			delete pScan;
190676af099aSliuyi 		ERROR_COLOR_ATTR;
190776af099aSliuyi 		printf("Creating Comm Object failed!");
190876af099aSliuyi 		NORMAL_COLOR_ATTR;
190976af099aSliuyi 		printf("\r\n");
191076af099aSliuyi 		return bSuccess;
191176af099aSliuyi 	}
191276af099aSliuyi 
191376af099aSliuyi 	pDevice = new CRKDevice(dev);
191476af099aSliuyi 	if (!pDevice) {
191576af099aSliuyi 		if (pComm)
191676af099aSliuyi 			delete pComm;
191776af099aSliuyi 		if (pScan)
191876af099aSliuyi 			delete pScan;
191976af099aSliuyi 		ERROR_COLOR_ATTR;
192076af099aSliuyi 		printf("Creating device object failed!");
192176af099aSliuyi 		NORMAL_COLOR_ATTR;
192276af099aSliuyi 		printf("\r\n");
192376af099aSliuyi 		return bSuccess;
192476af099aSliuyi 	}
192576af099aSliuyi 
192676af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
192776af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
192876af099aSliuyi 
192932268622SAndreas Färber 	printf("Starting to erase flash...\r\n");
1930*6502326dSliuyi 	bRet = pDevice->GetFlashInfo();
1931*6502326dSliuyi 	if (!bRet) {
1932*6502326dSliuyi 		if (pDevice)
1933*6502326dSliuyi 			delete pDevice;
1934*6502326dSliuyi 		if (pScan)
1935*6502326dSliuyi 			delete pScan;
1936*6502326dSliuyi 		ERROR_COLOR_ATTR;
1937*6502326dSliuyi 		printf("Getting flash info from device failed!");
1938*6502326dSliuyi 		NORMAL_COLOR_ATTR;
1939*6502326dSliuyi 		printf("\r\n");
1940*6502326dSliuyi 		return bSuccess;
1941*6502326dSliuyi 	}
194276af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
194376af099aSliuyi 	if (pDevice)
194476af099aSliuyi 		delete pDevice;
194576af099aSliuyi 
194676af099aSliuyi 	if (iRet == 0) {
194776af099aSliuyi 		if (pScan) {
194876af099aSliuyi 			pScan->SetVidPid();
194976af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
195076af099aSliuyi 			delete pScan;
195176af099aSliuyi 		}
195276af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
195376af099aSliuyi 		CURSOR_DEL_LINE;
195476af099aSliuyi 		bSuccess = true;
195532268622SAndreas Färber 		printf("Erasing flash complete.\r\n");
195676af099aSliuyi 	}
195776af099aSliuyi 
195876af099aSliuyi 	return bSuccess;
195976af099aSliuyi }
196076af099aSliuyi 
196176af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
196276af099aSliuyi {
196376af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
196476af099aSliuyi 		return false;
196576af099aSliuyi 	CRKUsbComm *pComm = NULL;
196676af099aSliuyi 	bool bRet, bSuccess = false;
196776af099aSliuyi 	int iRet;
196876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
196976af099aSliuyi 	if (bRet) {
197076af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
197176af099aSliuyi 		if (iRet != ERR_SUCCESS) {
197276af099aSliuyi 			if (g_pLogObject)
197376af099aSliuyi 				g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
197432268622SAndreas Färber 			printf("Test Device failed!\r\n");
197576af099aSliuyi 		} else {
197676af099aSliuyi 			bSuccess = true;
197776af099aSliuyi 			printf("Test Device OK.\r\n");
197876af099aSliuyi 		}
197976af099aSliuyi 	} else {
198032268622SAndreas Färber 		printf("Test Device quit, creating comm object failed!\r\n");
198176af099aSliuyi 	}
198276af099aSliuyi 	if (pComm) {
198376af099aSliuyi 		delete pComm;
198476af099aSliuyi 		pComm = NULL;
198576af099aSliuyi 	}
198676af099aSliuyi 	return bSuccess;
198776af099aSliuyi }
198876af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
198976af099aSliuyi {
199076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
199176af099aSliuyi 		return false;
199276af099aSliuyi 	CRKUsbComm *pComm = NULL;
199376af099aSliuyi 	bool bRet, bSuccess = false;
199476af099aSliuyi 	int iRet;
199576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
199676af099aSliuyi 	if (bRet) {
199776af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
199876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
199976af099aSliuyi 			if (g_pLogObject)
200076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
200132268622SAndreas Färber 			printf("Reset Device failed!\r\n");
200276af099aSliuyi 		} else {
200376af099aSliuyi 			bSuccess = true;
200476af099aSliuyi 			printf("Reset Device OK.\r\n");
200576af099aSliuyi 		}
200676af099aSliuyi 	} else {
200732268622SAndreas Färber 		printf("Reset Device quit, creating comm object failed!\r\n");
200876af099aSliuyi 	}
200976af099aSliuyi 	if (pComm) {
201076af099aSliuyi 		delete pComm;
201176af099aSliuyi 		pComm = NULL;
201276af099aSliuyi 	}
201376af099aSliuyi 	return bSuccess;
201476af099aSliuyi }
201576af099aSliuyi 
201676af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
201776af099aSliuyi {
201876af099aSliuyi 	CRKUsbComm *pComm = NULL;
201976af099aSliuyi 	bool bRet, bSuccess = false;
202076af099aSliuyi 	int iRet;
202176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
202276af099aSliuyi 		return bSuccess;
202376af099aSliuyi 
202476af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
202576af099aSliuyi 	if (bRet) {
202676af099aSliuyi 		BYTE flashID[5];
202776af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
202876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
202976af099aSliuyi 			if (g_pLogObject)
203076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
203132268622SAndreas Färber 			printf("Reading flash ID failed!\r\n");
203276af099aSliuyi 		} else {
203376af099aSliuyi 			printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
203476af099aSliuyi 			bSuccess = true;
203576af099aSliuyi 		}
203676af099aSliuyi 	} else {
203732268622SAndreas Färber 		printf("Read Flash ID quit, creating comm object failed!\r\n");
203876af099aSliuyi 	}
203976af099aSliuyi 	if (pComm) {
204076af099aSliuyi 		delete pComm;
204176af099aSliuyi 		pComm = NULL;
204276af099aSliuyi 	}
204376af099aSliuyi 	return bSuccess;
204476af099aSliuyi }
204576af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
204676af099aSliuyi {
204776af099aSliuyi 	CRKUsbComm *pComm = NULL;
204876af099aSliuyi 	bool bRet, bSuccess = false;
204976af099aSliuyi 	int iRet;
205076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
205176af099aSliuyi 		return bSuccess;
205276af099aSliuyi 
205376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
205476af099aSliuyi 	if (bRet) {
205576af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
205676af099aSliuyi 		UINT uiRead;
205776af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
205876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
205976af099aSliuyi 			if (g_pLogObject)
206076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
206132268622SAndreas Färber 			printf("Read Flash Info failed!\r\n");
206276af099aSliuyi 		} else {
206376af099aSliuyi 			printf("Flash Info:\r\n");
206476af099aSliuyi 			if (info.bManufCode <= 7) {
206576af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
206676af099aSliuyi 			}
206776af099aSliuyi 			else
206876af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
206976af099aSliuyi 
207076af099aSliuyi 			printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
207176af099aSliuyi 			printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
207276af099aSliuyi 			printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
207376af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
207476af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
207576af099aSliuyi 			printf("\tFlash CS: ");
207676af099aSliuyi 			for(int i = 0; i < 8; i++) {
207776af099aSliuyi 				if( info.bFlashCS & (1 << i) )
207876af099aSliuyi 					printf("Flash<%d> ", i);
207976af099aSliuyi 			}
208076af099aSliuyi 			printf("\r\n");
208176af099aSliuyi 			bSuccess = true;
208276af099aSliuyi 		}
208376af099aSliuyi 	}else {
208432268622SAndreas Färber 		printf("Read Flash Info quit, creating comm object failed!\r\n");
208576af099aSliuyi 	}
208676af099aSliuyi 	if (pComm) {
208776af099aSliuyi 		delete pComm;
208876af099aSliuyi 		pComm = NULL;
208976af099aSliuyi 	}
209076af099aSliuyi 	return bSuccess;
209176af099aSliuyi }
209276af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
209376af099aSliuyi {
209476af099aSliuyi 	CRKUsbComm *pComm = NULL;
209576af099aSliuyi 	bool bRet, bSuccess = false;
209676af099aSliuyi 	int iRet;
209776af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
209876af099aSliuyi 		return bSuccess;
209976af099aSliuyi 
210076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
210176af099aSliuyi 	if (bRet) {
210276af099aSliuyi 		BYTE chipInfo[16];
210376af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
210476af099aSliuyi 		if (iRet != ERR_SUCCESS) {
210576af099aSliuyi 			if (g_pLogObject)
210676af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
210732268622SAndreas Färber 			printf("Read Chip Info failed!\r\n");
210876af099aSliuyi 		} else {
210976af099aSliuyi 			string strChipInfo;
211076af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
211176af099aSliuyi 			printf("Chip Info: %s\r\n", strChipInfo.c_str());
211276af099aSliuyi 			bSuccess = true;
211376af099aSliuyi 		}
211476af099aSliuyi 	} else {
211532268622SAndreas Färber 		printf("Read Chip Info quit, creating comm object failed!\r\n");
211676af099aSliuyi 	}
211776af099aSliuyi 	if (pComm) {
211876af099aSliuyi 		delete pComm;
211976af099aSliuyi 		pComm = NULL;
212076af099aSliuyi 	}
212176af099aSliuyi 	return bSuccess;
212276af099aSliuyi }
21236ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt)
21246ae612beSliuyi {
21256ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
21266ae612beSliuyi 		return false;
21276ae612beSliuyi 	gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE);
21286ae612beSliuyi 	CRKUsbComm *pComm = NULL;
21296ae612beSliuyi 	bool bRet, bSuccess = false;
21306ae612beSliuyi 	int iRet;
21316ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
21326ae612beSliuyi 	if (bRet) {
21336ae612beSliuyi 		iRet = pComm->RKU_ReadLBA( 0, 34, pGpt);
21346ae612beSliuyi 		if(ERR_SUCCESS == iRet) {
21356ae612beSliuyi 			if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
21366ae612beSliuyi 				if (g_pLogObject)
21376ae612beSliuyi 					g_pLogObject->Record("Error: invalid gpt signature");
21386ae612beSliuyi 				printf("Invalid GPT signature!\r\n");
21396ae612beSliuyi 				goto Exit_ReadGPT;
21406ae612beSliuyi 			}
21416ae612beSliuyi 
21426ae612beSliuyi 		} else {
21436ae612beSliuyi 			if (g_pLogObject)
21446ae612beSliuyi 					g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
21456ae612beSliuyi 			printf("Read GPT failed!\r\n");
21466ae612beSliuyi 			goto Exit_ReadGPT;
21476ae612beSliuyi 		}
21486ae612beSliuyi 		bSuccess = true;
21496ae612beSliuyi 	}
21506ae612beSliuyi Exit_ReadGPT:
21516ae612beSliuyi 	if (pComm) {
21526ae612beSliuyi 		delete pComm;
21536ae612beSliuyi 		pComm = NULL;
21546ae612beSliuyi 	}
21556ae612beSliuyi 	return bSuccess;
21566ae612beSliuyi }
215776af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
215876af099aSliuyi {
215976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
216076af099aSliuyi 		return false;
216176af099aSliuyi 	CRKUsbComm *pComm = NULL;
216276af099aSliuyi 	FILE *file = NULL;
216376af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
216476af099aSliuyi 	int iRet;
216576af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
216676af099aSliuyi 	int nSectorSize = 512;
216776af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
216876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
216976af099aSliuyi 	if (bRet) {
217076af099aSliuyi 		if(szFile) {
217176af099aSliuyi 			file = fopen(szFile, "wb+");
217276af099aSliuyi 			if( !file ) {
217376af099aSliuyi 				printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
217476af099aSliuyi 				goto Exit_ReadLBA;
217576af099aSliuyi 			}
217676af099aSliuyi 		}
217776af099aSliuyi 
217876af099aSliuyi 		while(uiLen > 0) {
217976af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
218076af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
218176af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
218276af099aSliuyi 			if(ERR_SUCCESS == iRet) {
218376af099aSliuyi 				uiLen -= iRead;
218476af099aSliuyi 				iTotalRead += iRead;
218576af099aSliuyi 
218676af099aSliuyi 				if(szFile) {
218776af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
218876af099aSliuyi 					if (bFirst){
218976af099aSliuyi 						if (iTotalRead >= 1024)
219032268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
219176af099aSliuyi 						else
219232268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
219376af099aSliuyi 						bFirst = false;
219476af099aSliuyi 					} else {
219576af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
219676af099aSliuyi 						CURSOR_DEL_LINE;
219776af099aSliuyi 						if (iTotalRead >= 1024)
219832268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
219976af099aSliuyi 						else
220032268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
220176af099aSliuyi 					}
220276af099aSliuyi 				}
220376af099aSliuyi 				else
220476af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
220576af099aSliuyi 			} else {
220676af099aSliuyi 				if (g_pLogObject)
220776af099aSliuyi 					g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
220876af099aSliuyi 
220976af099aSliuyi 				printf("Read LBA failed!\r\n");
221076af099aSliuyi 				goto Exit_ReadLBA;
221176af099aSliuyi 			}
221276af099aSliuyi 		}
221376af099aSliuyi 		bSuccess = true;
221476af099aSliuyi 	} else {
221532268622SAndreas Färber 		printf("Read LBA quit, creating comm object failed!\r\n");
221676af099aSliuyi 	}
221776af099aSliuyi Exit_ReadLBA:
221876af099aSliuyi 	if (pComm) {
221976af099aSliuyi 		delete pComm;
222076af099aSliuyi 		pComm = NULL;
222176af099aSliuyi 	}
222276af099aSliuyi 	if (file)
222376af099aSliuyi 		fclose(file);
222476af099aSliuyi 	return bSuccess;
222576af099aSliuyi }
22266ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize)
22276ae612beSliuyi {
22286ae612beSliuyi 	UINT uiErase=2048*64;
22296ae612beSliuyi 	bool bSuccess = true;
22306ae612beSliuyi 	int iRet;
22316ae612beSliuyi 	while (uiSize)
22326ae612beSliuyi 	{
22336ae612beSliuyi 		if (uiSize>=uiErase)
22346ae612beSliuyi 		{
22356ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiErase);
22366ae612beSliuyi 			uiSize -= uiErase;
22376ae612beSliuyi 			uiOffset += uiErase;
22386ae612beSliuyi 		}
22396ae612beSliuyi 		else
22406ae612beSliuyi 		{
22416ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiSize);
22426ae612beSliuyi 			uiSize = 0;
22436ae612beSliuyi 			uiOffset += uiSize;
22446ae612beSliuyi 		}
22456ae612beSliuyi 		if (iRet!=ERR_SUCCESS)
22466ae612beSliuyi 		{
22476ae612beSliuyi 			if (g_pLogObject)
22486ae612beSliuyi 			{
22496ae612beSliuyi 				g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet);
22506ae612beSliuyi 			}
22516ae612beSliuyi 			bSuccess = false;
22526ae612beSliuyi 			break;
22536ae612beSliuyi 		}
22546ae612beSliuyi 	}
22556ae612beSliuyi 	return bSuccess;
22566ae612beSliuyi 
22576ae612beSliuyi }
22586ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk)
22596ae612beSliuyi {
22606ae612beSliuyi 	UINT uiRead;
22616ae612beSliuyi 	uiRead = fread(&chunk, 1, sizeof(chunk_header), file);
22626ae612beSliuyi 	if (uiRead != sizeof(chunk_header)) {
22636ae612beSliuyi 		if (g_pLogObject)
22646ae612beSliuyi 		{
22656ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno);
22666ae612beSliuyi 		}
22676ae612beSliuyi 		return false;
22686ae612beSliuyi 	}
22696ae612beSliuyi 	return true;
22706ae612beSliuyi }
22716ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize)
22726ae612beSliuyi {
22736ae612beSliuyi 	UINT uiRead;
22746ae612beSliuyi 	uiRead = fread(pBuf, 1, dwSize, file);
22756ae612beSliuyi 	if (uiRead!=dwSize)
22766ae612beSliuyi 	{
22776ae612beSliuyi 		if (g_pLogObject)
22786ae612beSliuyi 		{
22796ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno);
22806ae612beSliuyi 		}
22816ae612beSliuyi 		return false;
22826ae612beSliuyi 	}
22836ae612beSliuyi 	return true;
22846ae612beSliuyi }
22856ae612beSliuyi 
22866ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile)
22876ae612beSliuyi {
22886ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
22896ae612beSliuyi 		return false;
22906ae612beSliuyi 	CRKUsbComm *pComm = NULL;
22916ae612beSliuyi 	FILE *file = NULL;
22926ae612beSliuyi 	bool bRet, bSuccess = false, bFirst = true;
22936ae612beSliuyi 	int iRet;
22946ae612beSliuyi 	u64 iTotalWrite = 0, iFileSize = 0;
22956ae612beSliuyi 	UINT iRead = 0, uiTransferSec, curChunk, i;
22966ae612beSliuyi 	UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc;
22976ae612beSliuyi 	BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA];
22986ae612beSliuyi 	sparse_header header;
22996ae612beSliuyi 	chunk_header  chunk;
23006ae612beSliuyi 	dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE;
23016ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
23026ae612beSliuyi 	if (bRet) {
23036ae612beSliuyi 		bRet = erase_partition(pComm, uiBegin, uiSize);
23046ae612beSliuyi 		if (!bRet) {
23056ae612beSliuyi 			printf("%s failed, erase partition error\r\n", __func__);
23066ae612beSliuyi 			goto Exit_WriteSparseLBA;
23076ae612beSliuyi 		}
23086ae612beSliuyi 		file = fopen(szFile, "rb");
23096ae612beSliuyi 		if( !file ) {
23106ae612beSliuyi 			printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile);
23116ae612beSliuyi 			goto Exit_WriteSparseLBA;
23126ae612beSliuyi 		}
23136ae612beSliuyi 		fseeko(file, 0, SEEK_SET);
23146ae612beSliuyi 		iRead = fread(&header, 1, sizeof(header), file);
23156ae612beSliuyi 		if (iRead != sizeof(sparse_header))
23166ae612beSliuyi 		{
23176ae612beSliuyi 			if (g_pLogObject)
23186ae612beSliuyi 			{
23196ae612beSliuyi 				g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno);
23206ae612beSliuyi 			}
23216ae612beSliuyi 			goto Exit_WriteSparseLBA;
23226ae612beSliuyi 		}
23236ae612beSliuyi 		iFileSize = header.blk_sz * (u64)header.total_blks;
23246ae612beSliuyi 		iTotalWrite = 0;
23256ae612beSliuyi 		curChunk = 0;
23266ae612beSliuyi 
23276ae612beSliuyi 		while(curChunk < header.total_chunks)
23286ae612beSliuyi 		{
23296ae612beSliuyi 			if (!EatSparseChunk(file, chunk)) {
23306ae612beSliuyi 				goto Exit_WriteSparseLBA;
23316ae612beSliuyi 			}
23326ae612beSliuyi 			curChunk++;
23336ae612beSliuyi 			switch (chunk.chunk_type) {
23346ae612beSliuyi 			case CHUNK_TYPE_RAW:
23356ae612beSliuyi 				dwChunkDataSize = chunk.total_sz - sizeof(chunk_header);
23366ae612beSliuyi 				while (dwChunkDataSize) {
23376ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
23386ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
23396ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
23406ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
23416ae612beSliuyi 					} else {
23426ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
23436ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
23446ae612beSliuyi 					}
23456ae612beSliuyi 					if (!EatSparseData(file, pBuf, dwTransferBytes)) {
23466ae612beSliuyi 						goto Exit_WriteSparseLBA;
23476ae612beSliuyi 					}
23486ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
23496ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
23506ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
23516ae612beSliuyi 						iTotalWrite += dwTransferBytes;
23526ae612beSliuyi 						uiBegin += uiTransferSec;
23536ae612beSliuyi 					} else {
23546ae612beSliuyi 						if (g_pLogObject) {
23556ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)",  __func__, iTotalWrite, iRet);
23566ae612beSliuyi 						}
23576ae612beSliuyi 						goto Exit_WriteSparseLBA;
23586ae612beSliuyi 					}
23596ae612beSliuyi 					if (bFirst) {
23606ae612beSliuyi 						if (iTotalWrite >= 1024)
23616ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
23626ae612beSliuyi 						else
23636ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
23646ae612beSliuyi 						bFirst = false;
23656ae612beSliuyi 					} else {
23666ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
23676ae612beSliuyi 						CURSOR_DEL_LINE;
23686ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
23696ae612beSliuyi 					}
23706ae612beSliuyi 				}
23716ae612beSliuyi 				break;
23726ae612beSliuyi 			case CHUNK_TYPE_FILL:
23736ae612beSliuyi 				dwChunkDataSize = chunk.chunk_sz * header.blk_sz;
23746ae612beSliuyi 				if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) {
23756ae612beSliuyi 					goto Exit_WriteSparseLBA;
23766ae612beSliuyi 				}
23776ae612beSliuyi 				while (dwChunkDataSize) {
23786ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
23796ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
23806ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
23816ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
23826ae612beSliuyi 					} else {
23836ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
23846ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
23856ae612beSliuyi 					}
23866ae612beSliuyi 					for (i = 0; i < dwTransferBytes / 4; i++) {
23876ae612beSliuyi 						*(DWORD *)(pBuf + i * 4) = dwFillByte;
23886ae612beSliuyi 					}
23896ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
23906ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
23916ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
23926ae612beSliuyi 						iTotalWrite += dwTransferBytes;
23936ae612beSliuyi 						uiBegin += uiTransferSec;
23946ae612beSliuyi 					} else {
23956ae612beSliuyi 						if (g_pLogObject) {
23966ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet);
23976ae612beSliuyi 						}
23986ae612beSliuyi 						goto Exit_WriteSparseLBA;
23996ae612beSliuyi 					}
24006ae612beSliuyi 					if (bFirst) {
24016ae612beSliuyi 						if (iTotalWrite >= 1024)
24026ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
24036ae612beSliuyi 						else
24046ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
24056ae612beSliuyi 						bFirst = false;
24066ae612beSliuyi 					} else {
24076ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
24086ae612beSliuyi 						CURSOR_DEL_LINE;
24096ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
24106ae612beSliuyi 					}
24116ae612beSliuyi 				}
24126ae612beSliuyi 				break;
24136ae612beSliuyi 			case CHUNK_TYPE_DONT_CARE:
24146ae612beSliuyi 				dwChunkDataSize = chunk.chunk_sz * header.blk_sz;
24156ae612beSliuyi 				iTotalWrite += dwChunkDataSize;
24166ae612beSliuyi 				uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1));
24176ae612beSliuyi 				uiBegin += uiTransferSec;
24186ae612beSliuyi 				if (bFirst) {
24196ae612beSliuyi 					if (iTotalWrite >= 1024)
24206ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
24216ae612beSliuyi 					else
24226ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
24236ae612beSliuyi 					bFirst = false;
24246ae612beSliuyi 				} else {
24256ae612beSliuyi 					CURSOR_MOVEUP_LINE(1);
24266ae612beSliuyi 					CURSOR_DEL_LINE;
24276ae612beSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
24286ae612beSliuyi 				}
24296ae612beSliuyi 				break;
24306ae612beSliuyi 			case CHUNK_TYPE_CRC32:
24316ae612beSliuyi 				EatSparseData(file,(PBYTE)&dwCrc,4);
24326ae612beSliuyi 				break;
24336ae612beSliuyi 			}
24346ae612beSliuyi 		}
24356ae612beSliuyi 		bSuccess = true;
24366ae612beSliuyi 	} else {
24376ae612beSliuyi 		printf("Write LBA quit, creating comm object failed!\r\n");
24386ae612beSliuyi 	}
24396ae612beSliuyi Exit_WriteSparseLBA:
24406ae612beSliuyi 	if (pComm) {
24416ae612beSliuyi 		delete pComm;
24426ae612beSliuyi 		pComm = NULL;
24436ae612beSliuyi 	}
24446ae612beSliuyi 	if (file)
24456ae612beSliuyi 		fclose(file);
24466ae612beSliuyi 	return bSuccess;
24476ae612beSliuyi 
24486ae612beSliuyi }
24496ae612beSliuyi 
245076af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
245176af099aSliuyi {
245276af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
245376af099aSliuyi 		return false;
245476af099aSliuyi 	CRKUsbComm *pComm = NULL;
245576af099aSliuyi 	FILE *file = NULL;
245676af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
245776af099aSliuyi 	int iRet;
245876af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
245976af099aSliuyi 	UINT iWrite = 0, iRead = 0;
246076af099aSliuyi 	UINT uiLen;
246176af099aSliuyi 	int nSectorSize = 512;
246276af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
246376af099aSliuyi 
246476af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
246576af099aSliuyi 	if (bRet) {
246676af099aSliuyi 		file = fopen(szFile, "rb");
246776af099aSliuyi 		if( !file ) {
246876af099aSliuyi 			printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
246976af099aSliuyi 			goto Exit_WriteLBA;
247076af099aSliuyi 		}
247176af099aSliuyi 
247276af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
247376af099aSliuyi 		iFileSize = ftello(file);
247476af099aSliuyi 		fseeko(file, 0, SEEK_SET);
247576af099aSliuyi 		while(iTotalWrite < iFileSize) {
247676af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
247776af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
247876af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
247976af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
248076af099aSliuyi 			if(ERR_SUCCESS == iRet) {
248176af099aSliuyi 				uiBegin += uiLen;
248276af099aSliuyi 				iTotalWrite += iWrite;
248376af099aSliuyi 				if (bFirst) {
248476af099aSliuyi 					if (iTotalWrite >= 1024)
248576af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
248676af099aSliuyi 					else
248732268622SAndreas Färber 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
248876af099aSliuyi 					bFirst = false;
248976af099aSliuyi 				} else {
249076af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
249176af099aSliuyi 					CURSOR_DEL_LINE;
249276af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
249376af099aSliuyi 				}
249476af099aSliuyi 			} else {
249576af099aSliuyi 				if (g_pLogObject)
249676af099aSliuyi 					g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
249776af099aSliuyi 
249876af099aSliuyi 				printf("Write LBA failed!\r\n");
249976af099aSliuyi 				goto Exit_WriteLBA;
250076af099aSliuyi 			}
250176af099aSliuyi 		}
250276af099aSliuyi 		bSuccess = true;
250376af099aSliuyi 	} else {
250432268622SAndreas Färber 		printf("Write LBA quit, creating comm object failed!\r\n");
250576af099aSliuyi 	}
250676af099aSliuyi Exit_WriteLBA:
250776af099aSliuyi 	if (pComm) {
250876af099aSliuyi 		delete pComm;
250976af099aSliuyi 		pComm = NULL;
251076af099aSliuyi 	}
251176af099aSliuyi 	if (file)
251276af099aSliuyi 		fclose(file);
251376af099aSliuyi 	return bSuccess;
251476af099aSliuyi }
251576af099aSliuyi 
251676af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
251776af099aSliuyi {
251876af099aSliuyi 	string strItem;
251976af099aSliuyi 	char szItem[100];
252076af099aSliuyi 	char *pos = NULL, *pStart;
252176af099aSliuyi 	pStart = pszItems;
252276af099aSliuyi 	pos = strchr(pStart, ',');
252376af099aSliuyi 	while(pos != NULL) {
252476af099aSliuyi 		memset(szItem, 0, 100);
252576af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
252676af099aSliuyi 		strItem = szItem;
252776af099aSliuyi 		vecItems.push_back(strItem);
252876af099aSliuyi 		pStart = pos + 1;
252976af099aSliuyi 		if (*pStart == 0)
253076af099aSliuyi 			break;
253176af099aSliuyi 		pos = strchr(pStart, ',');
253276af099aSliuyi 	}
253376af099aSliuyi 	if (strlen(pStart) > 0) {
253476af099aSliuyi 		memset(szItem, 0, 100);
253576af099aSliuyi 		strncpy(szItem, pStart, strlen(pStart));
253676af099aSliuyi 		strItem = szItem;
253776af099aSliuyi 		vecItems.push_back(strItem);
253876af099aSliuyi 	}
253976af099aSliuyi }
2540c30d921cSKever Yang 
2541d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
2542d71e8c20SEddie Cai {
2543d71e8c20SEddie Cai 	FILE *file = NULL;
2544d71e8c20SEddie Cai 	int len;
2545d71e8c20SEddie Cai 
2546d71e8c20SEddie Cai 	if(!tag || !spl)
2547d71e8c20SEddie Cai 		return;
2548d71e8c20SEddie Cai 	len = strlen(tag);
2549d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
2550d71e8c20SEddie Cai 	file = fopen(spl, "rb");
2551d71e8c20SEddie Cai 	if( !file ){
2552d71e8c20SEddie Cai 		return;
2553d71e8c20SEddie Cai 	}
2554d71e8c20SEddie Cai 	int iFileSize;
2555d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
2556d71e8c20SEddie Cai 	iFileSize = ftell(file);
2557d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
2558d71e8c20SEddie Cai 	char *Buf = NULL;
2559d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
2560d71e8c20SEddie Cai 	if (!Buf){
2561d71e8c20SEddie Cai 		fclose(file);
2562d71e8c20SEddie Cai 		return;
2563d71e8c20SEddie Cai 	}
2564d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
2565d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
2566d71e8c20SEddie Cai 	int iRead;
2567d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
2568d71e8c20SEddie Cai 	if (iRead != iFileSize){
2569d71e8c20SEddie Cai 		fclose(file);
2570d71e8c20SEddie Cai 		delete []Buf;
2571d71e8c20SEddie Cai 		return;
2572d71e8c20SEddie Cai 	}
2573d71e8c20SEddie Cai 	fclose(file);
2574d71e8c20SEddie Cai 
2575d71e8c20SEddie Cai 	len = strlen(spl);
257632268622SAndreas Färber 	char *taggedspl = new char[len + 5];
257732268622SAndreas Färber 	strcpy(taggedspl, spl);
257832268622SAndreas Färber 	strcpy(taggedspl + len, ".tag");
257932268622SAndreas Färber 	taggedspl[len+4] = 0;
258032268622SAndreas Färber 	printf("Writing tagged spl to %s\n", taggedspl);
2581d71e8c20SEddie Cai 
258232268622SAndreas Färber 	file = fopen(taggedspl, "wb");
2583d71e8c20SEddie Cai 	if( !file ){
258432268622SAndreas Färber 		delete []taggedspl;
2585d71e8c20SEddie Cai 		delete []Buf;
2586d71e8c20SEddie Cai 		return;
2587d71e8c20SEddie Cai 	}
2588d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
2589d71e8c20SEddie Cai 	fclose(file);
259032268622SAndreas Färber 	delete []taggedspl;
2591d71e8c20SEddie Cai 	delete []Buf;
2592d71e8c20SEddie Cai 	printf("done\n");
2593d71e8c20SEddie Cai 	return;
2594d71e8c20SEddie Cai }
2595d71e8c20SEddie Cai 
259676af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
259776af099aSliuyi {
259876af099aSliuyi 	string strCmd;
259976af099aSliuyi 	strCmd = argv[1];
260076af099aSliuyi 	ssize_t cnt;
260176af099aSliuyi 	bool bRet,bSuccess = false;
26028df2d64aSEddie Cai 	char *s;
26038df2d64aSEddie Cai 	int i, ret;
260476af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
26056ae612beSliuyi 	u8 master_gpt[34 * SECTOR_SIZE];
26066ae612beSliuyi 	u64 lba, lba_end;
260776af099aSliuyi 
260876af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
26098df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
26108df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
26118df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
261278884ef4SEddie Cai 
26138df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
261476af099aSliuyi 		usage();
261576af099aSliuyi 		return true;
26168df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
2617c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
261876af099aSliuyi 		return true;
261978884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
262078884ef4SEddie Cai 		mergeBoot();
262178884ef4SEddie Cai 
262278884ef4SEddie Cai 		return true;
262378884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
262478884ef4SEddie Cai 		string strLoader = argv[2];
262578884ef4SEddie Cai 
262678884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
262778884ef4SEddie Cai 		return true;
2628d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
2629d71e8c20SEddie Cai 		if (argc == 4) {
2630d71e8c20SEddie Cai 			string tag = argv[2];
2631d71e8c20SEddie Cai 			string spl = argv[3];
2632d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
2633d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
2634d71e8c20SEddie Cai 			return true;
2635d71e8c20SEddie Cai 		}
2636d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
2637d71e8c20SEddie Cai 		usage();
263876af099aSliuyi 	}
263976af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
264076af099aSliuyi 	if (cnt < 1) {
264176af099aSliuyi 		ERROR_COLOR_ATTR;
264232268622SAndreas Färber 		printf("Did not find any rockusb device, please plug device in!");
264376af099aSliuyi 		NORMAL_COLOR_ATTR;
264476af099aSliuyi 		printf("\r\n");
264576af099aSliuyi 		return bSuccess;
264676af099aSliuyi 	} else if (cnt > 1) {
264776af099aSliuyi 		ERROR_COLOR_ATTR;
264832268622SAndreas Färber 		printf("Found too many rockusb devices, please plug devices out!");
264976af099aSliuyi 		NORMAL_COLOR_ATTR;
265076af099aSliuyi 		printf("\r\n");
265176af099aSliuyi 		return bSuccess;
265276af099aSliuyi 	}
265376af099aSliuyi 
265476af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
265576af099aSliuyi 	if (!bRet) {
265676af099aSliuyi 		ERROR_COLOR_ATTR;
265732268622SAndreas Färber 		printf("Getting information about rockusb device failed!");
265876af099aSliuyi 		NORMAL_COLOR_ATTR;
265976af099aSliuyi 		printf("\r\n");
266076af099aSliuyi 		return bSuccess;
266176af099aSliuyi 	}
266276af099aSliuyi 
266376af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
266476af099aSliuyi 		if ((argc != 2) && (argc != 3))
266576af099aSliuyi 			printf("Parameter of [RD] command is invalid, please check help!\r\n");
266676af099aSliuyi 		else {
266776af099aSliuyi 			if (argc == 2)
266876af099aSliuyi 				bSuccess = reset_device(dev);
266976af099aSliuyi 			else {
267076af099aSliuyi 				UINT uiSubCode;
267176af099aSliuyi 				char *pszEnd;
267276af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
267376af099aSliuyi 				if (*pszEnd)
267476af099aSliuyi 					printf("Subcode is invalid, please check!\r\n");
267576af099aSliuyi 				else {
267676af099aSliuyi 					if (uiSubCode <= 5)
267776af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
267876af099aSliuyi 					else
267976af099aSliuyi 						printf("Subcode is invalid, please check!\r\n");
268076af099aSliuyi 				}
268176af099aSliuyi 			}
268276af099aSliuyi 		}
268376af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
268476af099aSliuyi 		bSuccess = test_device(dev);
268576af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
268676af099aSliuyi 		bSuccess = read_flash_id(dev);
268776af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
268876af099aSliuyi 		bSuccess = read_flash_info(dev);
268976af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
269076af099aSliuyi 		bSuccess = read_chip_info(dev);
269176af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
269276af099aSliuyi 		if (argc > 2) {
269376af099aSliuyi 			string strLoader;
269476af099aSliuyi 			strLoader = argv[2];
269576af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
269676af099aSliuyi 		} else if (argc == 2) {
2697c29e5f0fSliuyi 			ret = find_config_item(g_ConfigItemVec, "loader");
269876af099aSliuyi 			if (ret == -1)
269932268622SAndreas Färber 				printf("Did not find loader item in config!\r\n");
270076af099aSliuyi 			else
270176af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
270276af099aSliuyi 		} else
270376af099aSliuyi 			printf("Parameter of [DB] command is invalid, please check help!\r\n");
2704c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
2705c30d921cSKever Yang 		if (argc > 2) {
2706c30d921cSKever Yang 			string strParameter;
2707c30d921cSKever Yang 			strParameter = argv[2];
2708c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
2709c30d921cSKever Yang 		} else
2710c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid, please check help!\r\n");
2711c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
2712c30d921cSKever Yang 		if (argc > 2) {
2713c30d921cSKever Yang 			string strLoader;
2714c30d921cSKever Yang 			strLoader = argv[2];
2715c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
2716c30d921cSKever Yang 		} else
2717c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid, please check help!\r\n");
271876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
271976af099aSliuyi 		if (argc == 2) {
272076af099aSliuyi 			bSuccess = erase_flash(dev);
272176af099aSliuyi 		} else
272276af099aSliuyi 			printf("Parameter of [EF] command is invalid, please check help!\r\n");
272376af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
272476af099aSliuyi 		if (argc == 4) {
272576af099aSliuyi 			UINT uiBegin;
272676af099aSliuyi 			char *pszEnd;
272776af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
272876af099aSliuyi 			if (*pszEnd)
272976af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
273076af099aSliuyi 			else
273176af099aSliuyi 				bSuccess = write_lba(dev, uiBegin, argv[3]);
273276af099aSliuyi 		} else
273376af099aSliuyi 			printf("Parameter of [WL] command is invalid, please check help!\r\n");
27346ae612beSliuyi 	} else if(strcmp(strCmd.c_str(), "WLX") == 0) {
27356ae612beSliuyi 		if (argc == 4) {
27366ae612beSliuyi 			bRet = read_gpt(dev, master_gpt);
27376ae612beSliuyi 			if (bRet) {
27386ae612beSliuyi 				bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end);
27396ae612beSliuyi 				if (bRet) {
27406ae612beSliuyi 					if (is_sparse_image(argv[3]))
27416ae612beSliuyi 						bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]);
27426ae612beSliuyi 					else
27436ae612beSliuyi 						bSuccess = write_lba(dev, (u32)lba, argv[3]);
27446ae612beSliuyi 				} else
27456ae612beSliuyi 					printf("No found %s partition\r\n", argv[2]);
27466ae612beSliuyi 			}
27476ae612beSliuyi 		} else
27486ae612beSliuyi 			printf("Parameter of [WLX] command is invalid, please check help!\r\n");
274976af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
275076af099aSliuyi 		char *pszEnd;
275176af099aSliuyi 		UINT uiBegin, uiLen;
275276af099aSliuyi 		if (argc != 5)
275376af099aSliuyi 			printf("Parameter of [RL] command is invalid, please check help!\r\n");
275476af099aSliuyi 		else {
275576af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
275676af099aSliuyi 			if (*pszEnd)
275776af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
275876af099aSliuyi 			else {
275976af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
276076af099aSliuyi 				if (*pszEnd)
276176af099aSliuyi 					printf("Len is invalid, please check!\r\n");
276276af099aSliuyi 				else {
276376af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
276476af099aSliuyi 				}
276576af099aSliuyi 			}
276676af099aSliuyi 		}
276776af099aSliuyi 	} else {
27689bc231bdSAndreas Färber 		printf("command is invalid!\r\n");
27699bc231bdSAndreas Färber 		usage();
277076af099aSliuyi 	}
277176af099aSliuyi 	return bSuccess;
277276af099aSliuyi }
277376af099aSliuyi 
277476af099aSliuyi 
277576af099aSliuyi int main(int argc, char* argv[])
277676af099aSliuyi {
277776af099aSliuyi 	CRKScan *pScan = NULL;
277876af099aSliuyi 	int ret;
277976af099aSliuyi 	char szProgramProcPath[100];
278076af099aSliuyi 	char szProgramDir[256];
278176af099aSliuyi 	string strLogDir,strConfigFile;
278276af099aSliuyi 	struct stat statBuf;
278376af099aSliuyi 
278476af099aSliuyi 	g_ConfigItemVec.clear();
278576af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
278676af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
278776af099aSliuyi 		strcpy(szProgramDir, ".");
278876af099aSliuyi 	else {
278976af099aSliuyi 		char *pSlash;
279076af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
279176af099aSliuyi 		if (pSlash)
279276af099aSliuyi 			*pSlash = '\0';
279376af099aSliuyi 	}
279476af099aSliuyi 	strLogDir = szProgramDir;
279576af099aSliuyi 	strLogDir +=  "/log/";
279676af099aSliuyi 	strConfigFile = szProgramDir;
279776af099aSliuyi 	strConfigFile += "/config.ini";
279876af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
279976af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
2800e5ee8cc0Sliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
280176af099aSliuyi 
280276af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
280376af099aSliuyi 		if (g_pLogObject) {
280476af099aSliuyi 			g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
280576af099aSliuyi 		}
280676af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
280776af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
280876af099aSliuyi 	}
280976af099aSliuyi 
281076af099aSliuyi 	ret = libusb_init(NULL);
281176af099aSliuyi 	if (ret < 0) {
281276af099aSliuyi 		if (g_pLogObject) {
281376af099aSliuyi 			g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
281476af099aSliuyi 			delete g_pLogObject;
281576af099aSliuyi 		}
281676af099aSliuyi 		return -1;
281776af099aSliuyi 	}
281876af099aSliuyi 
281976af099aSliuyi 	pScan = new CRKScan();
282076af099aSliuyi 	if (!pScan) {
282176af099aSliuyi 		if (g_pLogObject) {
282232268622SAndreas Färber 			g_pLogObject->Record("Error: failed to create object for searching device");
282376af099aSliuyi 			delete g_pLogObject;
282476af099aSliuyi 		}
282576af099aSliuyi 		libusb_exit(NULL);
282676af099aSliuyi 		return -2;
282776af099aSliuyi 	}
282876af099aSliuyi 	pScan->SetVidPid();
282976af099aSliuyi 
283076af099aSliuyi 	if (argc == 1)
283176af099aSliuyi 		usage();
283276af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
283376af099aSliuyi 			return -0xFF;
283476af099aSliuyi 	if (pScan)
283576af099aSliuyi 		delete pScan;
283676af099aSliuyi 	if (g_pLogObject)
283776af099aSliuyi 		delete g_pLogObject;
283876af099aSliuyi 	libusb_exit(NULL);
283976af099aSliuyi 	return 0;
284076af099aSliuyi }
2841