xref: /rkdeveloptool/main.cpp (revision 081d237ad5bf8f03170c9d60bd94ceefa0352aaf)
176af099aSliuyi /*
276af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi  * Seth Liu 2017.03.01
476af099aSliuyi  *
576af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
676af099aSliuyi  */
776af099aSliuyi 
876af099aSliuyi #include   <unistd.h>
976af099aSliuyi #include   <dirent.h>
10c30d921cSKever Yang #include "config.h"
1176af099aSliuyi #include "DefineHeader.h"
12c30d921cSKever Yang #include "gpt.h"
1376af099aSliuyi #include "RKLog.h"
1476af099aSliuyi #include "RKScan.h"
1576af099aSliuyi #include "RKComm.h"
1676af099aSliuyi #include "RKDevice.h"
1776af099aSliuyi #include "RKImage.h"
1876af099aSliuyi extern const char *szManufName[];
1976af099aSliuyi CRKLog *g_pLogObject=NULL;
2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec;
2176af099aSliuyi #define DEFAULT_RW_LBA 128
2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
2676af099aSliuyi #define ERROR_COLOR_ATTR  printf("%c[30;41m", 0x1B);
273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR  printf("%c[0m", 0x1B);
28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize);
29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize);
30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len);
31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len);
32c30d921cSKever Yang /*
33c30d921cSKever Yang u8 test_gpt_head[] = {
34c30d921cSKever Yang 	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00,
35c30d921cSKever Yang 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36c30d921cSKever Yang 	0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37c30d921cSKever Yang 	0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B,
38c30d921cSKever Yang 	0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39c30d921cSKever Yang 	0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08};
40c30d921cSKever Yang */
41c30d921cSKever Yang 
4276af099aSliuyi void usage()
4376af099aSliuyi {
4476af099aSliuyi 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
45ae4252f0Sliuyi 	printf("Help:\t\t\t-h or --help\r\n");
46154ee062SEddie Cai 	printf("Version:\t\t-v or --version\r\n");
47*081d237aSliuyi 	printf("ListDevice:\t\tld\r\n");
48154ee062SEddie Cai 	printf("DownloadBoot:\t\tdb <Loader>\r\n");
49154ee062SEddie Cai 	printf("UpgradeLoader:\t\tul <Loader>\r\n");
50154ee062SEddie Cai 	printf("ReadLBA:\t\trl  <BeginSec> <SectorLen> <File>\r\n");
51154ee062SEddie Cai 	printf("WriteLBA:\t\twl  <BeginSec> <File>\r\n");
526ae612beSliuyi 	printf("WriteLBA:\t\twlx  <PartitionName> <File>\r\n");
53154ee062SEddie Cai 	printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
54*081d237aSliuyi 	printf("WriteParameter:\t\tprm <parameter>\r\n");
55*081d237aSliuyi 	printf("PrintPartition:\t\tppt \r\n");
56154ee062SEddie Cai 	printf("EraseFlash:\t\tef \r\n");
57154ee062SEddie Cai 	printf("TestDevice:\t\ttd\r\n");
58154ee062SEddie Cai 	printf("ResetDevice:\t\trd [subcode]\r\n");
59154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
60154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
61154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
62*081d237aSliuyi 	printf("ReadCapability:\t\trcb\r\n");
6378884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
6478884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
65d71e8c20SEddie Cai 	printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
6676af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6776af099aSliuyi }
6876af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6976af099aSliuyi {
7076af099aSliuyi 	string strInfoText="";
7176af099aSliuyi 	char szText[256];
7276af099aSliuyi 	switch (promptID) {
7376af099aSliuyi 	case TESTDEVICE_PROGRESS:
7432268622SAndreas Färber 		sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue);
7576af099aSliuyi 		strInfoText = szText;
7676af099aSliuyi 		break;
7776af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7832268622SAndreas Färber 		sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue);
7976af099aSliuyi 		strInfoText = szText;
8076af099aSliuyi 		break;
8176af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
8232268622SAndreas Färber 		sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8376af099aSliuyi 		strInfoText = szText;
8476af099aSliuyi 		break;
8576af099aSliuyi 	case CHECKIMAGE_PROGRESS:
8632268622SAndreas Färber 		sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8776af099aSliuyi 		strInfoText = szText;
8876af099aSliuyi 		break;
8976af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
9032268622SAndreas Färber 		sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue);
9176af099aSliuyi 		strInfoText = szText;
9276af099aSliuyi 		break;
9376af099aSliuyi 	case TESTBLOCK_PROGRESS:
9432268622SAndreas Färber 		sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue);
9576af099aSliuyi 		strInfoText = szText;
9676af099aSliuyi 		break;
9776af099aSliuyi 	case ERASEFLASH_PROGRESS:
9832268622SAndreas Färber 		sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue);
9976af099aSliuyi 		strInfoText = szText;
10076af099aSliuyi 		break;
10176af099aSliuyi 	case ERASESYSTEM_PROGRESS:
10232268622SAndreas Färber 		sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue);
10376af099aSliuyi 		strInfoText = szText;
10476af099aSliuyi 		break;
10576af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
10632268622SAndreas Färber 		sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue);
10776af099aSliuyi 		strInfoText = szText;
10876af099aSliuyi 		break;
10976af099aSliuyi 	}
11076af099aSliuyi 	if (strInfoText.size() > 0){
11176af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
11276af099aSliuyi 		CURSOR_DEL_LINE;
11376af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
11476af099aSliuyi 	}
11576af099aSliuyi 	if (emCall == CALL_LAST)
11676af099aSliuyi 		deviceLayer = 0;
11776af099aSliuyi }
11876af099aSliuyi 
11976af099aSliuyi char *strupr(char *szSrc)
12076af099aSliuyi {
12176af099aSliuyi 	char *p = szSrc;
12276af099aSliuyi 	while(*p){
12376af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
12476af099aSliuyi 			*p = *p - 'a' + 'A';
12576af099aSliuyi 		p++;
12676af099aSliuyi 	}
12776af099aSliuyi 	return szSrc;
12876af099aSliuyi }
12976af099aSliuyi void PrintData(PBYTE pData, int nSize)
13076af099aSliuyi {
13176af099aSliuyi 	char szPrint[17] = "\0";
13276af099aSliuyi 	int i;
13376af099aSliuyi 	for( i = 0; i < nSize; i++){
13476af099aSliuyi 		if(i % 16 == 0){
13576af099aSliuyi 			if(i / 16 > 0)
13676af099aSliuyi 				printf("     %s\r\n", szPrint);
13776af099aSliuyi 			printf("%08d ", i / 16);
13876af099aSliuyi 		}
13976af099aSliuyi 		printf("%02X ", pData[i]);
14076af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
14176af099aSliuyi 	}
14276af099aSliuyi 	if(i / 16 > 0)
14376af099aSliuyi 		printf("     %s\r\n", szPrint);
14476af099aSliuyi }
14576af099aSliuyi 
14676af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
14776af099aSliuyi {
14876af099aSliuyi 	if (!pszSrc)
14976af099aSliuyi 		return false;
15076af099aSliuyi 	int nSrcLen = strlen(pszSrc);
15176af099aSliuyi 	int nDestLen = nSrcLen * 2;
15276af099aSliuyi 
15376af099aSliuyi 	pszDest = NULL;
15476af099aSliuyi 	pszDest = new wchar_t[nDestLen];
15576af099aSliuyi 	if (!pszDest)
15676af099aSliuyi 		return false;
15776af099aSliuyi 	nDestLen = nDestLen * sizeof(wchar_t);
15876af099aSliuyi 	memset(pszDest, 0, nDestLen);
15976af099aSliuyi 	int iRet;
16076af099aSliuyi 	iconv_t cd;
16176af099aSliuyi 	cd = iconv_open("UTF-32", "UTF-8");
16276af099aSliuyi 	if((iconv_t)-1 == cd) {
16376af099aSliuyi 		delete []pszDest;
16476af099aSliuyi 		pszDest = NULL;
16576af099aSliuyi 	      return false;
16676af099aSliuyi 	 }
16776af099aSliuyi 	char *pIn, *pOut;
16876af099aSliuyi 	pIn = (char *)pszSrc;
16976af099aSliuyi 	pOut = (char *)pszDest;
17076af099aSliuyi 
17176af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
17276af099aSliuyi 
17376af099aSliuyi 	if(iRet == -1) {
17476af099aSliuyi 		delete []pszDest;
17576af099aSliuyi 		pszDest = NULL;
17676af099aSliuyi 		iconv_close(cd);
17776af099aSliuyi 		return false;
17876af099aSliuyi 	 }
17976af099aSliuyi 
18076af099aSliuyi 	 iconv_close(cd);
18176af099aSliuyi 
18276af099aSliuyi 	 return true;
18376af099aSliuyi }
18476af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
18576af099aSliuyi {
18676af099aSliuyi 	if (!pszSrc)
18776af099aSliuyi 		return false;
18876af099aSliuyi 	int nSrcLen = wcslen(pszSrc);
18976af099aSliuyi 	int nDestLen = nSrcLen * 2;
19076af099aSliuyi 	nSrcLen = nSrcLen * sizeof(wchar_t);
19176af099aSliuyi 	pszDest = NULL;
19276af099aSliuyi 	pszDest = new char[nDestLen];
19376af099aSliuyi 	if (!pszDest)
19476af099aSliuyi 		return false;
19576af099aSliuyi 	memset(pszDest, 0, nDestLen);
19676af099aSliuyi 	int iRet;
19776af099aSliuyi 	iconv_t cd;
19876af099aSliuyi 	cd = iconv_open("UTF-8", "UTF-32");
19976af099aSliuyi 
20076af099aSliuyi 	if((iconv_t)-1 == cd) {
20176af099aSliuyi 		delete []pszDest;
20276af099aSliuyi 		pszDest = NULL;
20376af099aSliuyi 	      return false;
20476af099aSliuyi 	 }
20576af099aSliuyi 	char *pIn, *pOut;
20676af099aSliuyi 	pIn = (char *)pszSrc;
20776af099aSliuyi 	pOut = (char *)pszDest;
20876af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
20976af099aSliuyi 
21076af099aSliuyi 	if(iRet == -1) {
21176af099aSliuyi 		delete []pszDest;
21276af099aSliuyi 		pszDest = NULL;
21376af099aSliuyi 		iconv_close(cd);
21476af099aSliuyi 		return false;
21576af099aSliuyi 	 }
21676af099aSliuyi 
21776af099aSliuyi 	 iconv_close(cd);
21876af099aSliuyi 
21976af099aSliuyi 	 return true;
22076af099aSliuyi }
221c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName)
22276af099aSliuyi {
22376af099aSliuyi 	unsigned int i;
224c29e5f0fSliuyi 	for(i = 0; i < vecItems.size(); i++){
225c29e5f0fSliuyi 		if (strcasecmp(pszName, vecItems[i].szItemName) == 0){
22676af099aSliuyi 			return i;
22776af099aSliuyi 		}
22876af099aSliuyi 	}
22976af099aSliuyi 	return -1;
23076af099aSliuyi }
231c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid)
232c29e5f0fSliuyi {
233c29e5f0fSliuyi 	unsigned int i;
234c29e5f0fSliuyi 	char value;
235c29e5f0fSliuyi 	memset(uuid, 0, 16);
236c29e5f0fSliuyi 	for (i =0; i < strUUid.size(); i++) {
237c29e5f0fSliuyi 		value = 0;
238c29e5f0fSliuyi 		if ((strUUid[i] >= '0')&&(strUUid[i] <= '9'))
239c29e5f0fSliuyi 			value = strUUid[i] - '0';
240c29e5f0fSliuyi 		if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f'))
241c29e5f0fSliuyi 			value = strUUid[i] - 'a' + 10;
242c29e5f0fSliuyi 		if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F'))
243c29e5f0fSliuyi 			value = strUUid[i] - 'A' + 10;
244c29e5f0fSliuyi 		if ((i % 2) == 0)
245c29e5f0fSliuyi 			uuid[i / 2] += (value << 4);
246c29e5f0fSliuyi 		else
247c29e5f0fSliuyi 			uuid[i / 2] += value;
248c29e5f0fSliuyi 	}
249c29e5f0fSliuyi 	unsigned int *p32;
250c29e5f0fSliuyi 	unsigned short *p16;
251c29e5f0fSliuyi 	p32 = (unsigned int*)uuid;
252c29e5f0fSliuyi 	*p32 = cpu_to_be32(*p32);
253c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 4);
254c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
255c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 6);
256c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
257c29e5f0fSliuyi }
25876af099aSliuyi 
25976af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
26076af099aSliuyi {
26176af099aSliuyi 
26276af099aSliuyi 	stringstream configStream(pConfig);
26376af099aSliuyi 	string strLine, strItemName, strItemValue;
26476af099aSliuyi 	string::size_type line_size,pos;
26576af099aSliuyi 	STRUCT_CONFIG_ITEM item;
26676af099aSliuyi 	vecItem.clear();
26776af099aSliuyi 	while (!configStream.eof()){
26876af099aSliuyi 		getline(configStream, strLine);
26976af099aSliuyi 		line_size = strLine.size();
27076af099aSliuyi 		if (line_size == 0)
27176af099aSliuyi 			continue;
27276af099aSliuyi 		if (strLine[line_size-1] == '\r'){
27376af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
27476af099aSliuyi 		}
275c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
276c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
277c30d921cSKever Yang 		if (strLine.size()==0 )
278c30d921cSKever Yang 			continue;
279c30d921cSKever Yang 		if (strLine[0] == '#')
280c30d921cSKever Yang 			continue;
28176af099aSliuyi 		pos = strLine.find("=");
28276af099aSliuyi 		if (pos == string::npos){
28376af099aSliuyi 			continue;
28476af099aSliuyi 		}
28576af099aSliuyi 		strItemName = strLine.substr(0, pos);
28676af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
28776af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
28876af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
28976af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
29076af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
29176af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
29276af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
29376af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
29476af099aSliuyi 			vecItem.push_back(item);
29576af099aSliuyi 		}
29676af099aSliuyi 	}
29776af099aSliuyi 	return true;
29876af099aSliuyi 
29976af099aSliuyi }
30076af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
30176af099aSliuyi {
30276af099aSliuyi 	FILE *file = NULL;
30376af099aSliuyi 	file = fopen(pConfigFile, "rb");
30476af099aSliuyi 	if( !file ){
30576af099aSliuyi 		if (g_pLogObject)
30632268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile);
30776af099aSliuyi 		return false;
30876af099aSliuyi 	}
30976af099aSliuyi 	int iFileSize;
31076af099aSliuyi 	fseek(file, 0, SEEK_END);
31176af099aSliuyi 	iFileSize = ftell(file);
31276af099aSliuyi 	fseek(file, 0, SEEK_SET);
31376af099aSliuyi 	char *pConfigBuf = NULL;
31476af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
31576af099aSliuyi 	if (!pConfigBuf){
31676af099aSliuyi 		fclose(file);
31776af099aSliuyi 		return false;
31876af099aSliuyi 	}
31976af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
32076af099aSliuyi 	int iRead;
32176af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
32276af099aSliuyi 	if (iRead != iFileSize){
32376af099aSliuyi 		if (g_pLogObject)
32432268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize);
32576af099aSliuyi 		fclose(file);
32676af099aSliuyi 		delete []pConfigBuf;
32776af099aSliuyi 		return false;
32876af099aSliuyi 	}
32976af099aSliuyi 	fclose(file);
33076af099aSliuyi 	bool bRet;
33176af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
33276af099aSliuyi 	delete []pConfigBuf;
33376af099aSliuyi 	return bRet;
33476af099aSliuyi }
335c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
336c30d921cSKever Yang {
337c30d921cSKever Yang 	string::size_type pos,prevPos;
338c30d921cSKever Yang 	string strOffset,strLen;
339c30d921cSKever Yang 	int iCount;
340c30d921cSKever Yang 	prevPos = pos = 0;
341c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
342c30d921cSKever Yang 		return false;
343c30d921cSKever Yang 	}
344c30d921cSKever Yang 	pos = strPartInfo.find('@');
345c30d921cSKever Yang 	if (pos == string::npos) {
346c30d921cSKever Yang 		return false;
347c30d921cSKever Yang 	}
348c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
349c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
350c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
351c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
352c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
353c30d921cSKever Yang 	} else {
354c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
355c30d921cSKever Yang 		if (iCount != 1) {
356c30d921cSKever Yang 			return false;
357c30d921cSKever Yang 		}
358c30d921cSKever Yang 	}
359c30d921cSKever Yang 
360c30d921cSKever Yang 	prevPos = pos + 1;
361c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
362c30d921cSKever Yang 	if (pos == string::npos) {
363c30d921cSKever Yang 		return false;
364c30d921cSKever Yang 	}
365c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
366c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
367c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
368c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
369c30d921cSKever Yang 	if (iCount != 1) {
370c30d921cSKever Yang 		return false;
371c30d921cSKever Yang 	}
372c30d921cSKever Yang 	prevPos = pos + 1;
373c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
374c30d921cSKever Yang 	if (pos == string::npos) {
375c30d921cSKever Yang 		return false;
376c30d921cSKever Yang 	}
377c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
378c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
379c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
380c30d921cSKever Yang 
381c30d921cSKever Yang 	return true;
382c30d921cSKever Yang }
383c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid)
384c29e5f0fSliuyi {
385c29e5f0fSliuyi 	string::size_type pos(0);
386c30d921cSKever Yang 
387c29e5f0fSliuyi 	if (strUuidInfo.size() <= 0) {
388c29e5f0fSliuyi 		return false;
389c29e5f0fSliuyi 	}
390c29e5f0fSliuyi 	pos = strUuidInfo.find('=');
391c29e5f0fSliuyi 	if (pos == string::npos) {
392c29e5f0fSliuyi 		return false;
393c29e5f0fSliuyi 	}
394c29e5f0fSliuyi 	strName = strUuidInfo.substr(0, pos);
395c29e5f0fSliuyi 	strName.erase(0, strName.find_first_not_of(" "));
396c29e5f0fSliuyi 	strName.erase(strName.find_last_not_of(" ") + 1);
397c29e5f0fSliuyi 
398c29e5f0fSliuyi 	strUUid = strUuidInfo.substr(pos+1);
399c29e5f0fSliuyi 	strUUid.erase(0, strUUid.find_first_not_of(" "));
400c29e5f0fSliuyi 	strUUid.erase(strUUid.find_last_not_of(" ") + 1);
401c29e5f0fSliuyi 
402c29e5f0fSliuyi 	while(true) {
403c29e5f0fSliuyi 		pos = 0;
404c29e5f0fSliuyi 		if( (pos = strUUid.find("-")) != string::npos)
405c29e5f0fSliuyi 			strUUid.replace(pos,1,"");
406c29e5f0fSliuyi 		else
407c29e5f0fSliuyi 			break;
408c29e5f0fSliuyi 	}
409c29e5f0fSliuyi 	if (strUUid.size() != 32)
410c29e5f0fSliuyi 		return false;
411c29e5f0fSliuyi 	return true;
412c29e5f0fSliuyi }
413c29e5f0fSliuyi 
414c29e5f0fSliuyi 
415c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
416c30d921cSKever Yang {
417c30d921cSKever Yang 	stringstream paramStream(pParameter);
418c30d921cSKever Yang 	bool bRet,bFind = false;
419c29e5f0fSliuyi 	string strLine, strPartition, strPartInfo, strPartName, strUUid;
420c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
421c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
422c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
423c29e5f0fSliuyi 	STRUCT_CONFIG_ITEM uuid_item;
424c30d921cSKever Yang 	vecItem.clear();
425c29e5f0fSliuyi 	vecUuidItem.clear();
426c30d921cSKever Yang 	while (!paramStream.eof()) {
427c30d921cSKever Yang 		getline(paramStream,strLine);
428c30d921cSKever Yang 		line_size = strLine.size();
429c30d921cSKever Yang 		if (line_size == 0)
430c30d921cSKever Yang 			continue;
431c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
432c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
433c30d921cSKever Yang 		}
434c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
435c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
436c30d921cSKever Yang 		if (strLine.size()==0 )
437c30d921cSKever Yang 			continue;
438c30d921cSKever Yang 		if (strLine[0] == '#')
439c30d921cSKever Yang 			continue;
440c29e5f0fSliuyi 		pos = strLine.find("uuid:");
441c29e5f0fSliuyi 		if (pos != string::npos) {
442c29e5f0fSliuyi 			strPartInfo = strLine.substr(pos+5);
443c29e5f0fSliuyi 			bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid);
444c29e5f0fSliuyi 			if (bRet) {
445c29e5f0fSliuyi 				strcpy(uuid_item.szItemName, strPartName.c_str());
446c29e5f0fSliuyi 				string_to_uuid(strUUid,uuid_item.szItemValue);
447c29e5f0fSliuyi 				vecUuidItem.push_back(uuid_item);
448c29e5f0fSliuyi 			}
449c29e5f0fSliuyi 			continue;
450c29e5f0fSliuyi 		}
451c29e5f0fSliuyi 
452c30d921cSKever Yang 		pos = strLine.find("mtdparts");
453c30d921cSKever Yang 		if (pos == string::npos) {
454c30d921cSKever Yang 			continue;
455c30d921cSKever Yang 		}
456c30d921cSKever Yang 		bFind = true;
457c30d921cSKever Yang 		posColon = strLine.find(':', pos);
458c30d921cSKever Yang 		if (posColon == string::npos) {
459c30d921cSKever Yang 			continue;
460c30d921cSKever Yang 		}
461c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
462c30d921cSKever Yang 		pos = 0;
463c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
464c30d921cSKever Yang 		while (posComma != string::npos) {
465c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
466c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
467c30d921cSKever Yang 			if (bRet) {
468c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
469c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
470c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
471c30d921cSKever Yang 				vecItem.push_back(item);
472c30d921cSKever Yang 			}
473c30d921cSKever Yang 			pos = posComma + 1;
474c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
475c30d921cSKever Yang 		}
476c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
477c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
478c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
479c30d921cSKever Yang 			if (bRet) {
480c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
481c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
482c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
483c30d921cSKever Yang 				vecItem.push_back(item);
484c30d921cSKever Yang 			}
485c30d921cSKever Yang 		}
486c30d921cSKever Yang 		break;
487c30d921cSKever Yang 	}
488c30d921cSKever Yang 	return bFind;
489c30d921cSKever Yang 
490c30d921cSKever Yang }
491c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
492c30d921cSKever Yang {
493c30d921cSKever Yang 	FILE *file = NULL;
494c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
495c30d921cSKever Yang 	if( !file ) {
496c30d921cSKever Yang 		if (g_pLogObject)
49732268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
498c30d921cSKever Yang 		return false;
499c30d921cSKever Yang 	}
500c30d921cSKever Yang 	int iFileSize;
501c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
502c30d921cSKever Yang 	iFileSize = ftell(file);
503c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
504c30d921cSKever Yang 	char *pParamBuf = NULL;
505c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
506c30d921cSKever Yang 	if (!pParamBuf) {
507c30d921cSKever Yang 		fclose(file);
508c30d921cSKever Yang 		return false;
509c30d921cSKever Yang 	}
510c30d921cSKever Yang 	int iRead;
511c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
512c30d921cSKever Yang 	if (iRead != iFileSize) {
513c30d921cSKever Yang 		if (g_pLogObject)
51432268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
515c30d921cSKever Yang 		fclose(file);
516c30d921cSKever Yang 		delete []pParamBuf;
517c30d921cSKever Yang 		return false;
518c30d921cSKever Yang 	}
519c30d921cSKever Yang 	fclose(file);
520c30d921cSKever Yang 	bool bRet;
521c29e5f0fSliuyi 	bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem);
522c30d921cSKever Yang 	delete []pParamBuf;
523c30d921cSKever Yang 	return bRet;
524c30d921cSKever Yang }
5256ae612beSliuyi bool is_sparse_image(char *szImage)
5266ae612beSliuyi {
5276ae612beSliuyi 	FILE *file = NULL;
5286ae612beSliuyi 	sparse_header head;
5296ae612beSliuyi 	u32 uiRead;
5306ae612beSliuyi 	file = fopen(szImage, "rb");
5316ae612beSliuyi 	if( !file ) {
5326ae612beSliuyi 		if (g_pLogObject)
5336ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
5346ae612beSliuyi 		return false;
5356ae612beSliuyi 	}
5366ae612beSliuyi 	uiRead = fread(&head, 1, sizeof(head), file);
5376ae612beSliuyi 	if (uiRead != sizeof(head)) {
5386ae612beSliuyi 		if (g_pLogObject)
5396ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head));
5406ae612beSliuyi 		fclose(file);
5416ae612beSliuyi 		return false;
5426ae612beSliuyi 	}
5436ae612beSliuyi 	fclose(file);
5446ae612beSliuyi 	if (head.magic!=SPARSE_HEADER_MAGIC)
5456ae612beSliuyi 	{
5466ae612beSliuyi 		return false;
5476ae612beSliuyi 	}
5486ae612beSliuyi 	return true;
5496ae612beSliuyi 
5506ae612beSliuyi }
551c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
552c30d921cSKever Yang {
553c30d921cSKever Yang 	efi_guid_t id;
554c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
555c30d921cSKever Yang 	unsigned int i;
556c30d921cSKever Yang 
557c30d921cSKever Yang 	/* Set all fields randomly */
558c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
559c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
560c30d921cSKever Yang 
561c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
562c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
563c30d921cSKever Yang 
564c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
565c30d921cSKever Yang }
566c30d921cSKever Yang 
567c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup)
568c29e5f0fSliuyi {
569c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
570c29e5f0fSliuyi 	gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
571c29e5f0fSliuyi 	u32 calc_crc32;
572c29e5f0fSliuyi 	u64 val;
573c29e5f0fSliuyi 
574c29e5f0fSliuyi 	/* recalculate the values for the Backup GPT Header */
575c29e5f0fSliuyi 	val = le64_to_cpu(gptMasterHead->my_lba);
576c29e5f0fSliuyi 	gptBackupHead->my_lba = gptMasterHead->alternate_lba;
577c29e5f0fSliuyi 	gptBackupHead->alternate_lba = cpu_to_le64(val);
578c29e5f0fSliuyi 	gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
579c29e5f0fSliuyi 	gptBackupHead->header_crc32 = 0;
580c29e5f0fSliuyi 
581c29e5f0fSliuyi 	calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
582c29e5f0fSliuyi 	gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
583c29e5f0fSliuyi }
5846ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end)
5856ae612beSliuyi {
5866ae612beSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
5876ae612beSliuyi 	gpt_entry  *gptEntry  = NULL;
5886ae612beSliuyi 	u32 i,j;
5896ae612beSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
5906ae612beSliuyi 	bool bFound = false;
5916ae612beSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
5926ae612beSliuyi 
5936ae612beSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
5946ae612beSliuyi 		gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
5956ae612beSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
5966ae612beSliuyi 			break;
5976ae612beSliuyi 		for (j = 0; j < strlen(pszName); j++)
5986ae612beSliuyi 			if (gptEntry->partition_name[j] != pszName[j])
5996ae612beSliuyi 				break;
6006ae612beSliuyi 		if (gptEntry->partition_name[j] != 0)
6016ae612beSliuyi 			continue;
6026ae612beSliuyi 		if (j == strlen(pszName)) {
6036ae612beSliuyi 			bFound = true;
6046ae612beSliuyi 			break;
6056ae612beSliuyi 		}
6066ae612beSliuyi 	}
6076ae612beSliuyi 	if (bFound) {
6086ae612beSliuyi 		*lba = le64_to_cpu(gptEntry->starting_lba);
6096ae612beSliuyi 		*lba_end =  le64_to_cpu(gptEntry->ending_lba);
6106ae612beSliuyi 		return true;
6116ae612beSliuyi 	}
6126ae612beSliuyi 	return false;
6136ae612beSliuyi }
614*081d237aSliuyi bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size)
615*081d237aSliuyi {
616*081d237aSliuyi 	u32 i;
617*081d237aSliuyi 	bool bFound = false, bRet;
618*081d237aSliuyi 	PARAM_ITEM_VECTOR vecItem;
619*081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
620*081d237aSliuyi 
621*081d237aSliuyi 	bRet = parse_parameter((char *)param, vecItem, vecUuid);
622*081d237aSliuyi 	if (!bRet)
623*081d237aSliuyi 		return false;
624*081d237aSliuyi 
625*081d237aSliuyi 	for (i = 0; i < vecItem.size(); i++) {
626*081d237aSliuyi 		if (strcasecmp(pszName, vecItem[i].szItemName)==0) {
627*081d237aSliuyi 			bFound = true;
628*081d237aSliuyi 			break;
629*081d237aSliuyi 		}
630*081d237aSliuyi 	}
631*081d237aSliuyi 	if (bFound) {
632*081d237aSliuyi 		*part_offset = vecItem[i].uiItemOffset;
633*081d237aSliuyi 		*part_size =  vecItem[i].uiItemSize;
634*081d237aSliuyi 		return true;
635*081d237aSliuyi 	}
636*081d237aSliuyi 	return false;
637*081d237aSliuyi }
638*081d237aSliuyi 
639c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector)
640c29e5f0fSliuyi {
641c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
642c29e5f0fSliuyi 	gpt_entry  *gptLastPartEntry  = NULL;
643c29e5f0fSliuyi 	u32 i;
644c29e5f0fSliuyi 	u64 old_disksize;
645c29e5f0fSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
646c29e5f0fSliuyi 
647c29e5f0fSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
648c29e5f0fSliuyi 	old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1;
649c29e5f0fSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
650c29e5f0fSliuyi 		gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
651c29e5f0fSliuyi 		if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0)
652c29e5f0fSliuyi 			break;
653c29e5f0fSliuyi 	}
654c29e5f0fSliuyi 	i--;
655c29e5f0fSliuyi 	gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry));
656c29e5f0fSliuyi 
657c29e5f0fSliuyi 	gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1);
658c29e5f0fSliuyi 	gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34);
659c29e5f0fSliuyi 
660c29e5f0fSliuyi 	if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition
661c29e5f0fSliuyi 		gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34);
662c29e5f0fSliuyi 		gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
663c29e5f0fSliuyi 	}
664c29e5f0fSliuyi 	gptMasterHead->header_crc32 = 0;
665c29e5f0fSliuyi 	gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header)));
666c29e5f0fSliuyi 	memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS);
667c29e5f0fSliuyi 	memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE);
668c29e5f0fSliuyi 	prepare_gpt_backup(master, backup);
669c29e5f0fSliuyi 
670c29e5f0fSliuyi }
671c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup)
672c29e5f0fSliuyi {
673c29e5f0fSliuyi 	FILE *file = NULL;
674c29e5f0fSliuyi 	file = fopen(pParamFile, "rb");
675c29e5f0fSliuyi 	if( !file ) {
676c29e5f0fSliuyi 		if (g_pLogObject)
677c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
678c29e5f0fSliuyi 		return false;
679c29e5f0fSliuyi 	}
680c29e5f0fSliuyi 	int iFileSize;
681c29e5f0fSliuyi 	fseek(file, 0, SEEK_END);
682c29e5f0fSliuyi 	iFileSize = ftell(file);
683c29e5f0fSliuyi 	fseek(file, 0, SEEK_SET);
684c29e5f0fSliuyi 	if (iFileSize != 67 * SECTOR_SIZE) {
685c29e5f0fSliuyi 		if (g_pLogObject)
686c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile);
687c29e5f0fSliuyi 		fclose(file);
688c29e5f0fSliuyi 		return false;
689c29e5f0fSliuyi 	}
690c29e5f0fSliuyi 
691c29e5f0fSliuyi 	int iRead;
692c29e5f0fSliuyi 	iRead = fread(master, 1, 34 * SECTOR_SIZE, file);
693c29e5f0fSliuyi 	if (iRead != 34 * SECTOR_SIZE) {
694c29e5f0fSliuyi 		if (g_pLogObject)
695c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE);
696c29e5f0fSliuyi 		fclose(file);
697c29e5f0fSliuyi 		return false;
698c29e5f0fSliuyi 	}
699c29e5f0fSliuyi 	iRead = fread(backup, 1, 33 * SECTOR_SIZE, file);
700c29e5f0fSliuyi 	if (iRead != 33 * SECTOR_SIZE) {
701c29e5f0fSliuyi 		if (g_pLogObject)
702c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE);
703c29e5f0fSliuyi 		fclose(file);
704c29e5f0fSliuyi 		return false;
705c29e5f0fSliuyi 	}
706c29e5f0fSliuyi 	fclose(file);
707c29e5f0fSliuyi 	return true;
708c29e5f0fSliuyi }
709c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
710c30d921cSKever Yang {
711c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
712c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
713c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
714c30d921cSKever Yang 	u32 i,j;
715c29e5f0fSliuyi 	int pos;
716c30d921cSKever Yang 	string strPartName;
717c30d921cSKever Yang 	string::size_type colonPos;
718c30d921cSKever Yang 	/*1.protective mbr*/
719c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
720c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
721c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
722c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
723c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
724c30d921cSKever Yang 	/*2.gpt header*/
725c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
726c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
727c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
728c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
729c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
730c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
731c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
732c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
733c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
734c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
735c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
736c30d921cSKever Yang 	gptHead->header_crc32 = 0;
737c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
738c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
739c30d921cSKever Yang 
740c30d921cSKever Yang 	/*3.gpt partition entry*/
741c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
742c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
743c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
744c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
745c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
746c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
747c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
748c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
749c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
750c30d921cSKever Yang 		if (colonPos != string::npos) {
751c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
752c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
753c29e5f0fSliuyi 			if (strPartName.find("grow") != string::npos)
754c29e5f0fSliuyi 				gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
755c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
756c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
757c30d921cSKever Yang 		}
758c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
759c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
760c29e5f0fSliuyi 		if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1)
761c29e5f0fSliuyi 			memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
762c30d921cSKever Yang 		gptEntry++;
763c30d921cSKever Yang 	}
764c30d921cSKever Yang 
765c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
766c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
767c30d921cSKever Yang 
768c30d921cSKever Yang }
769b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
770c30d921cSKever Yang {
771c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
772c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
773c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
774c30d921cSKever Yang 
775c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
776b38fe5fcSliuyi 	pSec0->uiRc4Flag = rc4Flag;
777c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
778c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
779c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
780c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
781c30d921cSKever Yang 	return true;
782c30d921cSKever Yang }
783c30d921cSKever Yang 
784c30d921cSKever Yang 
785c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
786c30d921cSKever Yang {
787c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
788c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
789c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
790c30d921cSKever Yang 
791c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
792c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
793c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
794c30d921cSKever Yang 	return true;
795c30d921cSKever Yang }
796c30d921cSKever Yang 
797c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
798c30d921cSKever Yang {
799c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
800c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
801c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
802c30d921cSKever Yang 
803c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
804c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
805c30d921cSKever Yang 	return true;
806c30d921cSKever Yang }
807c30d921cSKever Yang 
808c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
809c30d921cSKever Yang {
810c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
811c30d921cSKever Yang 	return true;
812c30d921cSKever Yang }
813c30d921cSKever Yang 
814b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
815c30d921cSKever Yang {
816c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
817c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
818c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
819c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
820c30d921cSKever Yang 	UINT i;
821b38fe5fcSliuyi 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
822c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
823c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
824c30d921cSKever Yang 		return -6;
825c30d921cSKever Yang 	}
826c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
827c30d921cSKever Yang 		return -7;
828c30d921cSKever Yang 	}
829c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
830c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
831c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
832c30d921cSKever Yang 
833c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
834c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
835c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
836b38fe5fcSliuyi 
837b38fe5fcSliuyi 	if (rc4Flag) {
838b38fe5fcSliuyi 		for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
839b38fe5fcSliuyi 			P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
840b38fe5fcSliuyi 		for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
841b38fe5fcSliuyi 			P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
842b38fe5fcSliuyi 	}
843b38fe5fcSliuyi 
844c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
845c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
846c30d921cSKever Yang 
847c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
848c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
849c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
850c30d921cSKever Yang 		if(i == 1) {
851c30d921cSKever Yang 			continue;
852c30d921cSKever Yang 		} else {
853c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
854c30d921cSKever Yang 		}
855c30d921cSKever Yang 	}
856c30d921cSKever Yang 	return 0;
857c30d921cSKever Yang }
858c30d921cSKever Yang 
859c30d921cSKever Yang 
86076af099aSliuyi 
86176af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
86276af099aSliuyi {
86306ea143eSKlaus Goger 	if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType)
86476af099aSliuyi 		return true;
86576af099aSliuyi 	else
86676af099aSliuyi 	{
86776af099aSliuyi 		ERROR_COLOR_ATTR;
86832268622SAndreas Färber 		printf("The device does not support this operation!");
86976af099aSliuyi 		NORMAL_COLOR_ATTR;
87076af099aSliuyi 		printf("\r\n");
87176af099aSliuyi 		return false;
87276af099aSliuyi 	}
87376af099aSliuyi }
874*081d237aSliuyi bool MakeParamBuffer(char *pParamFile, char* &pParamData)
875*081d237aSliuyi {
876*081d237aSliuyi 	FILE *file=NULL;
877*081d237aSliuyi 	file = fopen(pParamFile, "rb");
878*081d237aSliuyi 	if( !file )
879*081d237aSliuyi 	{
880*081d237aSliuyi 		if (g_pLogObject)
881*081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile);
882*081d237aSliuyi 		return false;
883*081d237aSliuyi 	}
884*081d237aSliuyi 	int iFileSize;
885*081d237aSliuyi 	fseek(file,0,SEEK_END);
886*081d237aSliuyi 	iFileSize = ftell(file);
887*081d237aSliuyi 	fseek(file,0,SEEK_SET);
888*081d237aSliuyi 	char *pParamBuf=NULL;
889*081d237aSliuyi 	pParamBuf = new char[iFileSize + 12];
890*081d237aSliuyi 	if (!pParamBuf)
891*081d237aSliuyi 	{
892*081d237aSliuyi 		fclose(file);
893*081d237aSliuyi 		return false;
894*081d237aSliuyi 	}
895*081d237aSliuyi 	memset(pParamBuf,0,iFileSize+12);
896*081d237aSliuyi 	*(UINT *)(pParamBuf) = 0x4D524150;
897*081d237aSliuyi 
898*081d237aSliuyi 	int iRead;
899*081d237aSliuyi 	iRead = fread(pParamBuf+8,1,iFileSize,file);
900*081d237aSliuyi 	if (iRead!=iFileSize)
901*081d237aSliuyi 	{
902*081d237aSliuyi 		if (g_pLogObject)
903*081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize);
904*081d237aSliuyi 		fclose(file);
905*081d237aSliuyi 		delete []pParamBuf;
906*081d237aSliuyi 		return false;
907*081d237aSliuyi 	}
908*081d237aSliuyi 	fclose(file);
909*081d237aSliuyi 
910*081d237aSliuyi 	*(UINT *)(pParamBuf+4) = iFileSize;
911*081d237aSliuyi 	*(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize);
912*081d237aSliuyi 	pParamData = pParamBuf;
913*081d237aSliuyi 	return true;
914*081d237aSliuyi }
915*081d237aSliuyi 
916*081d237aSliuyi bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
917*081d237aSliuyi {
918*081d237aSliuyi 	CRKComm *pComm = NULL;
919*081d237aSliuyi 	char *pParamBuf = NULL, writeBuf[512*1024];
920*081d237aSliuyi 	int iRet, nParamSec, nParamSize;
921*081d237aSliuyi 	bool bRet, bSuccess = false;
922*081d237aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER))
923*081d237aSliuyi 		return false;
924*081d237aSliuyi 
925*081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
926*081d237aSliuyi 	if (!bRet) {
927*081d237aSliuyi 		ERROR_COLOR_ATTR;
928*081d237aSliuyi 		printf("Creating Comm Object failed!");
929*081d237aSliuyi 		NORMAL_COLOR_ATTR;
930*081d237aSliuyi 		printf("\r\n");
931*081d237aSliuyi 		return bSuccess;
932*081d237aSliuyi 	}
933*081d237aSliuyi 	if (!MakeParamBuffer(szParameter, pParamBuf)) {
934*081d237aSliuyi 		ERROR_COLOR_ATTR;
935*081d237aSliuyi 		printf("Generating parameter failed!");
936*081d237aSliuyi 		NORMAL_COLOR_ATTR;
937*081d237aSliuyi 		printf("\r\n");
938*081d237aSliuyi 		return bSuccess;
939*081d237aSliuyi 	}
940*081d237aSliuyi 	printf("Writing parameter...\r\n");
941*081d237aSliuyi 	nParamSize = *(UINT *)(pParamBuf+4) + 12;
942*081d237aSliuyi 	nParamSec = BYTE2SECTOR(nParamSize);
943*081d237aSliuyi 	if (nParamSec > 1024) {
944*081d237aSliuyi 		ERROR_COLOR_ATTR;
945*081d237aSliuyi 		printf("parameter is too large!");
946*081d237aSliuyi 		NORMAL_COLOR_ATTR;
947*081d237aSliuyi 		printf("\r\n");
948*081d237aSliuyi 		return bSuccess;
949*081d237aSliuyi 	}
950*081d237aSliuyi 	memset(writeBuf, 0, nParamSec*512);
951*081d237aSliuyi 	memcpy(writeBuf, pParamBuf, nParamSize);
952*081d237aSliuyi 	iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf);
953*081d237aSliuyi 	if (iRet != ERR_SUCCESS) {
954*081d237aSliuyi 		ERROR_COLOR_ATTR;
955*081d237aSliuyi 		printf("Writing parameter failed!");
956*081d237aSliuyi 		NORMAL_COLOR_ATTR;
957*081d237aSliuyi 		printf("\r\n");
958*081d237aSliuyi 		return bSuccess;
959*081d237aSliuyi 	}
960*081d237aSliuyi 
961*081d237aSliuyi 	bSuccess = true;
962*081d237aSliuyi 	CURSOR_MOVEUP_LINE(1);
963*081d237aSliuyi 	CURSOR_DEL_LINE;
964*081d237aSliuyi 	printf("Writing parameter succeeded.\r\n");
965*081d237aSliuyi 	return bSuccess;
966*081d237aSliuyi }
967*081d237aSliuyi 
968c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
969c30d921cSKever Yang {
970c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
971c30d921cSKever Yang 	u32 total_size_sector;
972c30d921cSKever Yang 	CRKComm *pComm = NULL;
973c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
974c29e5f0fSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
975c30d921cSKever Yang 	int iRet;
976c30d921cSKever Yang 	bool bRet, bSuccess = false;
977c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
978c30d921cSKever Yang 		return false;
979c30d921cSKever Yang 
980c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
981c30d921cSKever Yang 	if (!bRet) {
982c30d921cSKever Yang 		ERROR_COLOR_ATTR;
983c30d921cSKever Yang 		printf("Creating Comm Object failed!");
984c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
985c30d921cSKever Yang 		printf("\r\n");
986c30d921cSKever Yang 		return bSuccess;
987c30d921cSKever Yang 	}
98832268622SAndreas Färber 	printf("Writing gpt...\r\n");
989c30d921cSKever Yang 	//1.get flash info
990c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
991c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
992c30d921cSKever Yang 		ERROR_COLOR_ATTR;
993c30d921cSKever Yang 		printf("Reading Flash Info failed!");
994c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
995c30d921cSKever Yang 		printf("\r\n");
996c30d921cSKever Yang 		return bSuccess;
997c30d921cSKever Yang 	}
998c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
999c29e5f0fSliuyi 	if (strstr(szParameter, ".img")) {
1000c29e5f0fSliuyi 		if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) {
1001c29e5f0fSliuyi 			ERROR_COLOR_ATTR;
1002c29e5f0fSliuyi 			printf("Loading partition image failed!");
1003c29e5f0fSliuyi 			NORMAL_COLOR_ATTR;
1004c29e5f0fSliuyi 			printf("\r\n");
1005c29e5f0fSliuyi 			return bSuccess;
1006c29e5f0fSliuyi 		}
1007c29e5f0fSliuyi 		update_gpt_disksize(master_gpt, backup_gpt, total_size_sector);
1008c29e5f0fSliuyi 	} else {
1009c30d921cSKever Yang 		//2.get partition from parameter
1010c29e5f0fSliuyi 		bRet = parse_parameter_file(szParameter, vecItems, vecUuid);
1011c30d921cSKever Yang 		if (!bRet) {
1012c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1013c30d921cSKever Yang 			printf("Parsing parameter failed!");
1014c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1015c30d921cSKever Yang 			printf("\r\n");
1016c30d921cSKever Yang 			return bSuccess;
1017c30d921cSKever Yang 		}
1018c29e5f0fSliuyi 		vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33;
1019c30d921cSKever Yang 		//3.generate gpt info
1020c29e5f0fSliuyi 		create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector);
1021c30d921cSKever Yang 		memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
1022c30d921cSKever Yang 		memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
1023c29e5f0fSliuyi 		prepare_gpt_backup(master_gpt, backup_gpt);
1024c29e5f0fSliuyi 	}
1025c29e5f0fSliuyi 
1026c30d921cSKever Yang 	//4. write gpt
1027c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
1028c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
1029c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1030c30d921cSKever Yang 		printf("Writing master gpt failed!");
1031c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1032c30d921cSKever Yang 		printf("\r\n");
1033c30d921cSKever Yang 		return bSuccess;
1034c30d921cSKever Yang 	}
1035c29e5f0fSliuyi 	iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt);
1036c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
1037c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1038c30d921cSKever Yang 		printf("Writing backup gpt failed!");
1039c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1040c30d921cSKever Yang 		printf("\r\n");
1041c30d921cSKever Yang 		return bSuccess;
1042c30d921cSKever Yang 	}
1043c29e5f0fSliuyi 
1044c30d921cSKever Yang 	bSuccess = true;
1045c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
1046c30d921cSKever Yang 	CURSOR_DEL_LINE;
104732268622SAndreas Färber 	printf("Writing gpt succeeded.\r\n");
1048c30d921cSKever Yang 	return bSuccess;
1049c30d921cSKever Yang }
105076af099aSliuyi 
105178884ef4SEddie Cai #include "boot_merger.h"
105278884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
105378884ef4SEddie Cai options gOpts;
105478884ef4SEddie Cai 
105578884ef4SEddie Cai 
105678884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
105778884ef4SEddie Cai char* gConfigPath;
105878884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
105978884ef4SEddie Cai 
106078884ef4SEddie Cai static inline void fixPath(char* path) {
106178884ef4SEddie Cai 	int i, len = strlen(path);
106278884ef4SEddie Cai 	for(i=0; i<len; i++) {
106378884ef4SEddie Cai 		if (path[i] == '\\')
106478884ef4SEddie Cai 			path[i] = '/';
106578884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
106678884ef4SEddie Cai 			path[i] = '\0';
106778884ef4SEddie Cai 	}
106878884ef4SEddie Cai }
106978884ef4SEddie Cai 
107078884ef4SEddie Cai static bool parseChip(FILE* file) {
107178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
107278884ef4SEddie Cai 		return false;
107378884ef4SEddie Cai 	}
107478884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
107578884ef4SEddie Cai 		return false;
107678884ef4SEddie Cai 	}
107778884ef4SEddie Cai 	printf("chip: %s\n", gOpts.chip);
107878884ef4SEddie Cai 	return true;
107978884ef4SEddie Cai }
108078884ef4SEddie Cai 
108178884ef4SEddie Cai static bool parseVersion(FILE* file) {
108278884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
108378884ef4SEddie Cai 		return false;
108478884ef4SEddie Cai 	}
108578884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
108678884ef4SEddie Cai 		return false;
108778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
108878884ef4SEddie Cai 		return false;
108978884ef4SEddie Cai 	}
109078884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
109178884ef4SEddie Cai 		return false;
109278884ef4SEddie Cai 	printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
109378884ef4SEddie Cai 	return true;
109478884ef4SEddie Cai }
109578884ef4SEddie Cai 
109678884ef4SEddie Cai static bool parse471(FILE* file) {
109778884ef4SEddie Cai 	int i, index, pos;
109878884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
109978884ef4SEddie Cai 
110078884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
110178884ef4SEddie Cai 		return false;
110278884ef4SEddie Cai 	}
110378884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
110478884ef4SEddie Cai 		return false;
110578884ef4SEddie Cai 	printf("num: %d\n", gOpts.code471Num);
110678884ef4SEddie Cai 	if (!gOpts.code471Num)
110778884ef4SEddie Cai 		return true;
110878884ef4SEddie Cai 	if (gOpts.code471Num < 0)
110978884ef4SEddie Cai 		return false;
111078884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
111178884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
111278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
111378884ef4SEddie Cai 			return false;
111478884ef4SEddie Cai 		}
111578884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
111678884ef4SEddie Cai 				!= 2)
111778884ef4SEddie Cai 			return false;
111878884ef4SEddie Cai 		index--;
111978884ef4SEddie Cai 		fixPath(buf);
112078884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
112178884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code471Path[index]);
112278884ef4SEddie Cai 	}
112378884ef4SEddie Cai 	pos = ftell(file);
112478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
112578884ef4SEddie Cai 		return false;
112678884ef4SEddie Cai 	}
112778884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
112878884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
112978884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code471Sleep);
113078884ef4SEddie Cai 	return true;
113178884ef4SEddie Cai }
113278884ef4SEddie Cai 
113378884ef4SEddie Cai static bool parse472(FILE* file) {
113478884ef4SEddie Cai 	int i, index, pos;
113578884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
113678884ef4SEddie Cai 
113778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
113878884ef4SEddie Cai 		return false;
113978884ef4SEddie Cai 	}
114078884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
114178884ef4SEddie Cai 		return false;
114278884ef4SEddie Cai 	printf("num: %d\n", gOpts.code472Num);
114378884ef4SEddie Cai 	if (!gOpts.code472Num)
114478884ef4SEddie Cai 		return true;
114578884ef4SEddie Cai 	if (gOpts.code472Num < 0)
114678884ef4SEddie Cai 		return false;
114778884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
114878884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
114978884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
115078884ef4SEddie Cai 			return false;
115178884ef4SEddie Cai 		}
115278884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
115378884ef4SEddie Cai 				!= 2)
115478884ef4SEddie Cai 			return false;
115578884ef4SEddie Cai 		fixPath(buf);
115678884ef4SEddie Cai 		index--;
115778884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
115878884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code472Path[index]);
115978884ef4SEddie Cai 	}
116078884ef4SEddie Cai 	pos = ftell(file);
116178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
116278884ef4SEddie Cai 		return false;
116378884ef4SEddie Cai 	}
116478884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
116578884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
116678884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code472Sleep);
116778884ef4SEddie Cai 	return true;
116878884ef4SEddie Cai }
116978884ef4SEddie Cai 
117078884ef4SEddie Cai static bool parseLoader(FILE* file) {
117178884ef4SEddie Cai 	int i, j, index, pos;
117278884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
117378884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
117478884ef4SEddie Cai 
117578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
117678884ef4SEddie Cai 		return false;
117778884ef4SEddie Cai 	}
117878884ef4SEddie Cai 	pos = ftell(file);
117978884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
118078884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
118178884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
118278884ef4SEddie Cai 			return false;
118378884ef4SEddie Cai 		}
118478884ef4SEddie Cai 	}
118578884ef4SEddie Cai 	printf("num: %d\n", gOpts.loaderNum);
118678884ef4SEddie Cai 	if (!gOpts.loaderNum)
118778884ef4SEddie Cai 		return false;
118878884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
118978884ef4SEddie Cai 		return false;
119078884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
119178884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
119278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
119378884ef4SEddie Cai 			return false;
119478884ef4SEddie Cai 		}
119578884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
119678884ef4SEddie Cai 				!= 2)
119778884ef4SEddie Cai 			return false;
119878884ef4SEddie Cai 		index--;
119978884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
120078884ef4SEddie Cai 		printf("name%d: %s\n", index, gOpts.loader[index].name);
120178884ef4SEddie Cai 	}
120278884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
120378884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
120478884ef4SEddie Cai 			return false;
120578884ef4SEddie Cai 		}
120678884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
120778884ef4SEddie Cai 				!= 2)
120878884ef4SEddie Cai 			return false;
120978884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
121078884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
121178884ef4SEddie Cai 				fixPath(buf2);
121278884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
121378884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
121478884ef4SEddie Cai 				break;
121578884ef4SEddie Cai 			}
121678884ef4SEddie Cai 		}
121778884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
121878884ef4SEddie Cai 			return false;
121978884ef4SEddie Cai 		}
122078884ef4SEddie Cai 	}
122178884ef4SEddie Cai 	return true;
122278884ef4SEddie Cai }
122378884ef4SEddie Cai 
122478884ef4SEddie Cai static bool parseOut(FILE* file) {
122578884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
122678884ef4SEddie Cai 		return false;
122778884ef4SEddie Cai 	}
122878884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
122978884ef4SEddie Cai 		return false;
123078884ef4SEddie Cai 	fixPath(gOpts.outPath);
123178884ef4SEddie Cai 	printf("out: %s\n", gOpts.outPath);
123278884ef4SEddie Cai 	return true;
123378884ef4SEddie Cai }
123478884ef4SEddie Cai 
123578884ef4SEddie Cai 
123678884ef4SEddie Cai void printOpts(FILE* out) {
123778884ef4SEddie Cai 	int i;
123878884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
123978884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
124078884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
124178884ef4SEddie Cai 
124278884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
124378884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
124478884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
124578884ef4SEddie Cai 	}
124678884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
124778884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
124878884ef4SEddie Cai 
124978884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
125078884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
125178884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
125278884ef4SEddie Cai 	}
125378884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
125478884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
125578884ef4SEddie Cai 
125678884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
125778884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
125878884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
125978884ef4SEddie Cai 	}
126078884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
126178884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
126278884ef4SEddie Cai 	}
126378884ef4SEddie Cai 
126478884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
126578884ef4SEddie Cai }
126678884ef4SEddie Cai 
126778884ef4SEddie Cai static bool parseOpts(void) {
126878884ef4SEddie Cai 	bool ret = false;
126978884ef4SEddie Cai 	bool chipOk = false;
127078884ef4SEddie Cai 	bool versionOk = false;
127178884ef4SEddie Cai 	bool code471Ok = true;
127278884ef4SEddie Cai 	bool code472Ok = true;
127378884ef4SEddie Cai 	bool loaderOk = false;
127478884ef4SEddie Cai 	bool outOk = false;
127578884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
127678884ef4SEddie Cai 
127778884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
127878884ef4SEddie Cai 	FILE* file;
127978884ef4SEddie Cai 	file = fopen(configPath, "r");
128078884ef4SEddie Cai 	if (!file) {
128178884ef4SEddie Cai 		fprintf(stderr, "config (%s) not found!\n", configPath);
128208c0d218SKlaus Goger 		if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) {
128378884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
128478884ef4SEddie Cai 			if (file) {
128532268622SAndreas Färber 				fprintf(stderr, "creating defconfig\n");
128678884ef4SEddie Cai 				printOpts(file);
128778884ef4SEddie Cai 			}
128878884ef4SEddie Cai 		}
128978884ef4SEddie Cai 		goto end;
129078884ef4SEddie Cai 	}
129178884ef4SEddie Cai 
129232268622SAndreas Färber 	printf("Starting to parse...\n");
129378884ef4SEddie Cai 
129478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
129578884ef4SEddie Cai 		goto end;
129678884ef4SEddie Cai 	}
129778884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
129878884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
129978884ef4SEddie Cai 			chipOk = parseChip(file);
130078884ef4SEddie Cai 			if (!chipOk) {
130178884ef4SEddie Cai 				printf("parseChip failed!\n");
130278884ef4SEddie Cai 				goto end;
130378884ef4SEddie Cai 			}
130478884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
130578884ef4SEddie Cai 			versionOk = parseVersion(file);
130678884ef4SEddie Cai 			if (!versionOk) {
130778884ef4SEddie Cai 				printf("parseVersion failed!\n");
130878884ef4SEddie Cai 				goto end;
130978884ef4SEddie Cai 			}
131078884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
131178884ef4SEddie Cai 			code471Ok = parse471(file);
131278884ef4SEddie Cai 			if (!code471Ok) {
131378884ef4SEddie Cai 				printf("parse471 failed!\n");
131478884ef4SEddie Cai 				goto end;
131578884ef4SEddie Cai 			}
131678884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
131778884ef4SEddie Cai 			code472Ok = parse472(file);
131878884ef4SEddie Cai 			if (!code472Ok) {
131978884ef4SEddie Cai 				printf("parse472 failed!\n");
132078884ef4SEddie Cai 				goto end;
132178884ef4SEddie Cai 			}
132278884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
132378884ef4SEddie Cai 			loaderOk = parseLoader(file);
132478884ef4SEddie Cai 			if (!loaderOk) {
132578884ef4SEddie Cai 				printf("parseLoader failed!\n");
132678884ef4SEddie Cai 				goto end;
132778884ef4SEddie Cai 			}
132878884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
132978884ef4SEddie Cai 			outOk = parseOut(file);
133078884ef4SEddie Cai 			if (!outOk) {
133178884ef4SEddie Cai 				printf("parseOut failed!\n");
133278884ef4SEddie Cai 				goto end;
133378884ef4SEddie Cai 			}
133478884ef4SEddie Cai 		} else if (buf[0] == '#') {
133578884ef4SEddie Cai 			continue;
133678884ef4SEddie Cai 		} else {
133778884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
133878884ef4SEddie Cai 			goto end;
133978884ef4SEddie Cai 		}
134078884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
134178884ef4SEddie Cai 			goto end;
134278884ef4SEddie Cai 		}
134378884ef4SEddie Cai 	}
134478884ef4SEddie Cai 
134578884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
134678884ef4SEddie Cai 			&& loaderOk && outOk)
134778884ef4SEddie Cai 		ret = true;
134878884ef4SEddie Cai end:
134978884ef4SEddie Cai 	if (file)
135078884ef4SEddie Cai 		fclose(file);
135178884ef4SEddie Cai 	return ret;
135278884ef4SEddie Cai }
135378884ef4SEddie Cai 
135478884ef4SEddie Cai bool initOpts(void) {
135578884ef4SEddie Cai 	//set default opts
135678884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
135778884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
135878884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
135978884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
136078884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
136178884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
136278884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
136378884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
136478884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
136578884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
136678884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
136778884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
136878884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
136978884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
137078884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
137178884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
137278884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
137378884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
137478884ef4SEddie Cai 
137578884ef4SEddie Cai 	return parseOpts();
137678884ef4SEddie Cai }
137778884ef4SEddie Cai 
137878884ef4SEddie Cai /************merge code****************/
137978884ef4SEddie Cai 
138078884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
138178884ef4SEddie Cai 	uint8_t tmp[2] = {0};
138278884ef4SEddie Cai 	int i;
138378884ef4SEddie Cai 	uint32_t ret;
138478884ef4SEddie Cai 	//if (value > 0xFFFF) {
138578884ef4SEddie Cai 	//	return 0;
138678884ef4SEddie Cai 	//}
138778884ef4SEddie Cai 	for(i=0; i < 2; i++) {
138878884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
138978884ef4SEddie Cai 		value /= 100;
139078884ef4SEddie Cai 	}
139178884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
139278884ef4SEddie Cai 
139378884ef4SEddie Cai 	printf("ret: %x\n",ret);
139478884ef4SEddie Cai 	return ret&0xFF;
139578884ef4SEddie Cai }
139678884ef4SEddie Cai 
139778884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
139878884ef4SEddie Cai {
139978884ef4SEddie Cai 	int i;
140078884ef4SEddie Cai 	for (i = 0; i < len; i++) {
140178884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
140278884ef4SEddie Cai 	}
140378884ef4SEddie Cai 	wide[len] = 0;
140478884ef4SEddie Cai }
140578884ef4SEddie Cai 
140678884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
140778884ef4SEddie Cai 	char* end;
140878884ef4SEddie Cai 	char* start;
140978884ef4SEddie Cai 	int len;
141078884ef4SEddie Cai 	if (!path || !dst)
141178884ef4SEddie Cai 		return;
141278884ef4SEddie Cai 	start = strrchr(path, '/');
141378884ef4SEddie Cai 	if (!start)
141478884ef4SEddie Cai 		start = path;
141578884ef4SEddie Cai 	else
141678884ef4SEddie Cai 		start++;
141778884ef4SEddie Cai 	end = strrchr(path, '.');
1418641cfa16SEddie Cai 	if (!end || (end < start))
141978884ef4SEddie Cai 		end = path + strlen(path);
142078884ef4SEddie Cai 	len = end - start;
142178884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
142278884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
142378884ef4SEddie Cai 	str2wide(start, dst, len);
142478884ef4SEddie Cai 
142578884ef4SEddie Cai 
142678884ef4SEddie Cai 		char name[MAX_NAME_LEN];
142778884ef4SEddie Cai 		memset(name, 0, sizeof(name));
142878884ef4SEddie Cai 		memcpy(name, start, len);
142978884ef4SEddie Cai 		printf("path: %s, name: %s\n", path, name);
143078884ef4SEddie Cai 
143178884ef4SEddie Cai }
143278884ef4SEddie Cai 
143378884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
143478884ef4SEddie Cai 	struct stat st;
143578884ef4SEddie Cai 	if(stat(path, &st) < 0)
143678884ef4SEddie Cai 		return false;
143778884ef4SEddie Cai 	*size = st.st_size;
143878884ef4SEddie Cai 	printf("path: %s, size: %d\n", path, *size);
143978884ef4SEddie Cai 	return true;
144078884ef4SEddie Cai }
144178884ef4SEddie Cai 
144278884ef4SEddie Cai static inline rk_time getTime(void) {
144378884ef4SEddie Cai 	rk_time rkTime;
144478884ef4SEddie Cai 
144578884ef4SEddie Cai 	struct tm *tm;
144678884ef4SEddie Cai 	time_t tt = time(NULL);
144778884ef4SEddie Cai 	tm = localtime(&tt);
144878884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
144978884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
145078884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
145178884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
145278884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
145378884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
145478884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
145578884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
145678884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
145778884ef4SEddie Cai 	return rkTime;
145878884ef4SEddie Cai }
145978884ef4SEddie Cai 
146078884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
146178884ef4SEddie Cai 	bool ret = false;
146278884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
146378884ef4SEddie Cai 	uint8_t* buf;
146478884ef4SEddie Cai 
146578884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
146678884ef4SEddie Cai 	if (!inFile)
146778884ef4SEddie Cai 		goto end;
146878884ef4SEddie Cai 
146978884ef4SEddie Cai 	if (!getFileSize(path, &size))
147078884ef4SEddie Cai 		goto end;
147178884ef4SEddie Cai 	if (fix) {
147278884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
147378884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
147478884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
147578884ef4SEddie Cai 		fixSize +=tmp;
147678884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
147778884ef4SEddie Cai 	} else {
147878884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
147978884ef4SEddie Cai 	}
148078884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
148178884ef4SEddie Cai 		goto end;
148278884ef4SEddie Cai 
148378884ef4SEddie Cai 	if (fix) {
148478884ef4SEddie Cai 
148578884ef4SEddie Cai 		buf = gBuf;
148678884ef4SEddie Cai 		size = fixSize;
148778884ef4SEddie Cai 		while(1) {
148878884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
148978884ef4SEddie Cai 			buf += SMALL_PACKET;
149078884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
149178884ef4SEddie Cai 				break;
149278884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
149378884ef4SEddie Cai 		}
149478884ef4SEddie Cai 	} else {
149578884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
149678884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
149778884ef4SEddie Cai 		size +=tmp;
149878884ef4SEddie Cai 		P_RC4(gBuf, size);
149978884ef4SEddie Cai 	}
150078884ef4SEddie Cai 
150178884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
150278884ef4SEddie Cai 		goto end;
150378884ef4SEddie Cai 	ret = true;
150478884ef4SEddie Cai end:
150578884ef4SEddie Cai 	if (inFile)
150678884ef4SEddie Cai 		fclose(inFile);
150778884ef4SEddie Cai 	if (!ret)
150832268622SAndreas Färber 		printf("writing entry (%s) failed\n", path);
150978884ef4SEddie Cai 	return ret;
151078884ef4SEddie Cai }
151178884ef4SEddie Cai 
151278884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
151378884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
151478884ef4SEddie Cai 	uint32_t size;
151578884ef4SEddie Cai 	rk_boot_entry entry;
151678884ef4SEddie Cai 
151732268622SAndreas Färber 	printf("writing: %s\n", path);
1518641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
151978884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
152078884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
152178884ef4SEddie Cai 	entry.type = type;
152278884ef4SEddie Cai 	entry.dataOffset = *offset;
152378884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
152432268622SAndreas Färber 		printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
152578884ef4SEddie Cai 		return false;
152678884ef4SEddie Cai 	}
152778884ef4SEddie Cai 	if (fix)
152878884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
152978884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
153078884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
153132268622SAndreas Färber 	printf("alignment size: %d\n", size);
153278884ef4SEddie Cai 	entry.dataSize = size;
153378884ef4SEddie Cai 	entry.dataDelay = delay;
153478884ef4SEddie Cai 	*offset += size;
153578884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
153678884ef4SEddie Cai 	return true;
153778884ef4SEddie Cai }
153878884ef4SEddie Cai 
153978884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
154078884ef4SEddie Cai 	char buffer[5];
154178884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
154278884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
154378884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
154478884ef4SEddie Cai }
154578884ef4SEddie Cai 
154678884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
154778884ef4SEddie Cai 	printf("chip: %s\n", chip);
154878884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
154978884ef4SEddie Cai 	if(!chip) {
155078884ef4SEddie Cai 		goto end;
155178884ef4SEddie Cai 	}
155278884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
155378884ef4SEddie Cai 		chipType = RK28_DEVICE;
155478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
155578884ef4SEddie Cai 		chipType = RK28_DEVICE;
155678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
155778884ef4SEddie Cai 		chipType = RK281X_DEVICE;
155878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
155978884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
156078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
156178884ef4SEddie Cai 		chipType = RK27_DEVICE;
156278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
156378884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
156478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
156578884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
156678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
156778884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
156878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
156978884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
157078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
157178884ef4SEddie Cai 		chipType = RK29_DEVICE;
157278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
157378884ef4SEddie Cai 		chipType = RK292X_DEVICE;
157478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
157578884ef4SEddie Cai 		chipType = RK30_DEVICE;
157678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
157778884ef4SEddie Cai 		chipType = RK30B_DEVICE;
157878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
157978884ef4SEddie Cai 		chipType = RK31_DEVICE;
158078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
158178884ef4SEddie Cai 		chipType = RK32_DEVICE;
158278884ef4SEddie Cai 	} else {
158378884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
158478884ef4SEddie Cai 	}
158578884ef4SEddie Cai 
158678884ef4SEddie Cai end:
158778884ef4SEddie Cai 	printf("type: 0x%x\n", chipType);
158878884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
158932268622SAndreas Färber 		printf("chip type not supported!\n");
159078884ef4SEddie Cai 	}
159178884ef4SEddie Cai 	return chipType;
159278884ef4SEddie Cai }
159378884ef4SEddie Cai 
159478884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
159578884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
159678884ef4SEddie Cai 	hdr->tag = TAG;
159778884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
159878884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
159978884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
160078884ef4SEddie Cai 	hdr->releaseTime = getTime();
160178884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
160278884ef4SEddie Cai 
160378884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
160478884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
160578884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
160678884ef4SEddie Cai 
160778884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
160878884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
160978884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
161078884ef4SEddie Cai 
161178884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
161278884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
161378884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
161478884ef4SEddie Cai #ifndef USE_P_RC4
161578884ef4SEddie Cai 	hdr->rc4Flag = 1;
161678884ef4SEddie Cai #endif
161778884ef4SEddie Cai }
161878884ef4SEddie Cai 
161978884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
162078884ef4SEddie Cai 	uint32_t size = 0;
162178884ef4SEddie Cai 	uint32_t crc = 0;
162278884ef4SEddie Cai 
162378884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
162478884ef4SEddie Cai 	getFileSize(path, &size);
162578884ef4SEddie Cai 	if (!file)
162678884ef4SEddie Cai 		goto end;
162778884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
162878884ef4SEddie Cai 		goto end;
162978884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
163078884ef4SEddie Cai 	printf("crc: 0x%08x\n", crc);
163178884ef4SEddie Cai end:
163278884ef4SEddie Cai 	if (file)
163378884ef4SEddie Cai 		fclose(file);
163478884ef4SEddie Cai 	return crc;
163578884ef4SEddie Cai }
163678884ef4SEddie Cai 
163778884ef4SEddie Cai bool mergeBoot(void) {
163878884ef4SEddie Cai 	uint32_t dataOffset;
163978884ef4SEddie Cai 	bool ret = false;
164078884ef4SEddie Cai 	int i;
164178884ef4SEddie Cai 	FILE* outFile;
164278884ef4SEddie Cai 	uint32_t crc;
164378884ef4SEddie Cai 	rk_boot_header hdr;
164478884ef4SEddie Cai 
164578884ef4SEddie Cai 	if (!initOpts())
164678884ef4SEddie Cai 		return false;
164778884ef4SEddie Cai 	{
164878884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
164978884ef4SEddie Cai 		char version[MAX_LINE_LEN];
165078884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
165178884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
165278884ef4SEddie Cai 			subfix[0] = '\0';
165378884ef4SEddie Cai 		}
165478884ef4SEddie Cai 		strcat(gOpts.outPath, version);
165578884ef4SEddie Cai 		printf("fix opt: %s\n", gOpts.outPath);
165678884ef4SEddie Cai 	}
165778884ef4SEddie Cai 
165878884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
165978884ef4SEddie Cai 	printOpts(stdout);
166078884ef4SEddie Cai 	printf("---------------\n\n");
166178884ef4SEddie Cai 
166278884ef4SEddie Cai 
166378884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
166478884ef4SEddie Cai 	if (!outFile) {
166532268622SAndreas Färber 		printf("Opening output file (%s) failed\n", gOpts.outPath);
166678884ef4SEddie Cai 		goto end;
166778884ef4SEddie Cai 	}
166878884ef4SEddie Cai 
166978884ef4SEddie Cai 	getBoothdr(&hdr);
167032268622SAndreas Färber 	printf("Writing header...\n");
167178884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
167278884ef4SEddie Cai 
167378884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
167478884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
167578884ef4SEddie Cai 		sizeof(rk_boot_entry);
167678884ef4SEddie Cai 
167732268622SAndreas Färber 	printf("Writing code 471 entry...\n");
167878884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
167978884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
168078884ef4SEddie Cai 					&dataOffset, NULL, false))
168178884ef4SEddie Cai 			goto end;
168278884ef4SEddie Cai 	}
168332268622SAndreas Färber 	printf("Writing code 472 entry...\n");
168478884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
168578884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
168678884ef4SEddie Cai 					&dataOffset, NULL, false))
168778884ef4SEddie Cai 			goto end;
168878884ef4SEddie Cai 	}
168932268622SAndreas Färber 	printf("Writing loader entry...\n");
169078884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
169178884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
169278884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
169378884ef4SEddie Cai 			goto end;
169478884ef4SEddie Cai 	}
169578884ef4SEddie Cai 
169632268622SAndreas Färber 	printf("Writing code 471...\n");
169778884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
169878884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
169978884ef4SEddie Cai 			goto end;
170078884ef4SEddie Cai 	}
170132268622SAndreas Färber 	printf("Writing code 472...\n");
170278884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
170378884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
170478884ef4SEddie Cai 			goto end;
170578884ef4SEddie Cai 	}
170632268622SAndreas Färber 	printf("Writing loader...\n");
170778884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
170878884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
170978884ef4SEddie Cai 			goto end;
171078884ef4SEddie Cai 	}
171178884ef4SEddie Cai 	fflush(outFile);
171278884ef4SEddie Cai 
171332268622SAndreas Färber 	printf("Writing crc...\n");
171478884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
171578884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
171678884ef4SEddie Cai 		goto end;
171732268622SAndreas Färber 	printf("Done.\n");
171878884ef4SEddie Cai 	ret = true;
171978884ef4SEddie Cai end:
172078884ef4SEddie Cai 	if (outFile)
172178884ef4SEddie Cai 		fclose(outFile);
172278884ef4SEddie Cai 	return ret;
172378884ef4SEddie Cai }
172478884ef4SEddie Cai 
172578884ef4SEddie Cai /************merge code end************/
172678884ef4SEddie Cai /************unpack code***************/
172778884ef4SEddie Cai 
172878884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
172978884ef4SEddie Cai {
173078884ef4SEddie Cai 	int i;
173178884ef4SEddie Cai 	for (i = 0; i < len; i++) {
173278884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
173378884ef4SEddie Cai 	}
173478884ef4SEddie Cai 	str[len] = 0;
173578884ef4SEddie Cai }
173678884ef4SEddie Cai 
173778884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
173878884ef4SEddie Cai 		FILE* inFile) {
173978884ef4SEddie Cai 	bool ret = false;
174078884ef4SEddie Cai 	int size, i;
174178884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
174278884ef4SEddie Cai 	if (!outFile)
174378884ef4SEddie Cai 		goto end;
174432268622SAndreas Färber 	printf("unpacking entry (%s)\n", name);
174578884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
174678884ef4SEddie Cai 	size = entry->dataSize;
174778884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
174878884ef4SEddie Cai 		goto end;
174978884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
175078884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
175178884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
175278884ef4SEddie Cai 		if (size % SMALL_PACKET)
175378884ef4SEddie Cai 		{
175478884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
175578884ef4SEddie Cai 		}
175678884ef4SEddie Cai 	} else {
175778884ef4SEddie Cai 		P_RC4(gBuf, size);
175878884ef4SEddie Cai 	}
175978884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
176078884ef4SEddie Cai 		goto end;
176178884ef4SEddie Cai 	ret = true;
176278884ef4SEddie Cai end:
176378884ef4SEddie Cai 	if (outFile)
176478884ef4SEddie Cai 		fclose(outFile);
176578884ef4SEddie Cai 	return ret;
176678884ef4SEddie Cai }
176778884ef4SEddie Cai 
176878884ef4SEddie Cai bool unpackBoot(char* path) {
176978884ef4SEddie Cai 	bool ret = false;
177078884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
177178884ef4SEddie Cai 	int entryNum, i;
177278884ef4SEddie Cai 	char name[MAX_NAME_LEN];
177378884ef4SEddie Cai 	rk_boot_entry* entrys;
177478884ef4SEddie Cai 	if (!inFile) {
177578884ef4SEddie Cai 		fprintf(stderr, "loader (%s) not found\n", path);
177678884ef4SEddie Cai 		goto end;
177778884ef4SEddie Cai 	}
177878884ef4SEddie Cai 
177978884ef4SEddie Cai 	rk_boot_header hdr;
178078884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
178132268622SAndreas Färber 		fprintf(stderr, "reading header failed\n");
178278884ef4SEddie Cai 		goto end;
178378884ef4SEddie Cai 	}
178478884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
178578884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
178678884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
178778884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
178832268622SAndreas Färber 		fprintf(stderr, "reading data failed\n");
178978884ef4SEddie Cai 		goto end;
179078884ef4SEddie Cai 	}
179178884ef4SEddie Cai 
179278884ef4SEddie Cai 	printf("entry num: %d\n", entryNum);
179378884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
179478884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
179578884ef4SEddie Cai 
179678884ef4SEddie Cai 		printf("entry: t=%d, name=%s, off=%d, size=%d\n",
179778884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
179878884ef4SEddie Cai 				entrys[i].dataSize);
179978884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
180032268622SAndreas Färber 			fprintf(stderr, "unpacking entry (%s) failed\n", name);
180178884ef4SEddie Cai 			goto end;
180278884ef4SEddie Cai 		}
180378884ef4SEddie Cai 	}
180478884ef4SEddie Cai 	printf("done\n");
180578884ef4SEddie Cai 	ret = true;
180678884ef4SEddie Cai end:
180778884ef4SEddie Cai 	if (inFile)
180878884ef4SEddie Cai 		fclose(inFile);
180978884ef4SEddie Cai 	return ret;
181078884ef4SEddie Cai }
181178884ef4SEddie Cai 
181276af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
181376af099aSliuyi {
181476af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
181576af099aSliuyi 		return false;
181676af099aSliuyi 	CRKImage *pImage = NULL;
181776af099aSliuyi 	CRKBoot *pBoot = NULL;
181876af099aSliuyi 	bool bRet, bSuccess = false;
181976af099aSliuyi 	int iRet;
182076af099aSliuyi 
182176af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
182276af099aSliuyi 	if (!bRet){
182376af099aSliuyi 		ERROR_COLOR_ATTR;
182432268622SAndreas Färber 		printf("Opening loader failed, exiting download boot!");
182576af099aSliuyi 		NORMAL_COLOR_ATTR;
182676af099aSliuyi 		printf("\r\n");
182776af099aSliuyi 		return bSuccess;
182876af099aSliuyi 	} else {
182976af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
183076af099aSliuyi 		CRKComm *pComm = NULL;
183176af099aSliuyi 		CRKDevice *pDevice = NULL;
183276af099aSliuyi 
183376af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
183476af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
183576af099aSliuyi 		if (!bRet) {
183676af099aSliuyi 			if (pImage)
183776af099aSliuyi 				delete pImage;
183876af099aSliuyi 			ERROR_COLOR_ATTR;
183976af099aSliuyi 			printf("Creating Comm Object failed!");
184076af099aSliuyi 			NORMAL_COLOR_ATTR;
184176af099aSliuyi 			printf("\r\n");
184276af099aSliuyi 			return bSuccess;
184376af099aSliuyi 		}
184476af099aSliuyi 
184576af099aSliuyi 		pDevice = new CRKDevice(dev);
184676af099aSliuyi 		if (!pDevice) {
184776af099aSliuyi 			if (pImage)
184876af099aSliuyi 				delete pImage;
184976af099aSliuyi 			if (pComm)
185076af099aSliuyi 				delete pComm;
185176af099aSliuyi 			ERROR_COLOR_ATTR;
185276af099aSliuyi 			printf("Creating device object failed!");
185376af099aSliuyi 			NORMAL_COLOR_ATTR;
185476af099aSliuyi 			printf("\r\n");
185576af099aSliuyi 			return bSuccess;
185676af099aSliuyi 		}
185776af099aSliuyi 
185876af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
185932268622SAndreas Färber 		printf("Downloading bootloader...\r\n");
186076af099aSliuyi 		iRet = pDevice->DownloadBoot();
186176af099aSliuyi 
186276af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
186376af099aSliuyi 		CURSOR_DEL_LINE;
186476af099aSliuyi 		if (iRet == 0) {
186576af099aSliuyi 			bSuccess = true;
186632268622SAndreas Färber 			printf("Downloading bootloader succeeded.\r\n");
186776af099aSliuyi 		}
186876af099aSliuyi 		else
186932268622SAndreas Färber 			printf("Downloading bootloader failed!\r\n");
187076af099aSliuyi 
187176af099aSliuyi 		if (pImage)
187276af099aSliuyi 			delete pImage;
187376af099aSliuyi 		if(pDevice)
187476af099aSliuyi 			delete pDevice;
187576af099aSliuyi 	}
187676af099aSliuyi 	return bSuccess;
187776af099aSliuyi }
1878c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1879c30d921cSKever Yang {
1880c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1881c30d921cSKever Yang 		return false;
1882c30d921cSKever Yang 	CRKImage *pImage = NULL;
1883c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1884c30d921cSKever Yang 	CRKComm *pComm = NULL;
1885c30d921cSKever Yang 	bool bRet, bSuccess = false;
1886c30d921cSKever Yang 	int iRet;
1887c30d921cSKever Yang 	char index;
1888c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1889c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1890c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1891c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1892c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1893c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1894c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1895c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1896c30d921cSKever Yang 	if (!bRet){
1897c30d921cSKever Yang 		ERROR_COLOR_ATTR;
189832268622SAndreas Färber 		printf("Opening loader failed, exiting upgrade loader!");
1899c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1900c30d921cSKever Yang 		printf("\r\n");
1901c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1902c30d921cSKever Yang 	} else {
1903c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1904c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1905c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1906c30d921cSKever Yang 		if (!bRet) {
1907c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1908c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1909c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1910c30d921cSKever Yang 			printf("\r\n");
1911c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1912c30d921cSKever Yang 		}
1913c30d921cSKever Yang 
191432268622SAndreas Färber 		printf("Upgrading loader...\r\n");
1915c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1916c30d921cSKever Yang 		if (index == -1) {
1917c30d921cSKever Yang 			if (g_pLogObject) {
191832268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1919c30d921cSKever Yang 			}
1920c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1921c30d921cSKever Yang 		}
1922c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1923c30d921cSKever Yang 		if (!bRet) {
1924c30d921cSKever Yang 			if (g_pLogObject) {
192532268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1926c30d921cSKever Yang 			}
1927c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1928c30d921cSKever Yang 		}
1929c30d921cSKever Yang 
1930c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1931c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1932c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1933c30d921cSKever Yang 			if (g_pLogObject) {
193432268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1935c30d921cSKever Yang 			}
1936c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1937c30d921cSKever Yang 		}
1938c30d921cSKever Yang 
1939c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1940c30d921cSKever Yang 		if (index == -1) {
1941c30d921cSKever Yang 			if (g_pLogObject) {
194232268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1943c30d921cSKever Yang 			}
1944c30d921cSKever Yang 			delete []loaderCodeBuffer;
1945c30d921cSKever Yang 			return -4;
1946c30d921cSKever Yang 		}
1947c30d921cSKever Yang 
1948c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1949c30d921cSKever Yang 		if (!bRet) {
1950c30d921cSKever Yang 			if (g_pLogObject) {
195132268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1952c30d921cSKever Yang 			}
1953c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1954c30d921cSKever Yang 		}
1955c30d921cSKever Yang 
1956c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1957c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1958c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1959c30d921cSKever Yang 			if (g_pLogObject) {
196032268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1961c30d921cSKever Yang 			}
1962c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1963c30d921cSKever Yang 		}
1964c30d921cSKever Yang 
1965c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1966c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1967c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1968c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1969c30d921cSKever Yang 		if (!pIDBData) {
1970c30d921cSKever Yang 			ERROR_COLOR_ATTR;
197132268622SAndreas Färber 			printf("Allocating memory failed!");
1972c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1973c30d921cSKever Yang 			printf("\r\n");
1974c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1975c30d921cSKever Yang 		}
1976c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1977b38fe5fcSliuyi 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
1978c30d921cSKever Yang 		if (iRet != 0) {
1979c30d921cSKever Yang 			ERROR_COLOR_ATTR;
198032268622SAndreas Färber 			printf("Making idblock failed!");
1981c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1982c30d921cSKever Yang 			printf("\r\n");
1983c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1984c30d921cSKever Yang 		}
1985c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
1986c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
1987c30d921cSKever Yang 		CURSOR_DEL_LINE;
1988c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
1989b38fe5fcSliuyi 			//pComm->Reset_Usb_Device();
1990c30d921cSKever Yang 			bSuccess = true;
199132268622SAndreas Färber 			printf("Upgrading loader succeeded.\r\n");
1992c30d921cSKever Yang 		} else {
199332268622SAndreas Färber 			printf("Upgrading loader failed!\r\n");
1994c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1995c30d921cSKever Yang 		}
1996c30d921cSKever Yang 	}
1997c30d921cSKever Yang Exit_UpgradeLoader:
1998c30d921cSKever Yang 	if (pImage)
1999c30d921cSKever Yang 		delete pImage;
2000c30d921cSKever Yang 	if (pComm)
2001c30d921cSKever Yang 		delete pComm;
2002c30d921cSKever Yang 	if (loaderCodeBuffer)
2003c30d921cSKever Yang 		delete []loaderCodeBuffer;
2004c30d921cSKever Yang 	if (loaderDataBuffer)
2005c30d921cSKever Yang 		delete []loaderDataBuffer;
2006c30d921cSKever Yang 	if (pIDBData)
2007c30d921cSKever Yang 		delete []pIDBData;
2008c30d921cSKever Yang 	return bSuccess;
2009c30d921cSKever Yang }
20103dc7e3ceSliuyi bool print_gpt(STRUCT_RKDEVICE_DESC &dev)
20113dc7e3ceSliuyi {
20123dc7e3ceSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
20133dc7e3ceSliuyi 		return false;
20143dc7e3ceSliuyi 	u8 master_gpt[34 * SECTOR_SIZE];
20153dc7e3ceSliuyi 	gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE);
20163dc7e3ceSliuyi 	bool bRet, bSuccess = false;
20173dc7e3ceSliuyi 	int iRet;
20183dc7e3ceSliuyi 	gpt_entry  *gptEntry  = NULL;
20193dc7e3ceSliuyi 	u32 i,j;
20203dc7e3ceSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
20213dc7e3ceSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
20223dc7e3ceSliuyi 	CRKComm *pComm = NULL;
20233dc7e3ceSliuyi 	char partName[36];
20243dc7e3ceSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
20253dc7e3ceSliuyi 	if (!bRet) {
20263dc7e3ceSliuyi 		ERROR_COLOR_ATTR;
20273dc7e3ceSliuyi 		printf("Creating Comm Object failed!");
20283dc7e3ceSliuyi 		NORMAL_COLOR_ATTR;
20293dc7e3ceSliuyi 		printf("\r\n");
20303dc7e3ceSliuyi 		return bSuccess;
20313dc7e3ceSliuyi 	}
20323dc7e3ceSliuyi 	iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt);
20333dc7e3ceSliuyi 	if(ERR_SUCCESS == iRet) {
20343dc7e3ceSliuyi 		if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
20353dc7e3ceSliuyi 			goto Exit_PrintGpt;
20363dc7e3ceSliuyi 		}
20373dc7e3ceSliuyi 
20383dc7e3ceSliuyi 	} else {
20393dc7e3ceSliuyi 		if (g_pLogObject)
20403dc7e3ceSliuyi 				g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
20413dc7e3ceSliuyi 		printf("Read GPT failed!\r\n");
20423dc7e3ceSliuyi 		goto Exit_PrintGpt;
20433dc7e3ceSliuyi 	}
20443dc7e3ceSliuyi 
2045*081d237aSliuyi 	printf("**********Partition Info(GPT)**********\r\n");
20463dc7e3ceSliuyi 	printf("NO  LBA       Name                \r\n");
20473dc7e3ceSliuyi 	for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) {
20483dc7e3ceSliuyi 		gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
20493dc7e3ceSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
20503dc7e3ceSliuyi 			break;
20513dc7e3ceSliuyi 		memset(partName, 0 , 36);
20523dc7e3ceSliuyi 		j = 0;
20533dc7e3ceSliuyi 		while (gptEntry->partition_name[j]) {
20543dc7e3ceSliuyi 			partName[j] = (char)gptEntry->partition_name[j];
20553dc7e3ceSliuyi 			j++;
20563dc7e3ceSliuyi 		}
20573dc7e3ceSliuyi 		printf("%02d  %08X  %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName);
20583dc7e3ceSliuyi 	}
20593dc7e3ceSliuyi 	bSuccess = true;
20603dc7e3ceSliuyi Exit_PrintGpt:
20613dc7e3ceSliuyi 	if (pComm)
20623dc7e3ceSliuyi 		delete pComm;
20633dc7e3ceSliuyi 	return bSuccess;
20643dc7e3ceSliuyi }
2065*081d237aSliuyi bool print_parameter(STRUCT_RKDEVICE_DESC &dev)
2066*081d237aSliuyi {
2067*081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2068*081d237aSliuyi 		return false;
2069*081d237aSliuyi 	u8 param_buf[512 * SECTOR_SIZE];
2070*081d237aSliuyi 	bool bRet, bSuccess = false;
2071*081d237aSliuyi 	int iRet;
2072*081d237aSliuyi 	u32 i, nParamSize;
2073*081d237aSliuyi 	CRKComm *pComm = NULL;
2074*081d237aSliuyi 	PARAM_ITEM_VECTOR vecParamItem;
2075*081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuidItem;
2076*081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2077*081d237aSliuyi 	if (!bRet) {
2078*081d237aSliuyi 		ERROR_COLOR_ATTR;
2079*081d237aSliuyi 		printf("Creating Comm Object failed!");
2080*081d237aSliuyi 		NORMAL_COLOR_ATTR;
2081*081d237aSliuyi 		printf("\r\n");
2082*081d237aSliuyi 		return bSuccess;
2083*081d237aSliuyi 	}
2084*081d237aSliuyi 	iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf);
2085*081d237aSliuyi 	if(ERR_SUCCESS == iRet) {
2086*081d237aSliuyi 		if (*(u32 *)param_buf != 0x4D524150) {
2087*081d237aSliuyi 			goto Exit_PrintParam;
2088*081d237aSliuyi 		}
2089*081d237aSliuyi 
2090*081d237aSliuyi 	} else {
2091*081d237aSliuyi 		if (g_pLogObject)
2092*081d237aSliuyi 				g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2093*081d237aSliuyi 		printf("Read parameter failed!\r\n");
2094*081d237aSliuyi 		goto Exit_PrintParam;
2095*081d237aSliuyi 	}
2096*081d237aSliuyi 	nParamSize = *(u32 *)(param_buf + 4);
2097*081d237aSliuyi 	memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8);
2098*081d237aSliuyi 
2099*081d237aSliuyi 	bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem);
2100*081d237aSliuyi 	if (!bRet) {
2101*081d237aSliuyi 		if (g_pLogObject)
2102*081d237aSliuyi 				g_pLogObject->Record("Error: parse parameter failed");
2103*081d237aSliuyi 		printf("Parse parameter failed!\r\n");
2104*081d237aSliuyi 		goto Exit_PrintParam;
2105*081d237aSliuyi 	}
2106*081d237aSliuyi 	printf("**********Partition Info(parameter)**********\r\n");
2107*081d237aSliuyi 	printf("NO  LBA       Name                \r\n");
2108*081d237aSliuyi 	for (i = 0; i < vecParamItem.size(); i++) {
2109*081d237aSliuyi 		printf("%02d  %08X  %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName);
2110*081d237aSliuyi 	}
2111*081d237aSliuyi 	bSuccess = true;
2112*081d237aSliuyi Exit_PrintParam:
2113*081d237aSliuyi 	if (pComm)
2114*081d237aSliuyi 		delete pComm;
2115*081d237aSliuyi 	return bSuccess;
2116*081d237aSliuyi }
2117c30d921cSKever Yang 
211876af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
211976af099aSliuyi {
212076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
212176af099aSliuyi 		return false;
212276af099aSliuyi 	CRKImage *pImage = NULL;
212376af099aSliuyi 	bool bRet, bSuccess = false;
212476af099aSliuyi 	int iRet;
212576af099aSliuyi 	CRKScan *pScan = NULL;
212676af099aSliuyi 	pScan = new CRKScan();
212776af099aSliuyi 	pScan->SetVidPid();
212876af099aSliuyi 
212976af099aSliuyi 	CRKComm *pComm = NULL;
213076af099aSliuyi 	CRKDevice *pDevice = NULL;
213176af099aSliuyi 
213276af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
213376af099aSliuyi 	if (!bRet) {
213476af099aSliuyi 		if (pScan)
213576af099aSliuyi 			delete pScan;
213676af099aSliuyi 		ERROR_COLOR_ATTR;
213776af099aSliuyi 		printf("Creating Comm Object failed!");
213876af099aSliuyi 		NORMAL_COLOR_ATTR;
213976af099aSliuyi 		printf("\r\n");
214076af099aSliuyi 		return bSuccess;
214176af099aSliuyi 	}
214276af099aSliuyi 
214376af099aSliuyi 	pDevice = new CRKDevice(dev);
214476af099aSliuyi 	if (!pDevice) {
214576af099aSliuyi 		if (pComm)
214676af099aSliuyi 			delete pComm;
214776af099aSliuyi 		if (pScan)
214876af099aSliuyi 			delete pScan;
214976af099aSliuyi 		ERROR_COLOR_ATTR;
215076af099aSliuyi 		printf("Creating device object failed!");
215176af099aSliuyi 		NORMAL_COLOR_ATTR;
215276af099aSliuyi 		printf("\r\n");
215376af099aSliuyi 		return bSuccess;
215476af099aSliuyi 	}
215576af099aSliuyi 
215676af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
215776af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
215876af099aSliuyi 
215932268622SAndreas Färber 	printf("Starting to erase flash...\r\n");
21606502326dSliuyi 	bRet = pDevice->GetFlashInfo();
21616502326dSliuyi 	if (!bRet) {
21626502326dSliuyi 		if (pDevice)
21636502326dSliuyi 			delete pDevice;
21646502326dSliuyi 		if (pScan)
21656502326dSliuyi 			delete pScan;
21666502326dSliuyi 		ERROR_COLOR_ATTR;
21676502326dSliuyi 		printf("Getting flash info from device failed!");
21686502326dSliuyi 		NORMAL_COLOR_ATTR;
21696502326dSliuyi 		printf("\r\n");
21706502326dSliuyi 		return bSuccess;
21716502326dSliuyi 	}
217276af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
217376af099aSliuyi 	if (pDevice)
217476af099aSliuyi 		delete pDevice;
217576af099aSliuyi 
217676af099aSliuyi 	if (iRet == 0) {
217776af099aSliuyi 		if (pScan) {
217876af099aSliuyi 			pScan->SetVidPid();
217976af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
218076af099aSliuyi 			delete pScan;
218176af099aSliuyi 		}
218276af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
218376af099aSliuyi 		CURSOR_DEL_LINE;
218476af099aSliuyi 		bSuccess = true;
218532268622SAndreas Färber 		printf("Erasing flash complete.\r\n");
218676af099aSliuyi 	}
218776af099aSliuyi 
218876af099aSliuyi 	return bSuccess;
218976af099aSliuyi }
219076af099aSliuyi 
219176af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
219276af099aSliuyi {
219376af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
219476af099aSliuyi 		return false;
219576af099aSliuyi 	CRKUsbComm *pComm = NULL;
219676af099aSliuyi 	bool bRet, bSuccess = false;
219776af099aSliuyi 	int iRet;
219876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
219976af099aSliuyi 	if (bRet) {
220076af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
220176af099aSliuyi 		if (iRet != ERR_SUCCESS) {
220276af099aSliuyi 			if (g_pLogObject)
220376af099aSliuyi 				g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
220432268622SAndreas Färber 			printf("Test Device failed!\r\n");
220576af099aSliuyi 		} else {
220676af099aSliuyi 			bSuccess = true;
220776af099aSliuyi 			printf("Test Device OK.\r\n");
220876af099aSliuyi 		}
220976af099aSliuyi 	} else {
221032268622SAndreas Färber 		printf("Test Device quit, creating comm object failed!\r\n");
221176af099aSliuyi 	}
221276af099aSliuyi 	if (pComm) {
221376af099aSliuyi 		delete pComm;
221476af099aSliuyi 		pComm = NULL;
221576af099aSliuyi 	}
221676af099aSliuyi 	return bSuccess;
221776af099aSliuyi }
221876af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
221976af099aSliuyi {
222076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
222176af099aSliuyi 		return false;
222276af099aSliuyi 	CRKUsbComm *pComm = NULL;
222376af099aSliuyi 	bool bRet, bSuccess = false;
222476af099aSliuyi 	int iRet;
222576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
222676af099aSliuyi 	if (bRet) {
222776af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
222876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
222976af099aSliuyi 			if (g_pLogObject)
223076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
223132268622SAndreas Färber 			printf("Reset Device failed!\r\n");
223276af099aSliuyi 		} else {
223376af099aSliuyi 			bSuccess = true;
223476af099aSliuyi 			printf("Reset Device OK.\r\n");
223576af099aSliuyi 		}
223676af099aSliuyi 	} else {
223732268622SAndreas Färber 		printf("Reset Device quit, creating comm object failed!\r\n");
223876af099aSliuyi 	}
223976af099aSliuyi 	if (pComm) {
224076af099aSliuyi 		delete pComm;
224176af099aSliuyi 		pComm = NULL;
224276af099aSliuyi 	}
224376af099aSliuyi 	return bSuccess;
224476af099aSliuyi }
224576af099aSliuyi 
224676af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
224776af099aSliuyi {
224876af099aSliuyi 	CRKUsbComm *pComm = NULL;
224976af099aSliuyi 	bool bRet, bSuccess = false;
225076af099aSliuyi 	int iRet;
225176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
225276af099aSliuyi 		return bSuccess;
225376af099aSliuyi 
225476af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
225576af099aSliuyi 	if (bRet) {
225676af099aSliuyi 		BYTE flashID[5];
225776af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
225876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
225976af099aSliuyi 			if (g_pLogObject)
226076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
226132268622SAndreas Färber 			printf("Reading flash ID failed!\r\n");
226276af099aSliuyi 		} else {
226376af099aSliuyi 			printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
226476af099aSliuyi 			bSuccess = true;
226576af099aSliuyi 		}
226676af099aSliuyi 	} else {
226732268622SAndreas Färber 		printf("Read Flash ID quit, creating comm object failed!\r\n");
226876af099aSliuyi 	}
226976af099aSliuyi 	if (pComm) {
227076af099aSliuyi 		delete pComm;
227176af099aSliuyi 		pComm = NULL;
227276af099aSliuyi 	}
227376af099aSliuyi 	return bSuccess;
227476af099aSliuyi }
227576af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
227676af099aSliuyi {
227776af099aSliuyi 	CRKUsbComm *pComm = NULL;
227876af099aSliuyi 	bool bRet, bSuccess = false;
227976af099aSliuyi 	int iRet;
228076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
228176af099aSliuyi 		return bSuccess;
228276af099aSliuyi 
228376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
228476af099aSliuyi 	if (bRet) {
228576af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
228676af099aSliuyi 		UINT uiRead;
228776af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
228876af099aSliuyi 		if (iRet != ERR_SUCCESS) {
228976af099aSliuyi 			if (g_pLogObject)
229076af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
229132268622SAndreas Färber 			printf("Read Flash Info failed!\r\n");
229276af099aSliuyi 		} else {
229376af099aSliuyi 			printf("Flash Info:\r\n");
229476af099aSliuyi 			if (info.bManufCode <= 7) {
229576af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
229676af099aSliuyi 			}
229776af099aSliuyi 			else
229876af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
229976af099aSliuyi 
230076af099aSliuyi 			printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
230176af099aSliuyi 			printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
230276af099aSliuyi 			printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
230376af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
230476af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
230576af099aSliuyi 			printf("\tFlash CS: ");
230676af099aSliuyi 			for(int i = 0; i < 8; i++) {
230776af099aSliuyi 				if( info.bFlashCS & (1 << i) )
230876af099aSliuyi 					printf("Flash<%d> ", i);
230976af099aSliuyi 			}
231076af099aSliuyi 			printf("\r\n");
231176af099aSliuyi 			bSuccess = true;
231276af099aSliuyi 		}
231376af099aSliuyi 	}else {
231432268622SAndreas Färber 		printf("Read Flash Info quit, creating comm object failed!\r\n");
231576af099aSliuyi 	}
231676af099aSliuyi 	if (pComm) {
231776af099aSliuyi 		delete pComm;
231876af099aSliuyi 		pComm = NULL;
231976af099aSliuyi 	}
232076af099aSliuyi 	return bSuccess;
232176af099aSliuyi }
232276af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
232376af099aSliuyi {
232476af099aSliuyi 	CRKUsbComm *pComm = NULL;
232576af099aSliuyi 	bool bRet, bSuccess = false;
232676af099aSliuyi 	int iRet;
232776af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
232876af099aSliuyi 		return bSuccess;
232976af099aSliuyi 
233076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
233176af099aSliuyi 	if (bRet) {
233276af099aSliuyi 		BYTE chipInfo[16];
233376af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
233476af099aSliuyi 		if (iRet != ERR_SUCCESS) {
233576af099aSliuyi 			if (g_pLogObject)
233676af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
233732268622SAndreas Färber 			printf("Read Chip Info failed!\r\n");
233876af099aSliuyi 		} else {
233976af099aSliuyi 			string strChipInfo;
234076af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
234176af099aSliuyi 			printf("Chip Info: %s\r\n", strChipInfo.c_str());
234276af099aSliuyi 			bSuccess = true;
234376af099aSliuyi 		}
234476af099aSliuyi 	} else {
234532268622SAndreas Färber 		printf("Read Chip Info quit, creating comm object failed!\r\n");
234676af099aSliuyi 	}
234776af099aSliuyi 	if (pComm) {
234876af099aSliuyi 		delete pComm;
234976af099aSliuyi 		pComm = NULL;
235076af099aSliuyi 	}
235176af099aSliuyi 	return bSuccess;
235276af099aSliuyi }
2353*081d237aSliuyi bool read_capability(STRUCT_RKDEVICE_DESC &dev)
2354*081d237aSliuyi {
2355*081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2356*081d237aSliuyi 	bool bRet, bSuccess = false;
2357*081d237aSliuyi 	int iRet;
2358*081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2359*081d237aSliuyi 		return bSuccess;
2360*081d237aSliuyi 
2361*081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2362*081d237aSliuyi 	if (bRet) {
2363*081d237aSliuyi 
2364*081d237aSliuyi 		BYTE capability[8];
2365*081d237aSliuyi 		iRet = pComm->RKU_ReadCapability(capability);
2366*081d237aSliuyi 		if (iRet != ERR_SUCCESS)
2367*081d237aSliuyi 		{
2368*081d237aSliuyi 			if (g_pLogObject)
2369*081d237aSliuyi 				g_pLogObject->Record("Error:read_capability failed,err=%d", iRet);
2370*081d237aSliuyi 			printf("Read capability Fail!\r\n");
2371*081d237aSliuyi 		} else {
2372*081d237aSliuyi 			printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n",
2373*081d237aSliuyi 			capability[0], capability[1], capability[2], capability[3],
2374*081d237aSliuyi 			capability[4], capability[5], capability[6], capability[7]);
2375*081d237aSliuyi 			if (capability[0] & 1)
2376*081d237aSliuyi 			{
2377*081d237aSliuyi 				printf("Direct LBA:\tenabled\r\n");
2378*081d237aSliuyi 			}
2379*081d237aSliuyi 
2380*081d237aSliuyi 			if (capability[0] & 2)
2381*081d237aSliuyi 			{
2382*081d237aSliuyi 				printf("Vendor Storage:\tenabled\r\n");
2383*081d237aSliuyi 			}
2384*081d237aSliuyi 
2385*081d237aSliuyi 			if (capability[0] & 4)
2386*081d237aSliuyi 			{
2387*081d237aSliuyi 				printf("First 4m Access:\tenabled\r\n");
2388*081d237aSliuyi 			}
2389*081d237aSliuyi 			bSuccess = true;
2390*081d237aSliuyi 		}
2391*081d237aSliuyi 	} else {
2392*081d237aSliuyi 		printf("Read capability quit, creating comm object failed!\r\n");
2393*081d237aSliuyi 	}
2394*081d237aSliuyi 	if (pComm) {
2395*081d237aSliuyi 		delete pComm;
2396*081d237aSliuyi 		pComm = NULL;
2397*081d237aSliuyi 	}
2398*081d237aSliuyi 	return bSuccess;
2399*081d237aSliuyi }
2400*081d237aSliuyi bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam)
2401*081d237aSliuyi {
2402*081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2403*081d237aSliuyi 		return false;
2404*081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2405*081d237aSliuyi 	bool bRet, bSuccess = false;
2406*081d237aSliuyi 	int iRet;
2407*081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2408*081d237aSliuyi 	if (bRet) {
2409*081d237aSliuyi 		iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam);
2410*081d237aSliuyi 		if(ERR_SUCCESS == iRet) {
2411*081d237aSliuyi 			if (*(u32 *)pParam != 0x4D524150) {
2412*081d237aSliuyi 				goto Exit_ReadParam;
2413*081d237aSliuyi 			}
2414*081d237aSliuyi 		} else {
2415*081d237aSliuyi 			if (g_pLogObject)
2416*081d237aSliuyi 					g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2417*081d237aSliuyi 			printf("Read parameter failed!\r\n");
2418*081d237aSliuyi 			goto Exit_ReadParam;
2419*081d237aSliuyi 		}
2420*081d237aSliuyi 		bSuccess = true;
2421*081d237aSliuyi 	}
2422*081d237aSliuyi Exit_ReadParam:
2423*081d237aSliuyi 	if (pComm) {
2424*081d237aSliuyi 		delete pComm;
2425*081d237aSliuyi 		pComm = NULL;
2426*081d237aSliuyi 	}
2427*081d237aSliuyi 	return bSuccess;
2428*081d237aSliuyi }
2429*081d237aSliuyi 
2430*081d237aSliuyi 
24316ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt)
24326ae612beSliuyi {
24336ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
24346ae612beSliuyi 		return false;
24356ae612beSliuyi 	gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE);
24366ae612beSliuyi 	CRKUsbComm *pComm = NULL;
24376ae612beSliuyi 	bool bRet, bSuccess = false;
24386ae612beSliuyi 	int iRet;
24396ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
24406ae612beSliuyi 	if (bRet) {
24416ae612beSliuyi 		iRet = pComm->RKU_ReadLBA( 0, 34, pGpt);
24426ae612beSliuyi 		if(ERR_SUCCESS == iRet) {
24436ae612beSliuyi 			if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
24446ae612beSliuyi 				goto Exit_ReadGPT;
24456ae612beSliuyi 			}
24466ae612beSliuyi 		} else {
24476ae612beSliuyi 			if (g_pLogObject)
24486ae612beSliuyi 					g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
24496ae612beSliuyi 			printf("Read GPT failed!\r\n");
24506ae612beSliuyi 			goto Exit_ReadGPT;
24516ae612beSliuyi 		}
24526ae612beSliuyi 		bSuccess = true;
24536ae612beSliuyi 	}
24546ae612beSliuyi Exit_ReadGPT:
24556ae612beSliuyi 	if (pComm) {
24566ae612beSliuyi 		delete pComm;
24576ae612beSliuyi 		pComm = NULL;
24586ae612beSliuyi 	}
24596ae612beSliuyi 	return bSuccess;
24606ae612beSliuyi }
246176af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
246276af099aSliuyi {
246376af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
246476af099aSliuyi 		return false;
246576af099aSliuyi 	CRKUsbComm *pComm = NULL;
246676af099aSliuyi 	FILE *file = NULL;
246776af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
246876af099aSliuyi 	int iRet;
246976af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
247076af099aSliuyi 	int nSectorSize = 512;
247176af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
247276af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
247376af099aSliuyi 	if (bRet) {
247476af099aSliuyi 		if(szFile) {
247576af099aSliuyi 			file = fopen(szFile, "wb+");
247676af099aSliuyi 			if( !file ) {
247776af099aSliuyi 				printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
247876af099aSliuyi 				goto Exit_ReadLBA;
247976af099aSliuyi 			}
248076af099aSliuyi 		}
248176af099aSliuyi 
248276af099aSliuyi 		while(uiLen > 0) {
248376af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
248476af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
248576af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
248676af099aSliuyi 			if(ERR_SUCCESS == iRet) {
248776af099aSliuyi 				uiLen -= iRead;
248876af099aSliuyi 				iTotalRead += iRead;
248976af099aSliuyi 
249076af099aSliuyi 				if(szFile) {
249176af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
249276af099aSliuyi 					if (bFirst){
249376af099aSliuyi 						if (iTotalRead >= 1024)
249432268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
249576af099aSliuyi 						else
249632268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
249776af099aSliuyi 						bFirst = false;
249876af099aSliuyi 					} else {
249976af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
250076af099aSliuyi 						CURSOR_DEL_LINE;
250176af099aSliuyi 						if (iTotalRead >= 1024)
250232268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
250376af099aSliuyi 						else
250432268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
250576af099aSliuyi 					}
250676af099aSliuyi 				}
250776af099aSliuyi 				else
250876af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
250976af099aSliuyi 			} else {
251076af099aSliuyi 				if (g_pLogObject)
251176af099aSliuyi 					g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
251276af099aSliuyi 
251376af099aSliuyi 				printf("Read LBA failed!\r\n");
251476af099aSliuyi 				goto Exit_ReadLBA;
251576af099aSliuyi 			}
251676af099aSliuyi 		}
251776af099aSliuyi 		bSuccess = true;
251876af099aSliuyi 	} else {
251932268622SAndreas Färber 		printf("Read LBA quit, creating comm object failed!\r\n");
252076af099aSliuyi 	}
252176af099aSliuyi Exit_ReadLBA:
252276af099aSliuyi 	if (pComm) {
252376af099aSliuyi 		delete pComm;
252476af099aSliuyi 		pComm = NULL;
252576af099aSliuyi 	}
252676af099aSliuyi 	if (file)
252776af099aSliuyi 		fclose(file);
252876af099aSliuyi 	return bSuccess;
252976af099aSliuyi }
25306ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize)
25316ae612beSliuyi {
2532ae4252f0Sliuyi 	UINT uiErase=1024*32;
25336ae612beSliuyi 	bool bSuccess = true;
25346ae612beSliuyi 	int iRet;
25356ae612beSliuyi 	while (uiSize)
25366ae612beSliuyi 	{
25376ae612beSliuyi 		if (uiSize>=uiErase)
25386ae612beSliuyi 		{
25396ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiErase);
25406ae612beSliuyi 			uiSize -= uiErase;
25416ae612beSliuyi 			uiOffset += uiErase;
25426ae612beSliuyi 		}
25436ae612beSliuyi 		else
25446ae612beSliuyi 		{
25456ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiSize);
25466ae612beSliuyi 			uiSize = 0;
25476ae612beSliuyi 			uiOffset += uiSize;
25486ae612beSliuyi 		}
25496ae612beSliuyi 		if (iRet!=ERR_SUCCESS)
25506ae612beSliuyi 		{
25516ae612beSliuyi 			if (g_pLogObject)
25526ae612beSliuyi 			{
25536ae612beSliuyi 				g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet);
25546ae612beSliuyi 			}
25556ae612beSliuyi 			bSuccess = false;
25566ae612beSliuyi 			break;
25576ae612beSliuyi 		}
25586ae612beSliuyi 	}
25596ae612beSliuyi 	return bSuccess;
25606ae612beSliuyi 
25616ae612beSliuyi }
25626ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk)
25636ae612beSliuyi {
25646ae612beSliuyi 	UINT uiRead;
25656ae612beSliuyi 	uiRead = fread(&chunk, 1, sizeof(chunk_header), file);
25666ae612beSliuyi 	if (uiRead != sizeof(chunk_header)) {
25676ae612beSliuyi 		if (g_pLogObject)
25686ae612beSliuyi 		{
25696ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno);
25706ae612beSliuyi 		}
25716ae612beSliuyi 		return false;
25726ae612beSliuyi 	}
25736ae612beSliuyi 	return true;
25746ae612beSliuyi }
25756ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize)
25766ae612beSliuyi {
25776ae612beSliuyi 	UINT uiRead;
25786ae612beSliuyi 	uiRead = fread(pBuf, 1, dwSize, file);
25796ae612beSliuyi 	if (uiRead!=dwSize)
25806ae612beSliuyi 	{
25816ae612beSliuyi 		if (g_pLogObject)
25826ae612beSliuyi 		{
25836ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno);
25846ae612beSliuyi 		}
25856ae612beSliuyi 		return false;
25866ae612beSliuyi 	}
25876ae612beSliuyi 	return true;
25886ae612beSliuyi }
25896ae612beSliuyi 
25906ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile)
25916ae612beSliuyi {
25926ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
25936ae612beSliuyi 		return false;
25946ae612beSliuyi 	CRKUsbComm *pComm = NULL;
25956ae612beSliuyi 	FILE *file = NULL;
25966ae612beSliuyi 	bool bRet, bSuccess = false, bFirst = true;
25976ae612beSliuyi 	int iRet;
25986ae612beSliuyi 	u64 iTotalWrite = 0, iFileSize = 0;
25996ae612beSliuyi 	UINT iRead = 0, uiTransferSec, curChunk, i;
26006ae612beSliuyi 	UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc;
26016ae612beSliuyi 	BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA];
26026ae612beSliuyi 	sparse_header header;
26036ae612beSliuyi 	chunk_header  chunk;
26046ae612beSliuyi 	dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE;
26056ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
26066ae612beSliuyi 	if (bRet) {
2607ae4252f0Sliuyi 
26086ae612beSliuyi 		file = fopen(szFile, "rb");
26096ae612beSliuyi 		if( !file ) {
26106ae612beSliuyi 			printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile);
26116ae612beSliuyi 			goto Exit_WriteSparseLBA;
26126ae612beSliuyi 		}
26136ae612beSliuyi 		fseeko(file, 0, SEEK_SET);
26146ae612beSliuyi 		iRead = fread(&header, 1, sizeof(header), file);
26156ae612beSliuyi 		if (iRead != sizeof(sparse_header))
26166ae612beSliuyi 		{
26176ae612beSliuyi 			if (g_pLogObject)
26186ae612beSliuyi 			{
26196ae612beSliuyi 				g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno);
26206ae612beSliuyi 			}
26216ae612beSliuyi 			goto Exit_WriteSparseLBA;
26226ae612beSliuyi 		}
26236ae612beSliuyi 		iFileSize = header.blk_sz * (u64)header.total_blks;
26246ae612beSliuyi 		iTotalWrite = 0;
26256ae612beSliuyi 		curChunk = 0;
2626ae4252f0Sliuyi 		if (uiSize==(u32)-1)
2627ae4252f0Sliuyi 			uiSize = ALIGN(iFileSize, SECTOR_SIZE);
2628ae4252f0Sliuyi 		bRet = erase_partition(pComm, uiBegin, uiSize);
2629ae4252f0Sliuyi 		if (!bRet) {
2630ae4252f0Sliuyi 			printf("%s failed, erase partition error\r\n", __func__);
2631ae4252f0Sliuyi 			goto Exit_WriteSparseLBA;
2632ae4252f0Sliuyi 		}
26336ae612beSliuyi 		while(curChunk < header.total_chunks)
26346ae612beSliuyi 		{
26356ae612beSliuyi 			if (!EatSparseChunk(file, chunk)) {
26366ae612beSliuyi 				goto Exit_WriteSparseLBA;
26376ae612beSliuyi 			}
26386ae612beSliuyi 			curChunk++;
26396ae612beSliuyi 			switch (chunk.chunk_type) {
26406ae612beSliuyi 			case CHUNK_TYPE_RAW:
26416ae612beSliuyi 				dwChunkDataSize = chunk.total_sz - sizeof(chunk_header);
26426ae612beSliuyi 				while (dwChunkDataSize) {
26436ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
26446ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
26456ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
26466ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
26476ae612beSliuyi 					} else {
26486ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
26496ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
26506ae612beSliuyi 					}
26516ae612beSliuyi 					if (!EatSparseData(file, pBuf, dwTransferBytes)) {
26526ae612beSliuyi 						goto Exit_WriteSparseLBA;
26536ae612beSliuyi 					}
26546ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
26556ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
26566ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
26576ae612beSliuyi 						iTotalWrite += dwTransferBytes;
26586ae612beSliuyi 						uiBegin += uiTransferSec;
26596ae612beSliuyi 					} else {
26606ae612beSliuyi 						if (g_pLogObject) {
26616ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)",  __func__, iTotalWrite, iRet);
26626ae612beSliuyi 						}
26636ae612beSliuyi 						goto Exit_WriteSparseLBA;
26646ae612beSliuyi 					}
26656ae612beSliuyi 					if (bFirst) {
26666ae612beSliuyi 						if (iTotalWrite >= 1024)
26676ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
26686ae612beSliuyi 						else
26696ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
26706ae612beSliuyi 						bFirst = false;
26716ae612beSliuyi 					} else {
26726ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
26736ae612beSliuyi 						CURSOR_DEL_LINE;
26746ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
26756ae612beSliuyi 					}
26766ae612beSliuyi 				}
26776ae612beSliuyi 				break;
26786ae612beSliuyi 			case CHUNK_TYPE_FILL:
26796ae612beSliuyi 				dwChunkDataSize = chunk.chunk_sz * header.blk_sz;
26806ae612beSliuyi 				if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) {
26816ae612beSliuyi 					goto Exit_WriteSparseLBA;
26826ae612beSliuyi 				}
26836ae612beSliuyi 				while (dwChunkDataSize) {
26846ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
26856ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
26866ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
26876ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
26886ae612beSliuyi 					} else {
26896ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
26906ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
26916ae612beSliuyi 					}
26926ae612beSliuyi 					for (i = 0; i < dwTransferBytes / 4; i++) {
26936ae612beSliuyi 						*(DWORD *)(pBuf + i * 4) = dwFillByte;
26946ae612beSliuyi 					}
26956ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
26966ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
26976ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
26986ae612beSliuyi 						iTotalWrite += dwTransferBytes;
26996ae612beSliuyi 						uiBegin += uiTransferSec;
27006ae612beSliuyi 					} else {
27016ae612beSliuyi 						if (g_pLogObject) {
27026ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet);
27036ae612beSliuyi 						}
27046ae612beSliuyi 						goto Exit_WriteSparseLBA;
27056ae612beSliuyi 					}
27066ae612beSliuyi 					if (bFirst) {
27076ae612beSliuyi 						if (iTotalWrite >= 1024)
27086ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27096ae612beSliuyi 						else
27106ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
27116ae612beSliuyi 						bFirst = false;
27126ae612beSliuyi 					} else {
27136ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
27146ae612beSliuyi 						CURSOR_DEL_LINE;
27156ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27166ae612beSliuyi 					}
27176ae612beSliuyi 				}
27186ae612beSliuyi 				break;
27196ae612beSliuyi 			case CHUNK_TYPE_DONT_CARE:
27206ae612beSliuyi 				dwChunkDataSize = chunk.chunk_sz * header.blk_sz;
27216ae612beSliuyi 				iTotalWrite += dwChunkDataSize;
27226ae612beSliuyi 				uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1));
27236ae612beSliuyi 				uiBegin += uiTransferSec;
27246ae612beSliuyi 				if (bFirst) {
27256ae612beSliuyi 					if (iTotalWrite >= 1024)
27266ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27276ae612beSliuyi 					else
27286ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
27296ae612beSliuyi 					bFirst = false;
27306ae612beSliuyi 				} else {
27316ae612beSliuyi 					CURSOR_MOVEUP_LINE(1);
27326ae612beSliuyi 					CURSOR_DEL_LINE;
27336ae612beSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27346ae612beSliuyi 				}
27356ae612beSliuyi 				break;
27366ae612beSliuyi 			case CHUNK_TYPE_CRC32:
27376ae612beSliuyi 				EatSparseData(file,(PBYTE)&dwCrc,4);
27386ae612beSliuyi 				break;
27396ae612beSliuyi 			}
27406ae612beSliuyi 		}
27416ae612beSliuyi 		bSuccess = true;
27426ae612beSliuyi 	} else {
27436ae612beSliuyi 		printf("Write LBA quit, creating comm object failed!\r\n");
27446ae612beSliuyi 	}
27456ae612beSliuyi Exit_WriteSparseLBA:
27466ae612beSliuyi 	if (pComm) {
27476ae612beSliuyi 		delete pComm;
27486ae612beSliuyi 		pComm = NULL;
27496ae612beSliuyi 	}
27506ae612beSliuyi 	if (file)
27516ae612beSliuyi 		fclose(file);
27526ae612beSliuyi 	return bSuccess;
27536ae612beSliuyi 
27546ae612beSliuyi }
27556ae612beSliuyi 
275676af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
275776af099aSliuyi {
275876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
275976af099aSliuyi 		return false;
276076af099aSliuyi 	CRKUsbComm *pComm = NULL;
276176af099aSliuyi 	FILE *file = NULL;
276276af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
276376af099aSliuyi 	int iRet;
276476af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
276576af099aSliuyi 	UINT iWrite = 0, iRead = 0;
276676af099aSliuyi 	UINT uiLen;
276776af099aSliuyi 	int nSectorSize = 512;
276876af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
276976af099aSliuyi 
277076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
277176af099aSliuyi 	if (bRet) {
277276af099aSliuyi 		file = fopen(szFile, "rb");
277376af099aSliuyi 		if( !file ) {
277476af099aSliuyi 			printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
277576af099aSliuyi 			goto Exit_WriteLBA;
277676af099aSliuyi 		}
277776af099aSliuyi 
277876af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
277976af099aSliuyi 		iFileSize = ftello(file);
278076af099aSliuyi 		fseeko(file, 0, SEEK_SET);
278176af099aSliuyi 		while(iTotalWrite < iFileSize) {
278276af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
278376af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
278476af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
278576af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
278676af099aSliuyi 			if(ERR_SUCCESS == iRet) {
278776af099aSliuyi 				uiBegin += uiLen;
278876af099aSliuyi 				iTotalWrite += iWrite;
278976af099aSliuyi 				if (bFirst) {
279076af099aSliuyi 					if (iTotalWrite >= 1024)
279176af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
279276af099aSliuyi 					else
279332268622SAndreas Färber 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
279476af099aSliuyi 					bFirst = false;
279576af099aSliuyi 				} else {
279676af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
279776af099aSliuyi 					CURSOR_DEL_LINE;
279876af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
279976af099aSliuyi 				}
280076af099aSliuyi 			} else {
280176af099aSliuyi 				if (g_pLogObject)
280276af099aSliuyi 					g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
280376af099aSliuyi 
280476af099aSliuyi 				printf("Write LBA failed!\r\n");
280576af099aSliuyi 				goto Exit_WriteLBA;
280676af099aSliuyi 			}
280776af099aSliuyi 		}
280876af099aSliuyi 		bSuccess = true;
280976af099aSliuyi 	} else {
281032268622SAndreas Färber 		printf("Write LBA quit, creating comm object failed!\r\n");
281176af099aSliuyi 	}
281276af099aSliuyi Exit_WriteLBA:
281376af099aSliuyi 	if (pComm) {
281476af099aSliuyi 		delete pComm;
281576af099aSliuyi 		pComm = NULL;
281676af099aSliuyi 	}
281776af099aSliuyi 	if (file)
281876af099aSliuyi 		fclose(file);
281976af099aSliuyi 	return bSuccess;
282076af099aSliuyi }
282176af099aSliuyi 
282276af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
282376af099aSliuyi {
282476af099aSliuyi 	string strItem;
282576af099aSliuyi 	char szItem[100];
282676af099aSliuyi 	char *pos = NULL, *pStart;
282776af099aSliuyi 	pStart = pszItems;
282876af099aSliuyi 	pos = strchr(pStart, ',');
282976af099aSliuyi 	while(pos != NULL) {
283076af099aSliuyi 		memset(szItem, 0, 100);
283176af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
283276af099aSliuyi 		strItem = szItem;
283376af099aSliuyi 		vecItems.push_back(strItem);
283476af099aSliuyi 		pStart = pos + 1;
283576af099aSliuyi 		if (*pStart == 0)
283676af099aSliuyi 			break;
283776af099aSliuyi 		pos = strchr(pStart, ',');
283876af099aSliuyi 	}
283976af099aSliuyi 	if (strlen(pStart) > 0) {
284076af099aSliuyi 		memset(szItem, 0, 100);
284176af099aSliuyi 		strncpy(szItem, pStart, strlen(pStart));
284276af099aSliuyi 		strItem = szItem;
284376af099aSliuyi 		vecItems.push_back(strItem);
284476af099aSliuyi 	}
284576af099aSliuyi }
2846c30d921cSKever Yang 
2847d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
2848d71e8c20SEddie Cai {
2849d71e8c20SEddie Cai 	FILE *file = NULL;
2850d71e8c20SEddie Cai 	int len;
2851d71e8c20SEddie Cai 
2852d71e8c20SEddie Cai 	if(!tag || !spl)
2853d71e8c20SEddie Cai 		return;
2854d71e8c20SEddie Cai 	len = strlen(tag);
2855d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
2856d71e8c20SEddie Cai 	file = fopen(spl, "rb");
2857d71e8c20SEddie Cai 	if( !file ){
2858d71e8c20SEddie Cai 		return;
2859d71e8c20SEddie Cai 	}
2860d71e8c20SEddie Cai 	int iFileSize;
2861d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
2862d71e8c20SEddie Cai 	iFileSize = ftell(file);
2863d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
2864d71e8c20SEddie Cai 	char *Buf = NULL;
2865d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
2866d71e8c20SEddie Cai 	if (!Buf){
2867d71e8c20SEddie Cai 		fclose(file);
2868d71e8c20SEddie Cai 		return;
2869d71e8c20SEddie Cai 	}
2870d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
2871d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
2872d71e8c20SEddie Cai 	int iRead;
2873d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
2874d71e8c20SEddie Cai 	if (iRead != iFileSize){
2875d71e8c20SEddie Cai 		fclose(file);
2876d71e8c20SEddie Cai 		delete []Buf;
2877d71e8c20SEddie Cai 		return;
2878d71e8c20SEddie Cai 	}
2879d71e8c20SEddie Cai 	fclose(file);
2880d71e8c20SEddie Cai 
2881d71e8c20SEddie Cai 	len = strlen(spl);
288232268622SAndreas Färber 	char *taggedspl = new char[len + 5];
288332268622SAndreas Färber 	strcpy(taggedspl, spl);
288432268622SAndreas Färber 	strcpy(taggedspl + len, ".tag");
288532268622SAndreas Färber 	taggedspl[len+4] = 0;
288632268622SAndreas Färber 	printf("Writing tagged spl to %s\n", taggedspl);
2887d71e8c20SEddie Cai 
288832268622SAndreas Färber 	file = fopen(taggedspl, "wb");
2889d71e8c20SEddie Cai 	if( !file ){
289032268622SAndreas Färber 		delete []taggedspl;
2891d71e8c20SEddie Cai 		delete []Buf;
2892d71e8c20SEddie Cai 		return;
2893d71e8c20SEddie Cai 	}
2894d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
2895d71e8c20SEddie Cai 	fclose(file);
289632268622SAndreas Färber 	delete []taggedspl;
2897d71e8c20SEddie Cai 	delete []Buf;
2898d71e8c20SEddie Cai 	printf("done\n");
2899d71e8c20SEddie Cai 	return;
2900d71e8c20SEddie Cai }
2901*081d237aSliuyi void list_device(CRKScan *pScan)
2902*081d237aSliuyi {
2903*081d237aSliuyi 	STRUCT_RKDEVICE_DESC desc;
2904*081d237aSliuyi 	string strDevType;
2905*081d237aSliuyi 	int i,cnt;
2906*081d237aSliuyi 	cnt = pScan->DEVICE_COUNTS;
2907*081d237aSliuyi 	if (cnt == 0) {
2908*081d237aSliuyi 		printf("not found any devices!\r\n");
2909*081d237aSliuyi 		return;
2910*081d237aSliuyi 	}
2911*081d237aSliuyi 	for (i=0;i<cnt;i++)
2912*081d237aSliuyi 	{
2913*081d237aSliuyi 		pScan->GetDevice(desc, i);
2914*081d237aSliuyi 		if (desc.emUsbType==RKUSB_MASKROM)
2915*081d237aSliuyi 			strDevType = "Maskrom";
2916*081d237aSliuyi 		else if (desc.emUsbType==RKUSB_LOADER)
2917*081d237aSliuyi 			strDevType = "Loader";
2918*081d237aSliuyi 		else
2919*081d237aSliuyi 			strDevType = "Unknown";
2920*081d237aSliuyi 		printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid,
2921*081d237aSliuyi 		       desc.usPid,desc.uiLocationID,strDevType.c_str());
2922*081d237aSliuyi 	}
2923*081d237aSliuyi 
2924*081d237aSliuyi }
2925*081d237aSliuyi 
2926d71e8c20SEddie Cai 
292776af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
292876af099aSliuyi {
292976af099aSliuyi 	string strCmd;
293076af099aSliuyi 	strCmd = argv[1];
293176af099aSliuyi 	ssize_t cnt;
293276af099aSliuyi 	bool bRet,bSuccess = false;
29338df2d64aSEddie Cai 	char *s;
29348df2d64aSEddie Cai 	int i, ret;
293576af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
2936*081d237aSliuyi 	u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE];
29376ae612beSliuyi 	u64 lba, lba_end;
2938*081d237aSliuyi 	u32 part_size, part_offset;
293976af099aSliuyi 
294076af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
29418df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
29428df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
29438df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
294478884ef4SEddie Cai 
29458df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
294676af099aSliuyi 		usage();
294776af099aSliuyi 		return true;
29488df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
2949c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
295076af099aSliuyi 		return true;
295178884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
295278884ef4SEddie Cai 		mergeBoot();
295378884ef4SEddie Cai 
295478884ef4SEddie Cai 		return true;
295578884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
295678884ef4SEddie Cai 		string strLoader = argv[2];
295778884ef4SEddie Cai 
295878884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
295978884ef4SEddie Cai 		return true;
2960d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
2961d71e8c20SEddie Cai 		if (argc == 4) {
2962d71e8c20SEddie Cai 			string tag = argv[2];
2963d71e8c20SEddie Cai 			string spl = argv[3];
2964d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
2965d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
2966d71e8c20SEddie Cai 			return true;
2967d71e8c20SEddie Cai 		}
2968d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
2969d71e8c20SEddie Cai 		usage();
297076af099aSliuyi 	}
297176af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
2972*081d237aSliuyi 	if(strcmp(strCmd.c_str(), "LD") == 0) {
2973*081d237aSliuyi 		list_device(pScan);
2974*081d237aSliuyi 		return true;
2975*081d237aSliuyi 	}
2976*081d237aSliuyi 
297776af099aSliuyi 	if (cnt < 1) {
297876af099aSliuyi 		ERROR_COLOR_ATTR;
297932268622SAndreas Färber 		printf("Did not find any rockusb device, please plug device in!");
298076af099aSliuyi 		NORMAL_COLOR_ATTR;
298176af099aSliuyi 		printf("\r\n");
298276af099aSliuyi 		return bSuccess;
298376af099aSliuyi 	} else if (cnt > 1) {
298476af099aSliuyi 		ERROR_COLOR_ATTR;
298532268622SAndreas Färber 		printf("Found too many rockusb devices, please plug devices out!");
298676af099aSliuyi 		NORMAL_COLOR_ATTR;
298776af099aSliuyi 		printf("\r\n");
298876af099aSliuyi 		return bSuccess;
298976af099aSliuyi 	}
299076af099aSliuyi 
299176af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
299276af099aSliuyi 	if (!bRet) {
299376af099aSliuyi 		ERROR_COLOR_ATTR;
299432268622SAndreas Färber 		printf("Getting information about rockusb device failed!");
299576af099aSliuyi 		NORMAL_COLOR_ATTR;
299676af099aSliuyi 		printf("\r\n");
299776af099aSliuyi 		return bSuccess;
299876af099aSliuyi 	}
299976af099aSliuyi 
300076af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
300176af099aSliuyi 		if ((argc != 2) && (argc != 3))
300276af099aSliuyi 			printf("Parameter of [RD] command is invalid, please check help!\r\n");
300376af099aSliuyi 		else {
300476af099aSliuyi 			if (argc == 2)
300576af099aSliuyi 				bSuccess = reset_device(dev);
300676af099aSliuyi 			else {
300776af099aSliuyi 				UINT uiSubCode;
300876af099aSliuyi 				char *pszEnd;
300976af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
301076af099aSliuyi 				if (*pszEnd)
301176af099aSliuyi 					printf("Subcode is invalid, please check!\r\n");
301276af099aSliuyi 				else {
301376af099aSliuyi 					if (uiSubCode <= 5)
301476af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
301576af099aSliuyi 					else
301676af099aSliuyi 						printf("Subcode is invalid, please check!\r\n");
301776af099aSliuyi 				}
301876af099aSliuyi 			}
301976af099aSliuyi 		}
302076af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
302176af099aSliuyi 		bSuccess = test_device(dev);
302276af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
302376af099aSliuyi 		bSuccess = read_flash_id(dev);
302476af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
302576af099aSliuyi 		bSuccess = read_flash_info(dev);
302676af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
302776af099aSliuyi 		bSuccess = read_chip_info(dev);
3028*081d237aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability
3029*081d237aSliuyi 		bSuccess = read_capability(dev);
303076af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
303176af099aSliuyi 		if (argc > 2) {
303276af099aSliuyi 			string strLoader;
303376af099aSliuyi 			strLoader = argv[2];
303476af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
303576af099aSliuyi 		} else if (argc == 2) {
3036c29e5f0fSliuyi 			ret = find_config_item(g_ConfigItemVec, "loader");
303776af099aSliuyi 			if (ret == -1)
303832268622SAndreas Färber 				printf("Did not find loader item in config!\r\n");
303976af099aSliuyi 			else
304076af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
304176af099aSliuyi 		} else
304276af099aSliuyi 			printf("Parameter of [DB] command is invalid, please check help!\r\n");
3043c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
3044c30d921cSKever Yang 		if (argc > 2) {
3045c30d921cSKever Yang 			string strParameter;
3046c30d921cSKever Yang 			strParameter = argv[2];
3047c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
3048c30d921cSKever Yang 		} else
3049c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid, please check help!\r\n");
3050*081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PRM") == 0) {
3051*081d237aSliuyi 		if (argc > 2) {
3052*081d237aSliuyi 			string strParameter;
3053*081d237aSliuyi 			strParameter = argv[2];
3054*081d237aSliuyi 			bSuccess = write_parameter(dev, (char *)strParameter.c_str());
3055*081d237aSliuyi 		} else
3056*081d237aSliuyi 			printf("Parameter of [PRM] command is invalid, please check help!\r\n");
3057c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
3058c30d921cSKever Yang 		if (argc > 2) {
3059c30d921cSKever Yang 			string strLoader;
3060c30d921cSKever Yang 			strLoader = argv[2];
3061c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
3062c30d921cSKever Yang 		} else
3063c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid, please check help!\r\n");
306476af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
306576af099aSliuyi 		if (argc == 2) {
306676af099aSliuyi 			bSuccess = erase_flash(dev);
306776af099aSliuyi 		} else
306876af099aSliuyi 			printf("Parameter of [EF] command is invalid, please check help!\r\n");
306976af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
307076af099aSliuyi 		if (argc == 4) {
307176af099aSliuyi 			UINT uiBegin;
307276af099aSliuyi 			char *pszEnd;
307376af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
307476af099aSliuyi 			if (*pszEnd)
307576af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
3076ae4252f0Sliuyi 			else {
3077ae4252f0Sliuyi 				if (is_sparse_image(argv[3]))
3078ae4252f0Sliuyi 						bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]);
307976af099aSliuyi 					else
3080ae4252f0Sliuyi 						bSuccess = write_lba(dev, (u32)uiBegin, argv[3]);
3081ae4252f0Sliuyi 			}
308276af099aSliuyi 		} else
308376af099aSliuyi 			printf("Parameter of [WL] command is invalid, please check help!\r\n");
30846ae612beSliuyi 	} else if(strcmp(strCmd.c_str(), "WLX") == 0) {
30856ae612beSliuyi 		if (argc == 4) {
30866ae612beSliuyi 			bRet = read_gpt(dev, master_gpt);
30876ae612beSliuyi 			if (bRet) {
30886ae612beSliuyi 				bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end);
30896ae612beSliuyi 				if (bRet) {
30906ae612beSliuyi 					if (is_sparse_image(argv[3]))
30916ae612beSliuyi 						bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]);
30926ae612beSliuyi 					else
30936ae612beSliuyi 						bSuccess = write_lba(dev, (u32)lba, argv[3]);
30946ae612beSliuyi 				} else
30956ae612beSliuyi 					printf("No found %s partition\r\n", argv[2]);
3096*081d237aSliuyi 			} else {
3097*081d237aSliuyi 				bRet = read_param(dev, param_buffer);
3098*081d237aSliuyi 				if (bRet) {
3099*081d237aSliuyi 					bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size);
3100*081d237aSliuyi 					if (bRet) {
3101*081d237aSliuyi 						if (is_sparse_image(argv[3]))
3102*081d237aSliuyi 							bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]);
3103*081d237aSliuyi 						else
3104*081d237aSliuyi 							bSuccess = write_lba(dev, part_offset, argv[3]);
3105*081d237aSliuyi 					} else
3106*081d237aSliuyi 						printf("No found %s partition\r\n", argv[2]);
31076ae612beSliuyi 				}
3108*081d237aSliuyi 				else
3109*081d237aSliuyi 					printf("Not found any partition table!\r\n");
3110*081d237aSliuyi 			}
3111*081d237aSliuyi 
31126ae612beSliuyi 		} else
31136ae612beSliuyi 			printf("Parameter of [WLX] command is invalid, please check help!\r\n");
311476af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
311576af099aSliuyi 		char *pszEnd;
311676af099aSliuyi 		UINT uiBegin, uiLen;
311776af099aSliuyi 		if (argc != 5)
311876af099aSliuyi 			printf("Parameter of [RL] command is invalid, please check help!\r\n");
311976af099aSliuyi 		else {
312076af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
312176af099aSliuyi 			if (*pszEnd)
312276af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
312376af099aSliuyi 			else {
312476af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
312576af099aSliuyi 				if (*pszEnd)
312676af099aSliuyi 					printf("Len is invalid, please check!\r\n");
312776af099aSliuyi 				else {
312876af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
312976af099aSliuyi 				}
313076af099aSliuyi 			}
313176af099aSliuyi 		}
3132*081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PPT") == 0) {
31333dc7e3ceSliuyi 		if (argc == 2) {
31343dc7e3ceSliuyi 			bSuccess = print_gpt(dev);
3135*081d237aSliuyi 			if (!bSuccess) {
3136*081d237aSliuyi 				bSuccess = print_parameter(dev);
3137*081d237aSliuyi 				if (!bSuccess)
3138*081d237aSliuyi 					printf("Not found any partition table!\r\n");
3139*081d237aSliuyi 			}
31403dc7e3ceSliuyi 		} else
3141*081d237aSliuyi 			printf("Parameter of [PPT] command is invalid, please check help!\r\n");
314276af099aSliuyi 	} else {
31439bc231bdSAndreas Färber 		printf("command is invalid!\r\n");
31449bc231bdSAndreas Färber 		usage();
314576af099aSliuyi 	}
314676af099aSliuyi 	return bSuccess;
314776af099aSliuyi }
314876af099aSliuyi 
314976af099aSliuyi 
315076af099aSliuyi int main(int argc, char* argv[])
315176af099aSliuyi {
315276af099aSliuyi 	CRKScan *pScan = NULL;
315376af099aSliuyi 	int ret;
315476af099aSliuyi 	char szProgramProcPath[100];
315576af099aSliuyi 	char szProgramDir[256];
315676af099aSliuyi 	string strLogDir,strConfigFile;
315776af099aSliuyi 	struct stat statBuf;
315876af099aSliuyi 
315976af099aSliuyi 	g_ConfigItemVec.clear();
316076af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
316176af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
316276af099aSliuyi 		strcpy(szProgramDir, ".");
316376af099aSliuyi 	else {
316476af099aSliuyi 		char *pSlash;
316576af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
316676af099aSliuyi 		if (pSlash)
316776af099aSliuyi 			*pSlash = '\0';
316876af099aSliuyi 	}
316976af099aSliuyi 	strLogDir = szProgramDir;
317076af099aSliuyi 	strLogDir +=  "/log/";
317176af099aSliuyi 	strConfigFile = szProgramDir;
317276af099aSliuyi 	strConfigFile += "/config.ini";
317376af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
317476af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
3175e5ee8cc0Sliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
317676af099aSliuyi 
317776af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
317876af099aSliuyi 		if (g_pLogObject) {
317976af099aSliuyi 			g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
318076af099aSliuyi 		}
318176af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
318276af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
318376af099aSliuyi 	}
318476af099aSliuyi 
318576af099aSliuyi 	ret = libusb_init(NULL);
318676af099aSliuyi 	if (ret < 0) {
318776af099aSliuyi 		if (g_pLogObject) {
318876af099aSliuyi 			g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
318976af099aSliuyi 			delete g_pLogObject;
319076af099aSliuyi 		}
319176af099aSliuyi 		return -1;
319276af099aSliuyi 	}
319376af099aSliuyi 
319476af099aSliuyi 	pScan = new CRKScan();
319576af099aSliuyi 	if (!pScan) {
319676af099aSliuyi 		if (g_pLogObject) {
319732268622SAndreas Färber 			g_pLogObject->Record("Error: failed to create object for searching device");
319876af099aSliuyi 			delete g_pLogObject;
319976af099aSliuyi 		}
320076af099aSliuyi 		libusb_exit(NULL);
320176af099aSliuyi 		return -2;
320276af099aSliuyi 	}
320376af099aSliuyi 	pScan->SetVidPid();
320476af099aSliuyi 
320576af099aSliuyi 	if (argc == 1)
320676af099aSliuyi 		usage();
320776af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
320876af099aSliuyi 			return -0xFF;
320976af099aSliuyi 	if (pScan)
321076af099aSliuyi 		delete pScan;
321176af099aSliuyi 	if (g_pLogObject)
321276af099aSliuyi 		delete g_pLogObject;
321376af099aSliuyi 	libusb_exit(NULL);
321476af099aSliuyi 	return 0;
321576af099aSliuyi }
3216