xref: /rkdeveloptool/main.cpp (revision aca206f7e90f92e999d94f46ed198c3bcd735dbb)
176af099aSliuyi /*
276af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi  * Seth Liu 2017.03.01
476af099aSliuyi  *
576af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
676af099aSliuyi  */
776af099aSliuyi 
876af099aSliuyi #include   <unistd.h>
976af099aSliuyi #include   <dirent.h>
10c30d921cSKever Yang #include "config.h"
1176af099aSliuyi #include "DefineHeader.h"
12c30d921cSKever Yang #include "gpt.h"
1376af099aSliuyi #include "RKLog.h"
1476af099aSliuyi #include "RKScan.h"
1576af099aSliuyi #include "RKComm.h"
1676af099aSliuyi #include "RKDevice.h"
1776af099aSliuyi #include "RKImage.h"
1876af099aSliuyi extern const char *szManufName[];
1976af099aSliuyi CRKLog *g_pLogObject=NULL;
2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec;
2176af099aSliuyi #define DEFAULT_RW_LBA 128
2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
2676af099aSliuyi #define ERROR_COLOR_ATTR  printf("%c[30;41m", 0x1B);
273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR  printf("%c[0m", 0x1B);
28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize);
29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize);
30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len);
31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len);
32c30d921cSKever Yang /*
33c30d921cSKever Yang u8 test_gpt_head[] = {
34c30d921cSKever Yang 	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00,
35c30d921cSKever Yang 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36c30d921cSKever Yang 	0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37c30d921cSKever Yang 	0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B,
38c30d921cSKever Yang 	0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39c30d921cSKever Yang 	0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08};
40c30d921cSKever Yang */
41c30d921cSKever Yang 
4276af099aSliuyi void usage()
4376af099aSliuyi {
4476af099aSliuyi 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
45ae4252f0Sliuyi 	printf("Help:\t\t\t-h or --help\r\n");
46154ee062SEddie Cai 	printf("Version:\t\t-v or --version\r\n");
47081d237aSliuyi 	printf("ListDevice:\t\tld\r\n");
48154ee062SEddie Cai 	printf("DownloadBoot:\t\tdb <Loader>\r\n");
49154ee062SEddie Cai 	printf("UpgradeLoader:\t\tul <Loader>\r\n");
50154ee062SEddie Cai 	printf("ReadLBA:\t\trl  <BeginSec> <SectorLen> <File>\r\n");
51154ee062SEddie Cai 	printf("WriteLBA:\t\twl  <BeginSec> <File>\r\n");
526ae612beSliuyi 	printf("WriteLBA:\t\twlx  <PartitionName> <File>\r\n");
53154ee062SEddie Cai 	printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
54081d237aSliuyi 	printf("WriteParameter:\t\tprm <parameter>\r\n");
55081d237aSliuyi 	printf("PrintPartition:\t\tppt \r\n");
56154ee062SEddie Cai 	printf("EraseFlash:\t\tef \r\n");
57154ee062SEddie Cai 	printf("TestDevice:\t\ttd\r\n");
58154ee062SEddie Cai 	printf("ResetDevice:\t\trd [subcode]\r\n");
59154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
60154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
61154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
62081d237aSliuyi 	printf("ReadCapability:\t\trcb\r\n");
6378884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
6478884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
65d71e8c20SEddie Cai 	printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
6676af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6776af099aSliuyi }
6876af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6976af099aSliuyi {
7076af099aSliuyi 	string strInfoText="";
7176af099aSliuyi 	char szText[256];
7276af099aSliuyi 	switch (promptID) {
7376af099aSliuyi 	case TESTDEVICE_PROGRESS:
7432268622SAndreas Färber 		sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue);
7576af099aSliuyi 		strInfoText = szText;
7676af099aSliuyi 		break;
7776af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7832268622SAndreas Färber 		sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue);
7976af099aSliuyi 		strInfoText = szText;
8076af099aSliuyi 		break;
8176af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
8232268622SAndreas Färber 		sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8376af099aSliuyi 		strInfoText = szText;
8476af099aSliuyi 		break;
8576af099aSliuyi 	case CHECKIMAGE_PROGRESS:
8632268622SAndreas Färber 		sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8776af099aSliuyi 		strInfoText = szText;
8876af099aSliuyi 		break;
8976af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
9032268622SAndreas Färber 		sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue);
9176af099aSliuyi 		strInfoText = szText;
9276af099aSliuyi 		break;
9376af099aSliuyi 	case TESTBLOCK_PROGRESS:
9432268622SAndreas Färber 		sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue);
9576af099aSliuyi 		strInfoText = szText;
9676af099aSliuyi 		break;
9776af099aSliuyi 	case ERASEFLASH_PROGRESS:
9832268622SAndreas Färber 		sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue);
9976af099aSliuyi 		strInfoText = szText;
10076af099aSliuyi 		break;
10176af099aSliuyi 	case ERASESYSTEM_PROGRESS:
10232268622SAndreas Färber 		sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue);
10376af099aSliuyi 		strInfoText = szText;
10476af099aSliuyi 		break;
10576af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
10632268622SAndreas Färber 		sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue);
10776af099aSliuyi 		strInfoText = szText;
10876af099aSliuyi 		break;
10976af099aSliuyi 	}
11076af099aSliuyi 	if (strInfoText.size() > 0){
11176af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
11276af099aSliuyi 		CURSOR_DEL_LINE;
11376af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
11476af099aSliuyi 	}
11576af099aSliuyi 	if (emCall == CALL_LAST)
11676af099aSliuyi 		deviceLayer = 0;
11776af099aSliuyi }
11876af099aSliuyi 
11976af099aSliuyi char *strupr(char *szSrc)
12076af099aSliuyi {
12176af099aSliuyi 	char *p = szSrc;
12276af099aSliuyi 	while(*p){
12376af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
12476af099aSliuyi 			*p = *p - 'a' + 'A';
12576af099aSliuyi 		p++;
12676af099aSliuyi 	}
12776af099aSliuyi 	return szSrc;
12876af099aSliuyi }
12976af099aSliuyi void PrintData(PBYTE pData, int nSize)
13076af099aSliuyi {
13176af099aSliuyi 	char szPrint[17] = "\0";
13276af099aSliuyi 	int i;
13376af099aSliuyi 	for( i = 0; i < nSize; i++){
13476af099aSliuyi 		if(i % 16 == 0){
13576af099aSliuyi 			if(i / 16 > 0)
13676af099aSliuyi 				printf("     %s\r\n", szPrint);
13776af099aSliuyi 			printf("%08d ", i / 16);
13876af099aSliuyi 		}
13976af099aSliuyi 		printf("%02X ", pData[i]);
14076af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
14176af099aSliuyi 	}
14276af099aSliuyi 	if(i / 16 > 0)
14376af099aSliuyi 		printf("     %s\r\n", szPrint);
14476af099aSliuyi }
14576af099aSliuyi 
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 	}
487c30d921cSKever Yang 	return bFind;
488c30d921cSKever Yang 
489c30d921cSKever Yang }
490c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
491c30d921cSKever Yang {
492c30d921cSKever Yang 	FILE *file = NULL;
493c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
494c30d921cSKever Yang 	if( !file ) {
495c30d921cSKever Yang 		if (g_pLogObject)
49632268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
497c30d921cSKever Yang 		return false;
498c30d921cSKever Yang 	}
499c30d921cSKever Yang 	int iFileSize;
500c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
501c30d921cSKever Yang 	iFileSize = ftell(file);
502c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
503c30d921cSKever Yang 	char *pParamBuf = NULL;
504c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
505c30d921cSKever Yang 	if (!pParamBuf) {
506c30d921cSKever Yang 		fclose(file);
507c30d921cSKever Yang 		return false;
508c30d921cSKever Yang 	}
509c30d921cSKever Yang 	int iRead;
510c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
511c30d921cSKever Yang 	if (iRead != iFileSize) {
512c30d921cSKever Yang 		if (g_pLogObject)
51332268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
514c30d921cSKever Yang 		fclose(file);
515c30d921cSKever Yang 		delete []pParamBuf;
516c30d921cSKever Yang 		return false;
517c30d921cSKever Yang 	}
518c30d921cSKever Yang 	fclose(file);
519c30d921cSKever Yang 	bool bRet;
520c29e5f0fSliuyi 	bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem);
521c30d921cSKever Yang 	delete []pParamBuf;
522c30d921cSKever Yang 	return bRet;
523c30d921cSKever Yang }
5246ae612beSliuyi bool is_sparse_image(char *szImage)
5256ae612beSliuyi {
5266ae612beSliuyi 	FILE *file = NULL;
5276ae612beSliuyi 	sparse_header head;
5286ae612beSliuyi 	u32 uiRead;
5296ae612beSliuyi 	file = fopen(szImage, "rb");
5306ae612beSliuyi 	if( !file ) {
5316ae612beSliuyi 		if (g_pLogObject)
5326ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
5336ae612beSliuyi 		return false;
5346ae612beSliuyi 	}
5356ae612beSliuyi 	uiRead = fread(&head, 1, sizeof(head), file);
5366ae612beSliuyi 	if (uiRead != sizeof(head)) {
5376ae612beSliuyi 		if (g_pLogObject)
5386ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head));
5396ae612beSliuyi 		fclose(file);
5406ae612beSliuyi 		return false;
5416ae612beSliuyi 	}
5426ae612beSliuyi 	fclose(file);
5436ae612beSliuyi 	if (head.magic!=SPARSE_HEADER_MAGIC)
5446ae612beSliuyi 	{
5456ae612beSliuyi 		return false;
5466ae612beSliuyi 	}
5476ae612beSliuyi 	return true;
5486ae612beSliuyi 
5496ae612beSliuyi }
550c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
551c30d921cSKever Yang {
552c30d921cSKever Yang 	efi_guid_t id;
553c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
554c30d921cSKever Yang 	unsigned int i;
555c30d921cSKever Yang 
556c30d921cSKever Yang 	/* Set all fields randomly */
557c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
558c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
559c30d921cSKever Yang 
560c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
561c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
562c30d921cSKever Yang 
563c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
564c30d921cSKever Yang }
565c30d921cSKever Yang 
566c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup)
567c29e5f0fSliuyi {
568c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
569c29e5f0fSliuyi 	gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
570c29e5f0fSliuyi 	u32 calc_crc32;
571c29e5f0fSliuyi 	u64 val;
572c29e5f0fSliuyi 
573c29e5f0fSliuyi 	/* recalculate the values for the Backup GPT Header */
574c29e5f0fSliuyi 	val = le64_to_cpu(gptMasterHead->my_lba);
575c29e5f0fSliuyi 	gptBackupHead->my_lba = gptMasterHead->alternate_lba;
576c29e5f0fSliuyi 	gptBackupHead->alternate_lba = cpu_to_le64(val);
577c29e5f0fSliuyi 	gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
578c29e5f0fSliuyi 	gptBackupHead->header_crc32 = 0;
579c29e5f0fSliuyi 
580c29e5f0fSliuyi 	calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
581c29e5f0fSliuyi 	gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
582c29e5f0fSliuyi }
5836ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end)
5846ae612beSliuyi {
5856ae612beSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
5866ae612beSliuyi 	gpt_entry  *gptEntry  = NULL;
5876ae612beSliuyi 	u32 i,j;
5886ae612beSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
5896ae612beSliuyi 	bool bFound = false;
5906ae612beSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
5916ae612beSliuyi 
5926ae612beSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
5936ae612beSliuyi 		gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
5946ae612beSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
5956ae612beSliuyi 			break;
5966ae612beSliuyi 		for (j = 0; j < strlen(pszName); j++)
5976ae612beSliuyi 			if (gptEntry->partition_name[j] != pszName[j])
5986ae612beSliuyi 				break;
5996ae612beSliuyi 		if (gptEntry->partition_name[j] != 0)
6006ae612beSliuyi 			continue;
6016ae612beSliuyi 		if (j == strlen(pszName)) {
6026ae612beSliuyi 			bFound = true;
6036ae612beSliuyi 			break;
6046ae612beSliuyi 		}
6056ae612beSliuyi 	}
6066ae612beSliuyi 	if (bFound) {
6076ae612beSliuyi 		*lba = le64_to_cpu(gptEntry->starting_lba);
6086ae612beSliuyi 		*lba_end =  le64_to_cpu(gptEntry->ending_lba);
6096ae612beSliuyi 		return true;
6106ae612beSliuyi 	}
6116ae612beSliuyi 	return false;
6126ae612beSliuyi }
613081d237aSliuyi bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size)
614081d237aSliuyi {
615081d237aSliuyi 	u32 i;
616081d237aSliuyi 	bool bFound = false, bRet;
617081d237aSliuyi 	PARAM_ITEM_VECTOR vecItem;
618081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
619081d237aSliuyi 
620081d237aSliuyi 	bRet = parse_parameter((char *)param, vecItem, vecUuid);
621081d237aSliuyi 	if (!bRet)
622081d237aSliuyi 		return false;
623081d237aSliuyi 
624081d237aSliuyi 	for (i = 0; i < vecItem.size(); i++) {
625081d237aSliuyi 		if (strcasecmp(pszName, vecItem[i].szItemName)==0) {
626081d237aSliuyi 			bFound = true;
627081d237aSliuyi 			break;
628081d237aSliuyi 		}
629081d237aSliuyi 	}
630081d237aSliuyi 	if (bFound) {
631081d237aSliuyi 		*part_offset = vecItem[i].uiItemOffset;
632081d237aSliuyi 		*part_size =  vecItem[i].uiItemSize;
633081d237aSliuyi 		return true;
634081d237aSliuyi 	}
635081d237aSliuyi 	return false;
636081d237aSliuyi }
637081d237aSliuyi 
638c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector)
639c29e5f0fSliuyi {
640c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
641c29e5f0fSliuyi 	gpt_entry  *gptLastPartEntry  = NULL;
642c29e5f0fSliuyi 	u32 i;
643c29e5f0fSliuyi 	u64 old_disksize;
644c29e5f0fSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
645c29e5f0fSliuyi 
646c29e5f0fSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
647c29e5f0fSliuyi 	old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1;
648c29e5f0fSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
649c29e5f0fSliuyi 		gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
650c29e5f0fSliuyi 		if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0)
651c29e5f0fSliuyi 			break;
652c29e5f0fSliuyi 	}
653c29e5f0fSliuyi 	i--;
654c29e5f0fSliuyi 	gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry));
655c29e5f0fSliuyi 
656c29e5f0fSliuyi 	gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1);
657c29e5f0fSliuyi 	gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34);
658c29e5f0fSliuyi 
659c29e5f0fSliuyi 	if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition
660c29e5f0fSliuyi 		gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34);
661c29e5f0fSliuyi 		gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
662c29e5f0fSliuyi 	}
663c29e5f0fSliuyi 	gptMasterHead->header_crc32 = 0;
664c29e5f0fSliuyi 	gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header)));
665c29e5f0fSliuyi 	memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS);
666c29e5f0fSliuyi 	memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE);
667c29e5f0fSliuyi 	prepare_gpt_backup(master, backup);
668c29e5f0fSliuyi 
669c29e5f0fSliuyi }
670c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup)
671c29e5f0fSliuyi {
672c29e5f0fSliuyi 	FILE *file = NULL;
673c29e5f0fSliuyi 	file = fopen(pParamFile, "rb");
674c29e5f0fSliuyi 	if( !file ) {
675c29e5f0fSliuyi 		if (g_pLogObject)
676c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
677c29e5f0fSliuyi 		return false;
678c29e5f0fSliuyi 	}
679c29e5f0fSliuyi 	int iFileSize;
680c29e5f0fSliuyi 	fseek(file, 0, SEEK_END);
681c29e5f0fSliuyi 	iFileSize = ftell(file);
682c29e5f0fSliuyi 	fseek(file, 0, SEEK_SET);
683c29e5f0fSliuyi 	if (iFileSize != 67 * SECTOR_SIZE) {
684c29e5f0fSliuyi 		if (g_pLogObject)
685c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile);
686c29e5f0fSliuyi 		fclose(file);
687c29e5f0fSliuyi 		return false;
688c29e5f0fSliuyi 	}
689c29e5f0fSliuyi 
690c29e5f0fSliuyi 	int iRead;
691c29e5f0fSliuyi 	iRead = fread(master, 1, 34 * SECTOR_SIZE, file);
692c29e5f0fSliuyi 	if (iRead != 34 * SECTOR_SIZE) {
693c29e5f0fSliuyi 		if (g_pLogObject)
694c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE);
695c29e5f0fSliuyi 		fclose(file);
696c29e5f0fSliuyi 		return false;
697c29e5f0fSliuyi 	}
698c29e5f0fSliuyi 	iRead = fread(backup, 1, 33 * SECTOR_SIZE, file);
699c29e5f0fSliuyi 	if (iRead != 33 * SECTOR_SIZE) {
700c29e5f0fSliuyi 		if (g_pLogObject)
701c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE);
702c29e5f0fSliuyi 		fclose(file);
703c29e5f0fSliuyi 		return false;
704c29e5f0fSliuyi 	}
705c29e5f0fSliuyi 	fclose(file);
706c29e5f0fSliuyi 	return true;
707c29e5f0fSliuyi }
708c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
709c30d921cSKever Yang {
710c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
711c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
712c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
713c30d921cSKever Yang 	u32 i,j;
714c29e5f0fSliuyi 	int pos;
715c30d921cSKever Yang 	string strPartName;
716c30d921cSKever Yang 	string::size_type colonPos;
717c30d921cSKever Yang 	/*1.protective mbr*/
718c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
719c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
720c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
721c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
722c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
723c30d921cSKever Yang 	/*2.gpt header*/
724c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
725c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
726c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
727c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
728c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
729c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
730c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
731c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
732c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
733c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
734c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
735c30d921cSKever Yang 	gptHead->header_crc32 = 0;
736c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
737c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
738c30d921cSKever Yang 
739c30d921cSKever Yang 	/*3.gpt partition entry*/
740c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
741c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
742c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
743c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
744c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
745c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
746c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
747c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
748c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
749c30d921cSKever Yang 		if (colonPos != string::npos) {
750c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
751c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
752c29e5f0fSliuyi 			if (strPartName.find("grow") != string::npos)
753c29e5f0fSliuyi 				gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
754c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
755c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
756c30d921cSKever Yang 		}
757c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
758c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
759c29e5f0fSliuyi 		if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1)
760c29e5f0fSliuyi 			memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
761c30d921cSKever Yang 		gptEntry++;
762c30d921cSKever Yang 	}
763c30d921cSKever Yang 
764c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
765c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
766c30d921cSKever Yang 
767c30d921cSKever Yang }
768b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
769c30d921cSKever Yang {
770c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
771c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
772c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
773c30d921cSKever Yang 
774c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
775b38fe5fcSliuyi 	pSec0->uiRc4Flag = rc4Flag;
776c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
777c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
778c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
779c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
780c30d921cSKever Yang 	return true;
781c30d921cSKever Yang }
782c30d921cSKever Yang 
783c30d921cSKever Yang 
784c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
785c30d921cSKever Yang {
786c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
787c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
788c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
789c30d921cSKever Yang 
790c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
791c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
792c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
793c30d921cSKever Yang 	return true;
794c30d921cSKever Yang }
795c30d921cSKever Yang 
796c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
797c30d921cSKever Yang {
798c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
799c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
800c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
801c30d921cSKever Yang 
802c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
803c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
804c30d921cSKever Yang 	return true;
805c30d921cSKever Yang }
806c30d921cSKever Yang 
807c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
808c30d921cSKever Yang {
809c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
810c30d921cSKever Yang 	return true;
811c30d921cSKever Yang }
812c30d921cSKever Yang 
813b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
814c30d921cSKever Yang {
815c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
816c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
817c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
818c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
819c30d921cSKever Yang 	UINT i;
820b38fe5fcSliuyi 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
821c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
822c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
823c30d921cSKever Yang 		return -6;
824c30d921cSKever Yang 	}
825c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
826c30d921cSKever Yang 		return -7;
827c30d921cSKever Yang 	}
828c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
829c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
830c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
831c30d921cSKever Yang 
832c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
833c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
834c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
835b38fe5fcSliuyi 
836b38fe5fcSliuyi 	if (rc4Flag) {
837b38fe5fcSliuyi 		for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
838b38fe5fcSliuyi 			P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
839b38fe5fcSliuyi 		for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
840b38fe5fcSliuyi 			P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
841b38fe5fcSliuyi 	}
842b38fe5fcSliuyi 
843c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
844c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
845c30d921cSKever Yang 
846c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
847c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
848c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
849c30d921cSKever Yang 		if(i == 1) {
850c30d921cSKever Yang 			continue;
851c30d921cSKever Yang 		} else {
852c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
853c30d921cSKever Yang 		}
854c30d921cSKever Yang 	}
855c30d921cSKever Yang 	return 0;
856c30d921cSKever Yang }
857c30d921cSKever Yang 
858c30d921cSKever Yang 
85976af099aSliuyi 
86076af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
86176af099aSliuyi {
86206ea143eSKlaus Goger 	if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType)
86376af099aSliuyi 		return true;
86476af099aSliuyi 	else
86576af099aSliuyi 	{
86676af099aSliuyi 		ERROR_COLOR_ATTR;
86732268622SAndreas Färber 		printf("The device does not support this operation!");
86876af099aSliuyi 		NORMAL_COLOR_ATTR;
86976af099aSliuyi 		printf("\r\n");
87076af099aSliuyi 		return false;
87176af099aSliuyi 	}
87276af099aSliuyi }
873081d237aSliuyi bool MakeParamBuffer(char *pParamFile, char* &pParamData)
874081d237aSliuyi {
875081d237aSliuyi 	FILE *file=NULL;
876081d237aSliuyi 	file = fopen(pParamFile, "rb");
877081d237aSliuyi 	if( !file )
878081d237aSliuyi 	{
879081d237aSliuyi 		if (g_pLogObject)
880081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile);
881081d237aSliuyi 		return false;
882081d237aSliuyi 	}
883081d237aSliuyi 	int iFileSize;
884081d237aSliuyi 	fseek(file,0,SEEK_END);
885081d237aSliuyi 	iFileSize = ftell(file);
886081d237aSliuyi 	fseek(file,0,SEEK_SET);
887081d237aSliuyi 	char *pParamBuf=NULL;
888081d237aSliuyi 	pParamBuf = new char[iFileSize + 12];
889081d237aSliuyi 	if (!pParamBuf)
890081d237aSliuyi 	{
891081d237aSliuyi 		fclose(file);
892081d237aSliuyi 		return false;
893081d237aSliuyi 	}
894081d237aSliuyi 	memset(pParamBuf,0,iFileSize+12);
895081d237aSliuyi 	*(UINT *)(pParamBuf) = 0x4D524150;
896081d237aSliuyi 
897081d237aSliuyi 	int iRead;
898081d237aSliuyi 	iRead = fread(pParamBuf+8,1,iFileSize,file);
899081d237aSliuyi 	if (iRead!=iFileSize)
900081d237aSliuyi 	{
901081d237aSliuyi 		if (g_pLogObject)
902081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize);
903081d237aSliuyi 		fclose(file);
904081d237aSliuyi 		delete []pParamBuf;
905081d237aSliuyi 		return false;
906081d237aSliuyi 	}
907081d237aSliuyi 	fclose(file);
908081d237aSliuyi 
909081d237aSliuyi 	*(UINT *)(pParamBuf+4) = iFileSize;
910081d237aSliuyi 	*(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize);
911081d237aSliuyi 	pParamData = pParamBuf;
912081d237aSliuyi 	return true;
913081d237aSliuyi }
914081d237aSliuyi 
915081d237aSliuyi bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
916081d237aSliuyi {
917081d237aSliuyi 	CRKComm *pComm = NULL;
918081d237aSliuyi 	char *pParamBuf = NULL, writeBuf[512*1024];
919081d237aSliuyi 	int iRet, nParamSec, nParamSize;
920081d237aSliuyi 	bool bRet, bSuccess = false;
921081d237aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER))
922081d237aSliuyi 		return false;
923081d237aSliuyi 
924081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
925081d237aSliuyi 	if (!bRet) {
926081d237aSliuyi 		ERROR_COLOR_ATTR;
927081d237aSliuyi 		printf("Creating Comm Object failed!");
928081d237aSliuyi 		NORMAL_COLOR_ATTR;
929081d237aSliuyi 		printf("\r\n");
930081d237aSliuyi 		return bSuccess;
931081d237aSliuyi 	}
932081d237aSliuyi 	if (!MakeParamBuffer(szParameter, pParamBuf)) {
933081d237aSliuyi 		ERROR_COLOR_ATTR;
934081d237aSliuyi 		printf("Generating parameter failed!");
935081d237aSliuyi 		NORMAL_COLOR_ATTR;
936081d237aSliuyi 		printf("\r\n");
937081d237aSliuyi 		return bSuccess;
938081d237aSliuyi 	}
939081d237aSliuyi 	printf("Writing parameter...\r\n");
940081d237aSliuyi 	nParamSize = *(UINT *)(pParamBuf+4) + 12;
941081d237aSliuyi 	nParamSec = BYTE2SECTOR(nParamSize);
942081d237aSliuyi 	if (nParamSec > 1024) {
943081d237aSliuyi 		ERROR_COLOR_ATTR;
944081d237aSliuyi 		printf("parameter is too large!");
945081d237aSliuyi 		NORMAL_COLOR_ATTR;
946081d237aSliuyi 		printf("\r\n");
947081d237aSliuyi 		return bSuccess;
948081d237aSliuyi 	}
949081d237aSliuyi 	memset(writeBuf, 0, nParamSec*512);
950081d237aSliuyi 	memcpy(writeBuf, pParamBuf, nParamSize);
951081d237aSliuyi 	iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf);
952081d237aSliuyi 	if (iRet != ERR_SUCCESS) {
953081d237aSliuyi 		ERROR_COLOR_ATTR;
954081d237aSliuyi 		printf("Writing parameter failed!");
955081d237aSliuyi 		NORMAL_COLOR_ATTR;
956081d237aSliuyi 		printf("\r\n");
957081d237aSliuyi 		return bSuccess;
958081d237aSliuyi 	}
959081d237aSliuyi 
960081d237aSliuyi 	bSuccess = true;
961081d237aSliuyi 	CURSOR_MOVEUP_LINE(1);
962081d237aSliuyi 	CURSOR_DEL_LINE;
963081d237aSliuyi 	printf("Writing parameter succeeded.\r\n");
964081d237aSliuyi 	return bSuccess;
965081d237aSliuyi }
966081d237aSliuyi 
967c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
968c30d921cSKever Yang {
969c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
970c30d921cSKever Yang 	u32 total_size_sector;
971c30d921cSKever Yang 	CRKComm *pComm = NULL;
972c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
973c29e5f0fSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
974c30d921cSKever Yang 	int iRet;
975c30d921cSKever Yang 	bool bRet, bSuccess = false;
976c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
977c30d921cSKever Yang 		return false;
978c30d921cSKever Yang 
979c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
980c30d921cSKever Yang 	if (!bRet) {
981c30d921cSKever Yang 		ERROR_COLOR_ATTR;
982c30d921cSKever Yang 		printf("Creating Comm Object failed!");
983c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
984c30d921cSKever Yang 		printf("\r\n");
985c30d921cSKever Yang 		return bSuccess;
986c30d921cSKever Yang 	}
98732268622SAndreas Färber 	printf("Writing gpt...\r\n");
988c30d921cSKever Yang 	//1.get flash info
989c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
990c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
991c30d921cSKever Yang 		ERROR_COLOR_ATTR;
992c30d921cSKever Yang 		printf("Reading Flash Info failed!");
993c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
994c30d921cSKever Yang 		printf("\r\n");
995c30d921cSKever Yang 		return bSuccess;
996c30d921cSKever Yang 	}
997c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
998c29e5f0fSliuyi 	if (strstr(szParameter, ".img")) {
999c29e5f0fSliuyi 		if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) {
1000c29e5f0fSliuyi 			ERROR_COLOR_ATTR;
1001c29e5f0fSliuyi 			printf("Loading partition image failed!");
1002c29e5f0fSliuyi 			NORMAL_COLOR_ATTR;
1003c29e5f0fSliuyi 			printf("\r\n");
1004c29e5f0fSliuyi 			return bSuccess;
1005c29e5f0fSliuyi 		}
1006c29e5f0fSliuyi 		update_gpt_disksize(master_gpt, backup_gpt, total_size_sector);
1007c29e5f0fSliuyi 	} else {
1008c30d921cSKever Yang 		//2.get partition from parameter
1009c29e5f0fSliuyi 		bRet = parse_parameter_file(szParameter, vecItems, vecUuid);
1010c30d921cSKever Yang 		if (!bRet) {
1011c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1012c30d921cSKever Yang 			printf("Parsing parameter failed!");
1013c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1014c30d921cSKever Yang 			printf("\r\n");
1015c30d921cSKever Yang 			return bSuccess;
1016c30d921cSKever Yang 		}
1017c29e5f0fSliuyi 		vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33;
1018c30d921cSKever Yang 		//3.generate gpt info
1019c29e5f0fSliuyi 		create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector);
1020c30d921cSKever Yang 		memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
1021c30d921cSKever Yang 		memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
1022c29e5f0fSliuyi 		prepare_gpt_backup(master_gpt, backup_gpt);
1023c29e5f0fSliuyi 	}
1024c29e5f0fSliuyi 
1025c30d921cSKever Yang 	//4. write gpt
1026c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
1027c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
1028c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1029c30d921cSKever Yang 		printf("Writing master gpt failed!");
1030c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1031c30d921cSKever Yang 		printf("\r\n");
1032c30d921cSKever Yang 		return bSuccess;
1033c30d921cSKever Yang 	}
1034c29e5f0fSliuyi 	iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt);
1035c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
1036c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1037c30d921cSKever Yang 		printf("Writing backup gpt failed!");
1038c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1039c30d921cSKever Yang 		printf("\r\n");
1040c30d921cSKever Yang 		return bSuccess;
1041c30d921cSKever Yang 	}
1042c29e5f0fSliuyi 
1043c30d921cSKever Yang 	bSuccess = true;
1044c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
1045c30d921cSKever Yang 	CURSOR_DEL_LINE;
104632268622SAndreas Färber 	printf("Writing gpt succeeded.\r\n");
1047c30d921cSKever Yang 	return bSuccess;
1048c30d921cSKever Yang }
104976af099aSliuyi 
105078884ef4SEddie Cai #include "boot_merger.h"
105178884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
105278884ef4SEddie Cai options gOpts;
105378884ef4SEddie Cai 
105478884ef4SEddie Cai 
105578884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
105678884ef4SEddie Cai char* gConfigPath;
105778884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
105878884ef4SEddie Cai 
105978884ef4SEddie Cai static inline void fixPath(char* path) {
106078884ef4SEddie Cai 	int i, len = strlen(path);
106178884ef4SEddie Cai 	for(i=0; i<len; i++) {
106278884ef4SEddie Cai 		if (path[i] == '\\')
106378884ef4SEddie Cai 			path[i] = '/';
106478884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
106578884ef4SEddie Cai 			path[i] = '\0';
106678884ef4SEddie Cai 	}
106778884ef4SEddie Cai }
106878884ef4SEddie Cai 
106978884ef4SEddie Cai static bool parseChip(FILE* file) {
107078884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
107178884ef4SEddie Cai 		return false;
107278884ef4SEddie Cai 	}
107378884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
107478884ef4SEddie Cai 		return false;
107578884ef4SEddie Cai 	}
107678884ef4SEddie Cai 	printf("chip: %s\n", gOpts.chip);
107778884ef4SEddie Cai 	return true;
107878884ef4SEddie Cai }
107978884ef4SEddie Cai 
108078884ef4SEddie Cai static bool parseVersion(FILE* file) {
108178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
108278884ef4SEddie Cai 		return false;
108378884ef4SEddie Cai 	}
108478884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
108578884ef4SEddie Cai 		return false;
108678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
108778884ef4SEddie Cai 		return false;
108878884ef4SEddie Cai 	}
108978884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
109078884ef4SEddie Cai 		return false;
109178884ef4SEddie Cai 	printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
109278884ef4SEddie Cai 	return true;
109378884ef4SEddie Cai }
109478884ef4SEddie Cai 
109578884ef4SEddie Cai static bool parse471(FILE* file) {
109678884ef4SEddie Cai 	int i, index, pos;
109778884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
109878884ef4SEddie Cai 
109978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
110078884ef4SEddie Cai 		return false;
110178884ef4SEddie Cai 	}
110278884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
110378884ef4SEddie Cai 		return false;
110478884ef4SEddie Cai 	printf("num: %d\n", gOpts.code471Num);
110578884ef4SEddie Cai 	if (!gOpts.code471Num)
110678884ef4SEddie Cai 		return true;
110778884ef4SEddie Cai 	if (gOpts.code471Num < 0)
110878884ef4SEddie Cai 		return false;
110978884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
111078884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
111178884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
111278884ef4SEddie Cai 			return false;
111378884ef4SEddie Cai 		}
111478884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
111578884ef4SEddie Cai 				!= 2)
111678884ef4SEddie Cai 			return false;
111778884ef4SEddie Cai 		index--;
111878884ef4SEddie Cai 		fixPath(buf);
111978884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
112078884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code471Path[index]);
112178884ef4SEddie Cai 	}
112278884ef4SEddie Cai 	pos = ftell(file);
112378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
112478884ef4SEddie Cai 		return false;
112578884ef4SEddie Cai 	}
112678884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
112778884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
112878884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code471Sleep);
112978884ef4SEddie Cai 	return true;
113078884ef4SEddie Cai }
113178884ef4SEddie Cai 
113278884ef4SEddie Cai static bool parse472(FILE* file) {
113378884ef4SEddie Cai 	int i, index, pos;
113478884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
113578884ef4SEddie Cai 
113678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
113778884ef4SEddie Cai 		return false;
113878884ef4SEddie Cai 	}
113978884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
114078884ef4SEddie Cai 		return false;
114178884ef4SEddie Cai 	printf("num: %d\n", gOpts.code472Num);
114278884ef4SEddie Cai 	if (!gOpts.code472Num)
114378884ef4SEddie Cai 		return true;
114478884ef4SEddie Cai 	if (gOpts.code472Num < 0)
114578884ef4SEddie Cai 		return false;
114678884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
114778884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
114878884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
114978884ef4SEddie Cai 			return false;
115078884ef4SEddie Cai 		}
115178884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
115278884ef4SEddie Cai 				!= 2)
115378884ef4SEddie Cai 			return false;
115478884ef4SEddie Cai 		fixPath(buf);
115578884ef4SEddie Cai 		index--;
115678884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
115778884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code472Path[index]);
115878884ef4SEddie Cai 	}
115978884ef4SEddie Cai 	pos = ftell(file);
116078884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
116178884ef4SEddie Cai 		return false;
116278884ef4SEddie Cai 	}
116378884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
116478884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
116578884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code472Sleep);
116678884ef4SEddie Cai 	return true;
116778884ef4SEddie Cai }
116878884ef4SEddie Cai 
116978884ef4SEddie Cai static bool parseLoader(FILE* file) {
117078884ef4SEddie Cai 	int i, j, index, pos;
117178884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
117278884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
117378884ef4SEddie Cai 
117478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
117578884ef4SEddie Cai 		return false;
117678884ef4SEddie Cai 	}
117778884ef4SEddie Cai 	pos = ftell(file);
117878884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
117978884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
118078884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
118178884ef4SEddie Cai 			return false;
118278884ef4SEddie Cai 		}
118378884ef4SEddie Cai 	}
118478884ef4SEddie Cai 	printf("num: %d\n", gOpts.loaderNum);
118578884ef4SEddie Cai 	if (!gOpts.loaderNum)
118678884ef4SEddie Cai 		return false;
118778884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
118878884ef4SEddie Cai 		return false;
118978884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
119078884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
119178884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
119278884ef4SEddie Cai 			return false;
119378884ef4SEddie Cai 		}
119478884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
119578884ef4SEddie Cai 				!= 2)
119678884ef4SEddie Cai 			return false;
119778884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
119878884ef4SEddie Cai 		printf("name%d: %s\n", index, gOpts.loader[index].name);
1199544ec1d4SKlaus Goger 		index++;
120078884ef4SEddie Cai 	}
120178884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
120278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
120378884ef4SEddie Cai 			return false;
120478884ef4SEddie Cai 		}
120578884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
120678884ef4SEddie Cai 				!= 2)
120778884ef4SEddie Cai 			return false;
120878884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
120978884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
121078884ef4SEddie Cai 				fixPath(buf2);
121178884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
121278884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
121378884ef4SEddie Cai 				break;
121478884ef4SEddie Cai 			}
121578884ef4SEddie Cai 		}
121678884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
121778884ef4SEddie Cai 			return false;
121878884ef4SEddie Cai 		}
121978884ef4SEddie Cai 	}
122078884ef4SEddie Cai 	return true;
122178884ef4SEddie Cai }
122278884ef4SEddie Cai 
122378884ef4SEddie Cai static bool parseOut(FILE* file) {
122478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
122578884ef4SEddie Cai 		return false;
122678884ef4SEddie Cai 	}
122778884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
122878884ef4SEddie Cai 		return false;
122978884ef4SEddie Cai 	fixPath(gOpts.outPath);
123078884ef4SEddie Cai 	printf("out: %s\n", gOpts.outPath);
123178884ef4SEddie Cai 	return true;
123278884ef4SEddie Cai }
123378884ef4SEddie Cai 
123478884ef4SEddie Cai 
123578884ef4SEddie Cai void printOpts(FILE* out) {
123678884ef4SEddie Cai 	int i;
123778884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
123878884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
123978884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
124078884ef4SEddie Cai 
124178884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
124278884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
124378884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
124478884ef4SEddie Cai 	}
124578884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
124678884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
124778884ef4SEddie Cai 
124878884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
124978884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
125078884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
125178884ef4SEddie Cai 	}
125278884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
125378884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
125478884ef4SEddie Cai 
125578884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
125678884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
125778884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
125878884ef4SEddie Cai 	}
125978884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
126078884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
126178884ef4SEddie Cai 	}
126278884ef4SEddie Cai 
126378884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
126478884ef4SEddie Cai }
126578884ef4SEddie Cai 
126678884ef4SEddie Cai static bool parseOpts(void) {
126778884ef4SEddie Cai 	bool ret = false;
126878884ef4SEddie Cai 	bool chipOk = false;
126978884ef4SEddie Cai 	bool versionOk = false;
127078884ef4SEddie Cai 	bool code471Ok = true;
127178884ef4SEddie Cai 	bool code472Ok = true;
127278884ef4SEddie Cai 	bool loaderOk = false;
127378884ef4SEddie Cai 	bool outOk = false;
127478884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
127578884ef4SEddie Cai 
127678884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
127778884ef4SEddie Cai 	FILE* file;
127878884ef4SEddie Cai 	file = fopen(configPath, "r");
127978884ef4SEddie Cai 	if (!file) {
128078884ef4SEddie Cai 		fprintf(stderr, "config (%s) not found!\n", configPath);
128108c0d218SKlaus Goger 		if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) {
128278884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
128378884ef4SEddie Cai 			if (file) {
128432268622SAndreas Färber 				fprintf(stderr, "creating defconfig\n");
128578884ef4SEddie Cai 				printOpts(file);
128678884ef4SEddie Cai 			}
128778884ef4SEddie Cai 		}
128878884ef4SEddie Cai 		goto end;
128978884ef4SEddie Cai 	}
129078884ef4SEddie Cai 
129132268622SAndreas Färber 	printf("Starting to parse...\n");
129278884ef4SEddie Cai 
129378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
129478884ef4SEddie Cai 		goto end;
129578884ef4SEddie Cai 	}
129678884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
129778884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
129878884ef4SEddie Cai 			chipOk = parseChip(file);
129978884ef4SEddie Cai 			if (!chipOk) {
130078884ef4SEddie Cai 				printf("parseChip failed!\n");
130178884ef4SEddie Cai 				goto end;
130278884ef4SEddie Cai 			}
130378884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
130478884ef4SEddie Cai 			versionOk = parseVersion(file);
130578884ef4SEddie Cai 			if (!versionOk) {
130678884ef4SEddie Cai 				printf("parseVersion failed!\n");
130778884ef4SEddie Cai 				goto end;
130878884ef4SEddie Cai 			}
130978884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
131078884ef4SEddie Cai 			code471Ok = parse471(file);
131178884ef4SEddie Cai 			if (!code471Ok) {
131278884ef4SEddie Cai 				printf("parse471 failed!\n");
131378884ef4SEddie Cai 				goto end;
131478884ef4SEddie Cai 			}
131578884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
131678884ef4SEddie Cai 			code472Ok = parse472(file);
131778884ef4SEddie Cai 			if (!code472Ok) {
131878884ef4SEddie Cai 				printf("parse472 failed!\n");
131978884ef4SEddie Cai 				goto end;
132078884ef4SEddie Cai 			}
132178884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
132278884ef4SEddie Cai 			loaderOk = parseLoader(file);
132378884ef4SEddie Cai 			if (!loaderOk) {
132478884ef4SEddie Cai 				printf("parseLoader failed!\n");
132578884ef4SEddie Cai 				goto end;
132678884ef4SEddie Cai 			}
132778884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
132878884ef4SEddie Cai 			outOk = parseOut(file);
132978884ef4SEddie Cai 			if (!outOk) {
133078884ef4SEddie Cai 				printf("parseOut failed!\n");
133178884ef4SEddie Cai 				goto end;
133278884ef4SEddie Cai 			}
133378884ef4SEddie Cai 		} else if (buf[0] == '#') {
133478884ef4SEddie Cai 			continue;
133578884ef4SEddie Cai 		} else {
133678884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
133778884ef4SEddie Cai 			goto end;
133878884ef4SEddie Cai 		}
133978884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
134078884ef4SEddie Cai 			goto end;
134178884ef4SEddie Cai 		}
134278884ef4SEddie Cai 	}
134378884ef4SEddie Cai 
134478884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
134578884ef4SEddie Cai 			&& loaderOk && outOk)
134678884ef4SEddie Cai 		ret = true;
134778884ef4SEddie Cai end:
134878884ef4SEddie Cai 	if (file)
134978884ef4SEddie Cai 		fclose(file);
135078884ef4SEddie Cai 	return ret;
135178884ef4SEddie Cai }
135278884ef4SEddie Cai 
135378884ef4SEddie Cai bool initOpts(void) {
135478884ef4SEddie Cai 	//set default opts
135578884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
135678884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
135778884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
135878884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
135978884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
136078884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
136178884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
136278884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
136378884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
136478884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
136578884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
136678884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
136778884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
136878884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
136978884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
137078884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
137178884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
137278884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
137378884ef4SEddie Cai 
137478884ef4SEddie Cai 	return parseOpts();
137578884ef4SEddie Cai }
137678884ef4SEddie Cai 
137778884ef4SEddie Cai /************merge code****************/
137878884ef4SEddie Cai 
137978884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
138078884ef4SEddie Cai 	uint8_t tmp[2] = {0};
138178884ef4SEddie Cai 	int i;
138278884ef4SEddie Cai 	uint32_t ret;
138378884ef4SEddie Cai 	//if (value > 0xFFFF) {
138478884ef4SEddie Cai 	//	return 0;
138578884ef4SEddie Cai 	//}
138678884ef4SEddie Cai 	for(i=0; i < 2; i++) {
138778884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
138878884ef4SEddie Cai 		value /= 100;
138978884ef4SEddie Cai 	}
139078884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
139178884ef4SEddie Cai 
139278884ef4SEddie Cai 	printf("ret: %x\n",ret);
139378884ef4SEddie Cai 	return ret&0xFF;
139478884ef4SEddie Cai }
139578884ef4SEddie Cai 
139678884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
139778884ef4SEddie Cai {
139878884ef4SEddie Cai 	int i;
139978884ef4SEddie Cai 	for (i = 0; i < len; i++) {
140078884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
140178884ef4SEddie Cai 	}
140278884ef4SEddie Cai 	wide[len] = 0;
140378884ef4SEddie Cai }
140478884ef4SEddie Cai 
140578884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
140678884ef4SEddie Cai 	char* end;
140778884ef4SEddie Cai 	char* start;
140878884ef4SEddie Cai 	int len;
140978884ef4SEddie Cai 	if (!path || !dst)
141078884ef4SEddie Cai 		return;
141178884ef4SEddie Cai 	start = strrchr(path, '/');
141278884ef4SEddie Cai 	if (!start)
141378884ef4SEddie Cai 		start = path;
141478884ef4SEddie Cai 	else
141578884ef4SEddie Cai 		start++;
141678884ef4SEddie Cai 	end = strrchr(path, '.');
1417641cfa16SEddie Cai 	if (!end || (end < start))
141878884ef4SEddie Cai 		end = path + strlen(path);
141978884ef4SEddie Cai 	len = end - start;
142078884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
142178884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
142278884ef4SEddie Cai 	str2wide(start, dst, len);
142378884ef4SEddie Cai 
142478884ef4SEddie Cai 
142578884ef4SEddie Cai 		char name[MAX_NAME_LEN];
142678884ef4SEddie Cai 		memset(name, 0, sizeof(name));
142778884ef4SEddie Cai 		memcpy(name, start, len);
142878884ef4SEddie Cai 		printf("path: %s, name: %s\n", path, name);
142978884ef4SEddie Cai 
143078884ef4SEddie Cai }
143178884ef4SEddie Cai 
143278884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
143378884ef4SEddie Cai 	struct stat st;
143478884ef4SEddie Cai 	if(stat(path, &st) < 0)
143578884ef4SEddie Cai 		return false;
143678884ef4SEddie Cai 	*size = st.st_size;
143778884ef4SEddie Cai 	printf("path: %s, size: %d\n", path, *size);
143878884ef4SEddie Cai 	return true;
143978884ef4SEddie Cai }
144078884ef4SEddie Cai 
144178884ef4SEddie Cai static inline rk_time getTime(void) {
144278884ef4SEddie Cai 	rk_time rkTime;
144378884ef4SEddie Cai 
144478884ef4SEddie Cai 	struct tm *tm;
144578884ef4SEddie Cai 	time_t tt = time(NULL);
144678884ef4SEddie Cai 	tm = localtime(&tt);
144778884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
144878884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
144978884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
145078884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
145178884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
145278884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
145378884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
145478884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
145578884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
145678884ef4SEddie Cai 	return rkTime;
145778884ef4SEddie Cai }
145878884ef4SEddie Cai 
145978884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
146078884ef4SEddie Cai 	bool ret = false;
146178884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
146278884ef4SEddie Cai 	uint8_t* buf;
146378884ef4SEddie Cai 
146478884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
146578884ef4SEddie Cai 	if (!inFile)
146678884ef4SEddie Cai 		goto end;
146778884ef4SEddie Cai 
146878884ef4SEddie Cai 	if (!getFileSize(path, &size))
146978884ef4SEddie Cai 		goto end;
147078884ef4SEddie Cai 	if (fix) {
147178884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
147278884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
147378884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
147478884ef4SEddie Cai 		fixSize +=tmp;
147578884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
147678884ef4SEddie Cai 	} else {
147778884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
147878884ef4SEddie Cai 	}
147978884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
148078884ef4SEddie Cai 		goto end;
148178884ef4SEddie Cai 
148278884ef4SEddie Cai 	if (fix) {
148378884ef4SEddie Cai 
148478884ef4SEddie Cai 		buf = gBuf;
148578884ef4SEddie Cai 		size = fixSize;
148678884ef4SEddie Cai 		while(1) {
148778884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
148878884ef4SEddie Cai 			buf += SMALL_PACKET;
148978884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
149078884ef4SEddie Cai 				break;
149178884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
149278884ef4SEddie Cai 		}
149378884ef4SEddie Cai 	} else {
149478884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
149578884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
149678884ef4SEddie Cai 		size +=tmp;
149778884ef4SEddie Cai 		P_RC4(gBuf, size);
149878884ef4SEddie Cai 	}
149978884ef4SEddie Cai 
150078884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
150178884ef4SEddie Cai 		goto end;
150278884ef4SEddie Cai 	ret = true;
150378884ef4SEddie Cai end:
150478884ef4SEddie Cai 	if (inFile)
150578884ef4SEddie Cai 		fclose(inFile);
150678884ef4SEddie Cai 	if (!ret)
150732268622SAndreas Färber 		printf("writing entry (%s) failed\n", path);
150878884ef4SEddie Cai 	return ret;
150978884ef4SEddie Cai }
151078884ef4SEddie Cai 
151178884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
151278884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
151378884ef4SEddie Cai 	uint32_t size;
151478884ef4SEddie Cai 	rk_boot_entry entry;
151578884ef4SEddie Cai 
151632268622SAndreas Färber 	printf("writing: %s\n", path);
1517641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
151878884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
151978884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
152078884ef4SEddie Cai 	entry.type = type;
152178884ef4SEddie Cai 	entry.dataOffset = *offset;
152278884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
152332268622SAndreas Färber 		printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
152478884ef4SEddie Cai 		return false;
152578884ef4SEddie Cai 	}
152678884ef4SEddie Cai 	if (fix)
152778884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
152878884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
152978884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
153032268622SAndreas Färber 	printf("alignment size: %d\n", size);
153178884ef4SEddie Cai 	entry.dataSize = size;
153278884ef4SEddie Cai 	entry.dataDelay = delay;
153378884ef4SEddie Cai 	*offset += size;
153478884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
153578884ef4SEddie Cai 	return true;
153678884ef4SEddie Cai }
153778884ef4SEddie Cai 
153878884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
153978884ef4SEddie Cai 	char buffer[5];
154078884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
154178884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
154278884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
154378884ef4SEddie Cai }
154478884ef4SEddie Cai 
154578884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
154678884ef4SEddie Cai 	printf("chip: %s\n", chip);
154778884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
154878884ef4SEddie Cai 	if(!chip) {
154978884ef4SEddie Cai 		goto end;
155078884ef4SEddie Cai 	}
155178884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
155278884ef4SEddie Cai 		chipType = RK28_DEVICE;
155378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
155478884ef4SEddie Cai 		chipType = RK28_DEVICE;
155578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
155678884ef4SEddie Cai 		chipType = RK281X_DEVICE;
155778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
155878884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
155978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
156078884ef4SEddie Cai 		chipType = RK27_DEVICE;
156178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
156278884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
156378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
156478884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
156578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
156678884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
156778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
156878884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
156978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
157078884ef4SEddie Cai 		chipType = RK29_DEVICE;
157178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
157278884ef4SEddie Cai 		chipType = RK292X_DEVICE;
157378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
157478884ef4SEddie Cai 		chipType = RK30_DEVICE;
157578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
157678884ef4SEddie Cai 		chipType = RK30B_DEVICE;
157778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
157878884ef4SEddie Cai 		chipType = RK31_DEVICE;
157978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
158078884ef4SEddie Cai 		chipType = RK32_DEVICE;
158178884ef4SEddie Cai 	} else {
158278884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
158378884ef4SEddie Cai 	}
158478884ef4SEddie Cai 
158578884ef4SEddie Cai end:
158678884ef4SEddie Cai 	printf("type: 0x%x\n", chipType);
158778884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
158832268622SAndreas Färber 		printf("chip type not supported!\n");
158978884ef4SEddie Cai 	}
159078884ef4SEddie Cai 	return chipType;
159178884ef4SEddie Cai }
159278884ef4SEddie Cai 
159378884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
159478884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
159578884ef4SEddie Cai 	hdr->tag = TAG;
159678884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
159778884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
159878884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
159978884ef4SEddie Cai 	hdr->releaseTime = getTime();
160078884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
160178884ef4SEddie Cai 
160278884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
160378884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
160478884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
160578884ef4SEddie Cai 
160678884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
160778884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
160878884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
160978884ef4SEddie Cai 
161078884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
161178884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
161278884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
161378884ef4SEddie Cai #ifndef USE_P_RC4
161478884ef4SEddie Cai 	hdr->rc4Flag = 1;
161578884ef4SEddie Cai #endif
161678884ef4SEddie Cai }
161778884ef4SEddie Cai 
161878884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
161978884ef4SEddie Cai 	uint32_t size = 0;
162078884ef4SEddie Cai 	uint32_t crc = 0;
162178884ef4SEddie Cai 
162278884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
162378884ef4SEddie Cai 	getFileSize(path, &size);
162478884ef4SEddie Cai 	if (!file)
162578884ef4SEddie Cai 		goto end;
162678884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
162778884ef4SEddie Cai 		goto end;
162878884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
162978884ef4SEddie Cai 	printf("crc: 0x%08x\n", crc);
163078884ef4SEddie Cai end:
163178884ef4SEddie Cai 	if (file)
163278884ef4SEddie Cai 		fclose(file);
163378884ef4SEddie Cai 	return crc;
163478884ef4SEddie Cai }
163578884ef4SEddie Cai 
163678884ef4SEddie Cai bool mergeBoot(void) {
163778884ef4SEddie Cai 	uint32_t dataOffset;
163878884ef4SEddie Cai 	bool ret = false;
163978884ef4SEddie Cai 	int i;
164078884ef4SEddie Cai 	FILE* outFile;
164178884ef4SEddie Cai 	uint32_t crc;
164278884ef4SEddie Cai 	rk_boot_header hdr;
164378884ef4SEddie Cai 
164478884ef4SEddie Cai 	if (!initOpts())
164578884ef4SEddie Cai 		return false;
164678884ef4SEddie Cai 	{
164778884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
164878884ef4SEddie Cai 		char version[MAX_LINE_LEN];
164978884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
165078884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
165178884ef4SEddie Cai 			subfix[0] = '\0';
165278884ef4SEddie Cai 		}
165378884ef4SEddie Cai 		strcat(gOpts.outPath, version);
165478884ef4SEddie Cai 		printf("fix opt: %s\n", gOpts.outPath);
165578884ef4SEddie Cai 	}
165678884ef4SEddie Cai 
165778884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
165878884ef4SEddie Cai 	printOpts(stdout);
165978884ef4SEddie Cai 	printf("---------------\n\n");
166078884ef4SEddie Cai 
166178884ef4SEddie Cai 
166278884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
166378884ef4SEddie Cai 	if (!outFile) {
166432268622SAndreas Färber 		printf("Opening output file (%s) failed\n", gOpts.outPath);
166578884ef4SEddie Cai 		goto end;
166678884ef4SEddie Cai 	}
166778884ef4SEddie Cai 
166878884ef4SEddie Cai 	getBoothdr(&hdr);
166932268622SAndreas Färber 	printf("Writing header...\n");
167078884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
167178884ef4SEddie Cai 
167278884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
167378884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
167478884ef4SEddie Cai 		sizeof(rk_boot_entry);
167578884ef4SEddie Cai 
167632268622SAndreas Färber 	printf("Writing code 471 entry...\n");
167778884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
167878884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
167978884ef4SEddie Cai 					&dataOffset, NULL, false))
168078884ef4SEddie Cai 			goto end;
168178884ef4SEddie Cai 	}
168232268622SAndreas Färber 	printf("Writing code 472 entry...\n");
168378884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
168478884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
168578884ef4SEddie Cai 					&dataOffset, NULL, false))
168678884ef4SEddie Cai 			goto end;
168778884ef4SEddie Cai 	}
168832268622SAndreas Färber 	printf("Writing loader entry...\n");
168978884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
169078884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
169178884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
169278884ef4SEddie Cai 			goto end;
169378884ef4SEddie Cai 	}
169478884ef4SEddie Cai 
169532268622SAndreas Färber 	printf("Writing code 471...\n");
169678884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
169778884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
169878884ef4SEddie Cai 			goto end;
169978884ef4SEddie Cai 	}
170032268622SAndreas Färber 	printf("Writing code 472...\n");
170178884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
170278884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
170378884ef4SEddie Cai 			goto end;
170478884ef4SEddie Cai 	}
170532268622SAndreas Färber 	printf("Writing loader...\n");
170678884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
170778884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
170878884ef4SEddie Cai 			goto end;
170978884ef4SEddie Cai 	}
171078884ef4SEddie Cai 	fflush(outFile);
171178884ef4SEddie Cai 
171232268622SAndreas Färber 	printf("Writing crc...\n");
171378884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
171478884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
171578884ef4SEddie Cai 		goto end;
171632268622SAndreas Färber 	printf("Done.\n");
171778884ef4SEddie Cai 	ret = true;
171878884ef4SEddie Cai end:
171978884ef4SEddie Cai 	if (outFile)
172078884ef4SEddie Cai 		fclose(outFile);
172178884ef4SEddie Cai 	return ret;
172278884ef4SEddie Cai }
172378884ef4SEddie Cai 
172478884ef4SEddie Cai /************merge code end************/
172578884ef4SEddie Cai /************unpack code***************/
172678884ef4SEddie Cai 
172778884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
172878884ef4SEddie Cai {
172978884ef4SEddie Cai 	int i;
173078884ef4SEddie Cai 	for (i = 0; i < len; i++) {
173178884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
173278884ef4SEddie Cai 	}
173378884ef4SEddie Cai }
173478884ef4SEddie Cai 
173578884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
173678884ef4SEddie Cai 		FILE* inFile) {
173778884ef4SEddie Cai 	bool ret = false;
173878884ef4SEddie Cai 	int size, i;
173978884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
174078884ef4SEddie Cai 	if (!outFile)
174178884ef4SEddie Cai 		goto end;
174232268622SAndreas Färber 	printf("unpacking entry (%s)\n", name);
174378884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
174478884ef4SEddie Cai 	size = entry->dataSize;
174578884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
174678884ef4SEddie Cai 		goto end;
174778884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
174878884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
174978884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
175078884ef4SEddie Cai 		if (size % SMALL_PACKET)
175178884ef4SEddie Cai 		{
175278884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
175378884ef4SEddie Cai 		}
175478884ef4SEddie Cai 	} else {
175578884ef4SEddie Cai 		P_RC4(gBuf, size);
175678884ef4SEddie Cai 	}
175778884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
175878884ef4SEddie Cai 		goto end;
175978884ef4SEddie Cai 	ret = true;
176078884ef4SEddie Cai end:
176178884ef4SEddie Cai 	if (outFile)
176278884ef4SEddie Cai 		fclose(outFile);
176378884ef4SEddie Cai 	return ret;
176478884ef4SEddie Cai }
176578884ef4SEddie Cai 
176678884ef4SEddie Cai bool unpackBoot(char* path) {
176778884ef4SEddie Cai 	bool ret = false;
176878884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
176978884ef4SEddie Cai 	int entryNum, i;
177078884ef4SEddie Cai 	char name[MAX_NAME_LEN];
177178884ef4SEddie Cai 	rk_boot_entry* entrys;
177278884ef4SEddie Cai 	if (!inFile) {
177378884ef4SEddie Cai 		fprintf(stderr, "loader (%s) not found\n", path);
177478884ef4SEddie Cai 		goto end;
177578884ef4SEddie Cai 	}
177678884ef4SEddie Cai 
177778884ef4SEddie Cai 	rk_boot_header hdr;
177878884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
177932268622SAndreas Färber 		fprintf(stderr, "reading header failed\n");
178078884ef4SEddie Cai 		goto end;
178178884ef4SEddie Cai 	}
178278884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
178378884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
178478884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
178578884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
178632268622SAndreas Färber 		fprintf(stderr, "reading data failed\n");
178778884ef4SEddie Cai 		goto end;
178878884ef4SEddie Cai 	}
178978884ef4SEddie Cai 
179078884ef4SEddie Cai 	printf("entry num: %d\n", entryNum);
179178884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
179278884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
179378884ef4SEddie Cai 
179478884ef4SEddie Cai 		printf("entry: t=%d, name=%s, off=%d, size=%d\n",
179578884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
179678884ef4SEddie Cai 				entrys[i].dataSize);
179778884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
179832268622SAndreas Färber 			fprintf(stderr, "unpacking entry (%s) failed\n", name);
179978884ef4SEddie Cai 			goto end;
180078884ef4SEddie Cai 		}
180178884ef4SEddie Cai 	}
180278884ef4SEddie Cai 	printf("done\n");
180378884ef4SEddie Cai 	ret = true;
180478884ef4SEddie Cai end:
180578884ef4SEddie Cai 	if (inFile)
180678884ef4SEddie Cai 		fclose(inFile);
180778884ef4SEddie Cai 	return ret;
180878884ef4SEddie Cai }
180978884ef4SEddie Cai 
181076af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
181176af099aSliuyi {
181276af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
181376af099aSliuyi 		return false;
181476af099aSliuyi 	CRKImage *pImage = NULL;
181576af099aSliuyi 	CRKBoot *pBoot = NULL;
181676af099aSliuyi 	bool bRet, bSuccess = false;
181776af099aSliuyi 	int iRet;
181876af099aSliuyi 
181976af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
182076af099aSliuyi 	if (!bRet){
182176af099aSliuyi 		ERROR_COLOR_ATTR;
182232268622SAndreas Färber 		printf("Opening loader failed, exiting download boot!");
182376af099aSliuyi 		NORMAL_COLOR_ATTR;
182476af099aSliuyi 		printf("\r\n");
182576af099aSliuyi 		return bSuccess;
182676af099aSliuyi 	} else {
182776af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
182876af099aSliuyi 		CRKComm *pComm = NULL;
182976af099aSliuyi 		CRKDevice *pDevice = NULL;
183076af099aSliuyi 
183176af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
183276af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
183376af099aSliuyi 		if (!bRet) {
183476af099aSliuyi 			if (pImage)
183576af099aSliuyi 				delete pImage;
183676af099aSliuyi 			ERROR_COLOR_ATTR;
183776af099aSliuyi 			printf("Creating Comm Object failed!");
183876af099aSliuyi 			NORMAL_COLOR_ATTR;
183976af099aSliuyi 			printf("\r\n");
184076af099aSliuyi 			return bSuccess;
184176af099aSliuyi 		}
184276af099aSliuyi 
184376af099aSliuyi 		pDevice = new CRKDevice(dev);
184476af099aSliuyi 		if (!pDevice) {
184576af099aSliuyi 			if (pImage)
184676af099aSliuyi 				delete pImage;
184776af099aSliuyi 			if (pComm)
184876af099aSliuyi 				delete pComm;
184976af099aSliuyi 			ERROR_COLOR_ATTR;
185076af099aSliuyi 			printf("Creating device object failed!");
185176af099aSliuyi 			NORMAL_COLOR_ATTR;
185276af099aSliuyi 			printf("\r\n");
185376af099aSliuyi 			return bSuccess;
185476af099aSliuyi 		}
185576af099aSliuyi 
185676af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
185732268622SAndreas Färber 		printf("Downloading bootloader...\r\n");
185876af099aSliuyi 		iRet = pDevice->DownloadBoot();
185976af099aSliuyi 
186076af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
186176af099aSliuyi 		CURSOR_DEL_LINE;
186276af099aSliuyi 		if (iRet == 0) {
186376af099aSliuyi 			bSuccess = true;
186432268622SAndreas Färber 			printf("Downloading bootloader succeeded.\r\n");
186576af099aSliuyi 		}
186676af099aSliuyi 		else
186732268622SAndreas Färber 			printf("Downloading bootloader failed!\r\n");
186876af099aSliuyi 
186976af099aSliuyi 		if (pImage)
187076af099aSliuyi 			delete pImage;
187176af099aSliuyi 		if(pDevice)
187276af099aSliuyi 			delete pDevice;
187376af099aSliuyi 	}
187476af099aSliuyi 	return bSuccess;
187576af099aSliuyi }
1876c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1877c30d921cSKever Yang {
1878c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1879c30d921cSKever Yang 		return false;
1880c30d921cSKever Yang 	CRKImage *pImage = NULL;
1881c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1882c30d921cSKever Yang 	CRKComm *pComm = NULL;
1883c30d921cSKever Yang 	bool bRet, bSuccess = false;
1884c30d921cSKever Yang 	int iRet;
1885*aca206f7SPeter Robinson 	signed char index;
1886c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1887c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1888c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1889c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1890c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1891c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1892c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1893c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1894c30d921cSKever Yang 	if (!bRet){
1895c30d921cSKever Yang 		ERROR_COLOR_ATTR;
189632268622SAndreas Färber 		printf("Opening loader failed, exiting upgrade loader!");
1897c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1898c30d921cSKever Yang 		printf("\r\n");
1899c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1900c30d921cSKever Yang 	} else {
1901c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1902c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1903c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1904c30d921cSKever Yang 		if (!bRet) {
1905c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1906c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1907c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1908c30d921cSKever Yang 			printf("\r\n");
1909c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1910c30d921cSKever Yang 		}
1911c30d921cSKever Yang 
191232268622SAndreas Färber 		printf("Upgrading loader...\r\n");
1913c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1914c30d921cSKever Yang 		if (index == -1) {
1915c30d921cSKever Yang 			if (g_pLogObject) {
191632268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1917c30d921cSKever Yang 			}
1918c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1919c30d921cSKever Yang 		}
1920c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1921c30d921cSKever Yang 		if (!bRet) {
1922c30d921cSKever Yang 			if (g_pLogObject) {
192332268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1924c30d921cSKever Yang 			}
1925c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1926c30d921cSKever Yang 		}
1927c30d921cSKever Yang 
1928c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1929c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1930c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1931c30d921cSKever Yang 			if (g_pLogObject) {
193232268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1933c30d921cSKever Yang 			}
1934c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1935c30d921cSKever Yang 		}
1936c30d921cSKever Yang 
1937c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1938c30d921cSKever Yang 		if (index == -1) {
1939c30d921cSKever Yang 			if (g_pLogObject) {
194032268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1941c30d921cSKever Yang 			}
1942c30d921cSKever Yang 			delete []loaderCodeBuffer;
1943c30d921cSKever Yang 			return -4;
1944c30d921cSKever Yang 		}
1945c30d921cSKever Yang 
1946c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1947c30d921cSKever Yang 		if (!bRet) {
1948c30d921cSKever Yang 			if (g_pLogObject) {
194932268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1950c30d921cSKever Yang 			}
1951c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1952c30d921cSKever Yang 		}
1953c30d921cSKever Yang 
1954c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1955c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1956c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1957c30d921cSKever Yang 			if (g_pLogObject) {
195832268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1959c30d921cSKever Yang 			}
1960c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1961c30d921cSKever Yang 		}
1962c30d921cSKever Yang 
1963c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1964c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1965c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1966c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1967c30d921cSKever Yang 		if (!pIDBData) {
1968c30d921cSKever Yang 			ERROR_COLOR_ATTR;
196932268622SAndreas Färber 			printf("Allocating memory failed!");
1970c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1971c30d921cSKever Yang 			printf("\r\n");
1972c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1973c30d921cSKever Yang 		}
1974c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
1975b38fe5fcSliuyi 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
1976c30d921cSKever Yang 		if (iRet != 0) {
1977c30d921cSKever Yang 			ERROR_COLOR_ATTR;
197832268622SAndreas Färber 			printf("Making idblock failed!");
1979c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1980c30d921cSKever Yang 			printf("\r\n");
1981c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1982c30d921cSKever Yang 		}
1983c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
1984c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
1985c30d921cSKever Yang 		CURSOR_DEL_LINE;
1986c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
1987b38fe5fcSliuyi 			//pComm->Reset_Usb_Device();
1988c30d921cSKever Yang 			bSuccess = true;
198932268622SAndreas Färber 			printf("Upgrading loader succeeded.\r\n");
1990c30d921cSKever Yang 		} else {
199132268622SAndreas Färber 			printf("Upgrading loader failed!\r\n");
1992c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1993c30d921cSKever Yang 		}
1994c30d921cSKever Yang 	}
1995c30d921cSKever Yang Exit_UpgradeLoader:
1996c30d921cSKever Yang 	if (pImage)
1997c30d921cSKever Yang 		delete pImage;
1998c30d921cSKever Yang 	if (pComm)
1999c30d921cSKever Yang 		delete pComm;
2000c30d921cSKever Yang 	if (loaderCodeBuffer)
2001c30d921cSKever Yang 		delete []loaderCodeBuffer;
2002c30d921cSKever Yang 	if (loaderDataBuffer)
2003c30d921cSKever Yang 		delete []loaderDataBuffer;
2004c30d921cSKever Yang 	if (pIDBData)
2005c30d921cSKever Yang 		delete []pIDBData;
2006c30d921cSKever Yang 	return bSuccess;
2007c30d921cSKever Yang }
20083dc7e3ceSliuyi bool print_gpt(STRUCT_RKDEVICE_DESC &dev)
20093dc7e3ceSliuyi {
20103dc7e3ceSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
20113dc7e3ceSliuyi 		return false;
20123dc7e3ceSliuyi 	u8 master_gpt[34 * SECTOR_SIZE];
20133dc7e3ceSliuyi 	gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE);
20143dc7e3ceSliuyi 	bool bRet, bSuccess = false;
20153dc7e3ceSliuyi 	int iRet;
20163dc7e3ceSliuyi 	gpt_entry  *gptEntry  = NULL;
20173dc7e3ceSliuyi 	u32 i,j;
20183dc7e3ceSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
20193dc7e3ceSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
20203dc7e3ceSliuyi 	CRKComm *pComm = NULL;
20213dc7e3ceSliuyi 	char partName[36];
20223dc7e3ceSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
20233dc7e3ceSliuyi 	if (!bRet) {
20243dc7e3ceSliuyi 		ERROR_COLOR_ATTR;
20253dc7e3ceSliuyi 		printf("Creating Comm Object failed!");
20263dc7e3ceSliuyi 		NORMAL_COLOR_ATTR;
20273dc7e3ceSliuyi 		printf("\r\n");
20283dc7e3ceSliuyi 		return bSuccess;
20293dc7e3ceSliuyi 	}
20303dc7e3ceSliuyi 	iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt);
20313dc7e3ceSliuyi 	if(ERR_SUCCESS == iRet) {
20323dc7e3ceSliuyi 		if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
20333dc7e3ceSliuyi 			goto Exit_PrintGpt;
20343dc7e3ceSliuyi 		}
20353dc7e3ceSliuyi 
20363dc7e3ceSliuyi 	} else {
20373dc7e3ceSliuyi 		if (g_pLogObject)
20383dc7e3ceSliuyi 				g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
20393dc7e3ceSliuyi 		printf("Read GPT failed!\r\n");
20403dc7e3ceSliuyi 		goto Exit_PrintGpt;
20413dc7e3ceSliuyi 	}
20423dc7e3ceSliuyi 
2043081d237aSliuyi 	printf("**********Partition Info(GPT)**********\r\n");
20443dc7e3ceSliuyi 	printf("NO  LBA       Name                \r\n");
20453dc7e3ceSliuyi 	for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) {
20463dc7e3ceSliuyi 		gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
20473dc7e3ceSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
20483dc7e3ceSliuyi 			break;
20493dc7e3ceSliuyi 		memset(partName, 0 , 36);
20503dc7e3ceSliuyi 		j = 0;
20513dc7e3ceSliuyi 		while (gptEntry->partition_name[j]) {
20523dc7e3ceSliuyi 			partName[j] = (char)gptEntry->partition_name[j];
20533dc7e3ceSliuyi 			j++;
20543dc7e3ceSliuyi 		}
20553dc7e3ceSliuyi 		printf("%02d  %08X  %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName);
20563dc7e3ceSliuyi 	}
20573dc7e3ceSliuyi 	bSuccess = true;
20583dc7e3ceSliuyi Exit_PrintGpt:
20593dc7e3ceSliuyi 	if (pComm)
20603dc7e3ceSliuyi 		delete pComm;
20613dc7e3ceSliuyi 	return bSuccess;
20623dc7e3ceSliuyi }
2063081d237aSliuyi bool print_parameter(STRUCT_RKDEVICE_DESC &dev)
2064081d237aSliuyi {
2065081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2066081d237aSliuyi 		return false;
2067081d237aSliuyi 	u8 param_buf[512 * SECTOR_SIZE];
2068081d237aSliuyi 	bool bRet, bSuccess = false;
2069081d237aSliuyi 	int iRet;
2070081d237aSliuyi 	u32 i, nParamSize;
2071081d237aSliuyi 	CRKComm *pComm = NULL;
2072081d237aSliuyi 	PARAM_ITEM_VECTOR vecParamItem;
2073081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuidItem;
2074081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2075081d237aSliuyi 	if (!bRet) {
2076081d237aSliuyi 		ERROR_COLOR_ATTR;
2077081d237aSliuyi 		printf("Creating Comm Object failed!");
2078081d237aSliuyi 		NORMAL_COLOR_ATTR;
2079081d237aSliuyi 		printf("\r\n");
2080081d237aSliuyi 		return bSuccess;
2081081d237aSliuyi 	}
2082081d237aSliuyi 	iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf);
2083081d237aSliuyi 	if(ERR_SUCCESS == iRet) {
2084081d237aSliuyi 		if (*(u32 *)param_buf != 0x4D524150) {
2085081d237aSliuyi 			goto Exit_PrintParam;
2086081d237aSliuyi 		}
2087081d237aSliuyi 
2088081d237aSliuyi 	} else {
2089081d237aSliuyi 		if (g_pLogObject)
2090081d237aSliuyi 				g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2091081d237aSliuyi 		printf("Read parameter failed!\r\n");
2092081d237aSliuyi 		goto Exit_PrintParam;
2093081d237aSliuyi 	}
2094081d237aSliuyi 	nParamSize = *(u32 *)(param_buf + 4);
2095081d237aSliuyi 	memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8);
2096081d237aSliuyi 
2097081d237aSliuyi 	bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem);
2098081d237aSliuyi 	if (!bRet) {
2099081d237aSliuyi 		if (g_pLogObject)
2100081d237aSliuyi 				g_pLogObject->Record("Error: parse parameter failed");
2101081d237aSliuyi 		printf("Parse parameter failed!\r\n");
2102081d237aSliuyi 		goto Exit_PrintParam;
2103081d237aSliuyi 	}
2104081d237aSliuyi 	printf("**********Partition Info(parameter)**********\r\n");
2105081d237aSliuyi 	printf("NO  LBA       Name                \r\n");
2106081d237aSliuyi 	for (i = 0; i < vecParamItem.size(); i++) {
2107081d237aSliuyi 		printf("%02d  %08X  %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName);
2108081d237aSliuyi 	}
2109081d237aSliuyi 	bSuccess = true;
2110081d237aSliuyi Exit_PrintParam:
2111081d237aSliuyi 	if (pComm)
2112081d237aSliuyi 		delete pComm;
2113081d237aSliuyi 	return bSuccess;
2114081d237aSliuyi }
2115c30d921cSKever Yang 
211676af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
211776af099aSliuyi {
211876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
211976af099aSliuyi 		return false;
212076af099aSliuyi 	CRKImage *pImage = NULL;
212176af099aSliuyi 	bool bRet, bSuccess = false;
212276af099aSliuyi 	int iRet;
212376af099aSliuyi 	CRKScan *pScan = NULL;
212476af099aSliuyi 	pScan = new CRKScan();
212576af099aSliuyi 	pScan->SetVidPid();
212676af099aSliuyi 
212776af099aSliuyi 	CRKComm *pComm = NULL;
212876af099aSliuyi 	CRKDevice *pDevice = NULL;
212976af099aSliuyi 
213076af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
213176af099aSliuyi 	if (!bRet) {
213276af099aSliuyi 		if (pScan)
213376af099aSliuyi 			delete pScan;
213476af099aSliuyi 		ERROR_COLOR_ATTR;
213576af099aSliuyi 		printf("Creating Comm Object failed!");
213676af099aSliuyi 		NORMAL_COLOR_ATTR;
213776af099aSliuyi 		printf("\r\n");
213876af099aSliuyi 		return bSuccess;
213976af099aSliuyi 	}
214076af099aSliuyi 
214176af099aSliuyi 	pDevice = new CRKDevice(dev);
214276af099aSliuyi 	if (!pDevice) {
214376af099aSliuyi 		if (pComm)
214476af099aSliuyi 			delete pComm;
214576af099aSliuyi 		if (pScan)
214676af099aSliuyi 			delete pScan;
214776af099aSliuyi 		ERROR_COLOR_ATTR;
214876af099aSliuyi 		printf("Creating device object failed!");
214976af099aSliuyi 		NORMAL_COLOR_ATTR;
215076af099aSliuyi 		printf("\r\n");
215176af099aSliuyi 		return bSuccess;
215276af099aSliuyi 	}
215376af099aSliuyi 
215476af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
215576af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
215676af099aSliuyi 
215732268622SAndreas Färber 	printf("Starting to erase flash...\r\n");
21586502326dSliuyi 	bRet = pDevice->GetFlashInfo();
21596502326dSliuyi 	if (!bRet) {
21606502326dSliuyi 		if (pDevice)
21616502326dSliuyi 			delete pDevice;
21626502326dSliuyi 		if (pScan)
21636502326dSliuyi 			delete pScan;
21646502326dSliuyi 		ERROR_COLOR_ATTR;
21656502326dSliuyi 		printf("Getting flash info from device failed!");
21666502326dSliuyi 		NORMAL_COLOR_ATTR;
21676502326dSliuyi 		printf("\r\n");
21686502326dSliuyi 		return bSuccess;
21696502326dSliuyi 	}
217076af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
217176af099aSliuyi 	if (pDevice)
217276af099aSliuyi 		delete pDevice;
217376af099aSliuyi 
217476af099aSliuyi 	if (iRet == 0) {
217576af099aSliuyi 		if (pScan) {
217676af099aSliuyi 			pScan->SetVidPid();
217776af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
217876af099aSliuyi 			delete pScan;
217976af099aSliuyi 		}
218076af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
218176af099aSliuyi 		CURSOR_DEL_LINE;
218276af099aSliuyi 		bSuccess = true;
218332268622SAndreas Färber 		printf("Erasing flash complete.\r\n");
218476af099aSliuyi 	}
218576af099aSliuyi 
218676af099aSliuyi 	return bSuccess;
218776af099aSliuyi }
218876af099aSliuyi 
218976af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
219076af099aSliuyi {
219176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
219276af099aSliuyi 		return false;
219376af099aSliuyi 	CRKUsbComm *pComm = NULL;
219476af099aSliuyi 	bool bRet, bSuccess = false;
219576af099aSliuyi 	int iRet;
219676af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
219776af099aSliuyi 	if (bRet) {
219876af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
219976af099aSliuyi 		if (iRet != ERR_SUCCESS) {
220076af099aSliuyi 			if (g_pLogObject)
220176af099aSliuyi 				g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
220232268622SAndreas Färber 			printf("Test Device failed!\r\n");
220376af099aSliuyi 		} else {
220476af099aSliuyi 			bSuccess = true;
220576af099aSliuyi 			printf("Test Device OK.\r\n");
220676af099aSliuyi 		}
220776af099aSliuyi 	} else {
220832268622SAndreas Färber 		printf("Test Device quit, creating comm object failed!\r\n");
220976af099aSliuyi 	}
221076af099aSliuyi 	if (pComm) {
221176af099aSliuyi 		delete pComm;
221276af099aSliuyi 		pComm = NULL;
221376af099aSliuyi 	}
221476af099aSliuyi 	return bSuccess;
221576af099aSliuyi }
221676af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
221776af099aSliuyi {
221876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
221976af099aSliuyi 		return false;
222076af099aSliuyi 	CRKUsbComm *pComm = NULL;
222176af099aSliuyi 	bool bRet, bSuccess = false;
222276af099aSliuyi 	int iRet;
222376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
222476af099aSliuyi 	if (bRet) {
222576af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
222676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
222776af099aSliuyi 			if (g_pLogObject)
222876af099aSliuyi 				g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
222932268622SAndreas Färber 			printf("Reset Device failed!\r\n");
223076af099aSliuyi 		} else {
223176af099aSliuyi 			bSuccess = true;
223276af099aSliuyi 			printf("Reset Device OK.\r\n");
223376af099aSliuyi 		}
223476af099aSliuyi 	} else {
223532268622SAndreas Färber 		printf("Reset Device quit, creating comm object failed!\r\n");
223676af099aSliuyi 	}
223776af099aSliuyi 	if (pComm) {
223876af099aSliuyi 		delete pComm;
223976af099aSliuyi 		pComm = NULL;
224076af099aSliuyi 	}
224176af099aSliuyi 	return bSuccess;
224276af099aSliuyi }
224376af099aSliuyi 
224476af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
224576af099aSliuyi {
224676af099aSliuyi 	CRKUsbComm *pComm = NULL;
224776af099aSliuyi 	bool bRet, bSuccess = false;
224876af099aSliuyi 	int iRet;
224976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
225076af099aSliuyi 		return bSuccess;
225176af099aSliuyi 
225276af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
225376af099aSliuyi 	if (bRet) {
225476af099aSliuyi 		BYTE flashID[5];
225576af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
225676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
225776af099aSliuyi 			if (g_pLogObject)
225876af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
225932268622SAndreas Färber 			printf("Reading flash ID failed!\r\n");
226076af099aSliuyi 		} else {
226176af099aSliuyi 			printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
226276af099aSliuyi 			bSuccess = true;
226376af099aSliuyi 		}
226476af099aSliuyi 	} else {
226532268622SAndreas Färber 		printf("Read Flash ID quit, creating comm object failed!\r\n");
226676af099aSliuyi 	}
226776af099aSliuyi 	if (pComm) {
226876af099aSliuyi 		delete pComm;
226976af099aSliuyi 		pComm = NULL;
227076af099aSliuyi 	}
227176af099aSliuyi 	return bSuccess;
227276af099aSliuyi }
227376af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
227476af099aSliuyi {
227576af099aSliuyi 	CRKUsbComm *pComm = NULL;
227676af099aSliuyi 	bool bRet, bSuccess = false;
227776af099aSliuyi 	int iRet;
227876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
227976af099aSliuyi 		return bSuccess;
228076af099aSliuyi 
228176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
228276af099aSliuyi 	if (bRet) {
228376af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
228476af099aSliuyi 		UINT uiRead;
228576af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
228676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
228776af099aSliuyi 			if (g_pLogObject)
228876af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
228932268622SAndreas Färber 			printf("Read Flash Info failed!\r\n");
229076af099aSliuyi 		} else {
229176af099aSliuyi 			printf("Flash Info:\r\n");
229276af099aSliuyi 			if (info.bManufCode <= 7) {
229376af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
229476af099aSliuyi 			}
229576af099aSliuyi 			else
229676af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
229776af099aSliuyi 
229876af099aSliuyi 			printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
229976af099aSliuyi 			printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
230076af099aSliuyi 			printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
230176af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
230276af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
230376af099aSliuyi 			printf("\tFlash CS: ");
230476af099aSliuyi 			for(int i = 0; i < 8; i++) {
230576af099aSliuyi 				if( info.bFlashCS & (1 << i) )
230676af099aSliuyi 					printf("Flash<%d> ", i);
230776af099aSliuyi 			}
230876af099aSliuyi 			printf("\r\n");
230976af099aSliuyi 			bSuccess = true;
231076af099aSliuyi 		}
231176af099aSliuyi 	}else {
231232268622SAndreas Färber 		printf("Read Flash Info quit, creating comm object failed!\r\n");
231376af099aSliuyi 	}
231476af099aSliuyi 	if (pComm) {
231576af099aSliuyi 		delete pComm;
231676af099aSliuyi 		pComm = NULL;
231776af099aSliuyi 	}
231876af099aSliuyi 	return bSuccess;
231976af099aSliuyi }
232076af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
232176af099aSliuyi {
232276af099aSliuyi 	CRKUsbComm *pComm = NULL;
232376af099aSliuyi 	bool bRet, bSuccess = false;
232476af099aSliuyi 	int iRet;
232576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
232676af099aSliuyi 		return bSuccess;
232776af099aSliuyi 
232876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
232976af099aSliuyi 	if (bRet) {
233076af099aSliuyi 		BYTE chipInfo[16];
233176af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
233276af099aSliuyi 		if (iRet != ERR_SUCCESS) {
233376af099aSliuyi 			if (g_pLogObject)
233476af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
233532268622SAndreas Färber 			printf("Read Chip Info failed!\r\n");
233676af099aSliuyi 		} else {
233776af099aSliuyi 			string strChipInfo;
233876af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
233976af099aSliuyi 			printf("Chip Info: %s\r\n", strChipInfo.c_str());
234076af099aSliuyi 			bSuccess = true;
234176af099aSliuyi 		}
234276af099aSliuyi 	} else {
234332268622SAndreas Färber 		printf("Read Chip Info quit, creating comm object failed!\r\n");
234476af099aSliuyi 	}
234576af099aSliuyi 	if (pComm) {
234676af099aSliuyi 		delete pComm;
234776af099aSliuyi 		pComm = NULL;
234876af099aSliuyi 	}
234976af099aSliuyi 	return bSuccess;
235076af099aSliuyi }
2351081d237aSliuyi bool read_capability(STRUCT_RKDEVICE_DESC &dev)
2352081d237aSliuyi {
2353081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2354081d237aSliuyi 	bool bRet, bSuccess = false;
2355081d237aSliuyi 	int iRet;
2356081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2357081d237aSliuyi 		return bSuccess;
2358081d237aSliuyi 
2359081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2360081d237aSliuyi 	if (bRet) {
2361081d237aSliuyi 
2362081d237aSliuyi 		BYTE capability[8];
2363081d237aSliuyi 		iRet = pComm->RKU_ReadCapability(capability);
2364081d237aSliuyi 		if (iRet != ERR_SUCCESS)
2365081d237aSliuyi 		{
2366081d237aSliuyi 			if (g_pLogObject)
2367081d237aSliuyi 				g_pLogObject->Record("Error:read_capability failed,err=%d", iRet);
2368081d237aSliuyi 			printf("Read capability Fail!\r\n");
2369081d237aSliuyi 		} else {
2370081d237aSliuyi 			printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n",
2371081d237aSliuyi 			capability[0], capability[1], capability[2], capability[3],
2372081d237aSliuyi 			capability[4], capability[5], capability[6], capability[7]);
2373081d237aSliuyi 			if (capability[0] & 1)
2374081d237aSliuyi 			{
2375081d237aSliuyi 				printf("Direct LBA:\tenabled\r\n");
2376081d237aSliuyi 			}
2377081d237aSliuyi 
2378081d237aSliuyi 			if (capability[0] & 2)
2379081d237aSliuyi 			{
2380081d237aSliuyi 				printf("Vendor Storage:\tenabled\r\n");
2381081d237aSliuyi 			}
2382081d237aSliuyi 
2383081d237aSliuyi 			if (capability[0] & 4)
2384081d237aSliuyi 			{
2385081d237aSliuyi 				printf("First 4m Access:\tenabled\r\n");
2386081d237aSliuyi 			}
2387081d237aSliuyi 			bSuccess = true;
2388081d237aSliuyi 		}
2389081d237aSliuyi 	} else {
2390081d237aSliuyi 		printf("Read capability quit, creating comm object failed!\r\n");
2391081d237aSliuyi 	}
2392081d237aSliuyi 	if (pComm) {
2393081d237aSliuyi 		delete pComm;
2394081d237aSliuyi 		pComm = NULL;
2395081d237aSliuyi 	}
2396081d237aSliuyi 	return bSuccess;
2397081d237aSliuyi }
2398081d237aSliuyi bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam)
2399081d237aSliuyi {
2400081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2401081d237aSliuyi 		return false;
2402081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2403081d237aSliuyi 	bool bRet, bSuccess = false;
2404081d237aSliuyi 	int iRet;
2405081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2406081d237aSliuyi 	if (bRet) {
2407081d237aSliuyi 		iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam);
2408081d237aSliuyi 		if(ERR_SUCCESS == iRet) {
2409081d237aSliuyi 			if (*(u32 *)pParam != 0x4D524150) {
2410081d237aSliuyi 				goto Exit_ReadParam;
2411081d237aSliuyi 			}
2412081d237aSliuyi 		} else {
2413081d237aSliuyi 			if (g_pLogObject)
2414081d237aSliuyi 					g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2415081d237aSliuyi 			printf("Read parameter failed!\r\n");
2416081d237aSliuyi 			goto Exit_ReadParam;
2417081d237aSliuyi 		}
2418081d237aSliuyi 		bSuccess = true;
2419081d237aSliuyi 	}
2420081d237aSliuyi Exit_ReadParam:
2421081d237aSliuyi 	if (pComm) {
2422081d237aSliuyi 		delete pComm;
2423081d237aSliuyi 		pComm = NULL;
2424081d237aSliuyi 	}
2425081d237aSliuyi 	return bSuccess;
2426081d237aSliuyi }
2427081d237aSliuyi 
2428081d237aSliuyi 
24296ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt)
24306ae612beSliuyi {
24316ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
24326ae612beSliuyi 		return false;
24336ae612beSliuyi 	gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE);
24346ae612beSliuyi 	CRKUsbComm *pComm = NULL;
24356ae612beSliuyi 	bool bRet, bSuccess = false;
24366ae612beSliuyi 	int iRet;
24376ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
24386ae612beSliuyi 	if (bRet) {
24396ae612beSliuyi 		iRet = pComm->RKU_ReadLBA( 0, 34, pGpt);
24406ae612beSliuyi 		if(ERR_SUCCESS == iRet) {
24416ae612beSliuyi 			if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
24426ae612beSliuyi 				goto Exit_ReadGPT;
24436ae612beSliuyi 			}
24446ae612beSliuyi 		} else {
24456ae612beSliuyi 			if (g_pLogObject)
24466ae612beSliuyi 					g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
24476ae612beSliuyi 			printf("Read GPT failed!\r\n");
24486ae612beSliuyi 			goto Exit_ReadGPT;
24496ae612beSliuyi 		}
24506ae612beSliuyi 		bSuccess = true;
24516ae612beSliuyi 	}
24526ae612beSliuyi Exit_ReadGPT:
24536ae612beSliuyi 	if (pComm) {
24546ae612beSliuyi 		delete pComm;
24556ae612beSliuyi 		pComm = NULL;
24566ae612beSliuyi 	}
24576ae612beSliuyi 	return bSuccess;
24586ae612beSliuyi }
245976af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
246076af099aSliuyi {
246176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
246276af099aSliuyi 		return false;
246376af099aSliuyi 	CRKUsbComm *pComm = NULL;
246476af099aSliuyi 	FILE *file = NULL;
246576af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
246676af099aSliuyi 	int iRet;
246776af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
246876af099aSliuyi 	int nSectorSize = 512;
246976af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
247076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
247176af099aSliuyi 	if (bRet) {
247276af099aSliuyi 		if(szFile) {
247376af099aSliuyi 			file = fopen(szFile, "wb+");
247476af099aSliuyi 			if( !file ) {
247576af099aSliuyi 				printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
247676af099aSliuyi 				goto Exit_ReadLBA;
247776af099aSliuyi 			}
247876af099aSliuyi 		}
247976af099aSliuyi 
248076af099aSliuyi 		while(uiLen > 0) {
248176af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
248276af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
248376af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
248476af099aSliuyi 			if(ERR_SUCCESS == iRet) {
248576af099aSliuyi 				uiLen -= iRead;
248676af099aSliuyi 				iTotalRead += iRead;
248776af099aSliuyi 
248876af099aSliuyi 				if(szFile) {
248976af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
249076af099aSliuyi 					if (bFirst){
249176af099aSliuyi 						if (iTotalRead >= 1024)
249232268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
249376af099aSliuyi 						else
249432268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
249576af099aSliuyi 						bFirst = false;
249676af099aSliuyi 					} else {
249776af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
249876af099aSliuyi 						CURSOR_DEL_LINE;
249976af099aSliuyi 						if (iTotalRead >= 1024)
250032268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
250176af099aSliuyi 						else
250232268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
250376af099aSliuyi 					}
250476af099aSliuyi 				}
250576af099aSliuyi 				else
250676af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
250776af099aSliuyi 			} else {
250876af099aSliuyi 				if (g_pLogObject)
250976af099aSliuyi 					g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
251076af099aSliuyi 
251176af099aSliuyi 				printf("Read LBA failed!\r\n");
251276af099aSliuyi 				goto Exit_ReadLBA;
251376af099aSliuyi 			}
251476af099aSliuyi 		}
251576af099aSliuyi 		bSuccess = true;
251676af099aSliuyi 	} else {
251732268622SAndreas Färber 		printf("Read LBA quit, creating comm object failed!\r\n");
251876af099aSliuyi 	}
251976af099aSliuyi Exit_ReadLBA:
252076af099aSliuyi 	if (pComm) {
252176af099aSliuyi 		delete pComm;
252276af099aSliuyi 		pComm = NULL;
252376af099aSliuyi 	}
252476af099aSliuyi 	if (file)
252576af099aSliuyi 		fclose(file);
252676af099aSliuyi 	return bSuccess;
252776af099aSliuyi }
25286ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize)
25296ae612beSliuyi {
2530ae4252f0Sliuyi 	UINT uiErase=1024*32;
25316ae612beSliuyi 	bool bSuccess = true;
25326ae612beSliuyi 	int iRet;
25336ae612beSliuyi 	while (uiSize)
25346ae612beSliuyi 	{
25356ae612beSliuyi 		if (uiSize>=uiErase)
25366ae612beSliuyi 		{
25376ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiErase);
25386ae612beSliuyi 			uiSize -= uiErase;
25396ae612beSliuyi 			uiOffset += uiErase;
25406ae612beSliuyi 		}
25416ae612beSliuyi 		else
25426ae612beSliuyi 		{
25436ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiSize);
25446ae612beSliuyi 			uiSize = 0;
25456ae612beSliuyi 			uiOffset += uiSize;
25466ae612beSliuyi 		}
25476ae612beSliuyi 		if (iRet!=ERR_SUCCESS)
25486ae612beSliuyi 		{
25496ae612beSliuyi 			if (g_pLogObject)
25506ae612beSliuyi 			{
25516ae612beSliuyi 				g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet);
25526ae612beSliuyi 			}
25536ae612beSliuyi 			bSuccess = false;
25546ae612beSliuyi 			break;
25556ae612beSliuyi 		}
25566ae612beSliuyi 	}
25576ae612beSliuyi 	return bSuccess;
25586ae612beSliuyi 
25596ae612beSliuyi }
25606ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk)
25616ae612beSliuyi {
25626ae612beSliuyi 	UINT uiRead;
25636ae612beSliuyi 	uiRead = fread(&chunk, 1, sizeof(chunk_header), file);
25646ae612beSliuyi 	if (uiRead != sizeof(chunk_header)) {
25656ae612beSliuyi 		if (g_pLogObject)
25666ae612beSliuyi 		{
25676ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno);
25686ae612beSliuyi 		}
25696ae612beSliuyi 		return false;
25706ae612beSliuyi 	}
25716ae612beSliuyi 	return true;
25726ae612beSliuyi }
25736ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize)
25746ae612beSliuyi {
25756ae612beSliuyi 	UINT uiRead;
25766ae612beSliuyi 	uiRead = fread(pBuf, 1, dwSize, file);
25776ae612beSliuyi 	if (uiRead!=dwSize)
25786ae612beSliuyi 	{
25796ae612beSliuyi 		if (g_pLogObject)
25806ae612beSliuyi 		{
25816ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno);
25826ae612beSliuyi 		}
25836ae612beSliuyi 		return false;
25846ae612beSliuyi 	}
25856ae612beSliuyi 	return true;
25866ae612beSliuyi }
25876ae612beSliuyi 
25886ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile)
25896ae612beSliuyi {
25906ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
25916ae612beSliuyi 		return false;
25926ae612beSliuyi 	CRKUsbComm *pComm = NULL;
25936ae612beSliuyi 	FILE *file = NULL;
25946ae612beSliuyi 	bool bRet, bSuccess = false, bFirst = true;
25956ae612beSliuyi 	int iRet;
25966ae612beSliuyi 	u64 iTotalWrite = 0, iFileSize = 0;
25976ae612beSliuyi 	UINT iRead = 0, uiTransferSec, curChunk, i;
25986ae612beSliuyi 	UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc;
25996ae612beSliuyi 	BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA];
26006ae612beSliuyi 	sparse_header header;
26016ae612beSliuyi 	chunk_header  chunk;
26026ae612beSliuyi 	dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE;
26036ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
26046ae612beSliuyi 	if (bRet) {
2605ae4252f0Sliuyi 
26066ae612beSliuyi 		file = fopen(szFile, "rb");
26076ae612beSliuyi 		if( !file ) {
26086ae612beSliuyi 			printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile);
26096ae612beSliuyi 			goto Exit_WriteSparseLBA;
26106ae612beSliuyi 		}
26116ae612beSliuyi 		fseeko(file, 0, SEEK_SET);
26126ae612beSliuyi 		iRead = fread(&header, 1, sizeof(header), file);
26136ae612beSliuyi 		if (iRead != sizeof(sparse_header))
26146ae612beSliuyi 		{
26156ae612beSliuyi 			if (g_pLogObject)
26166ae612beSliuyi 			{
26176ae612beSliuyi 				g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno);
26186ae612beSliuyi 			}
26196ae612beSliuyi 			goto Exit_WriteSparseLBA;
26206ae612beSliuyi 		}
26216ae612beSliuyi 		iFileSize = header.blk_sz * (u64)header.total_blks;
26226ae612beSliuyi 		iTotalWrite = 0;
26236ae612beSliuyi 		curChunk = 0;
2624ae4252f0Sliuyi 		if (uiSize==(u32)-1)
2625ae4252f0Sliuyi 			uiSize = ALIGN(iFileSize, SECTOR_SIZE);
2626ae4252f0Sliuyi 		bRet = erase_partition(pComm, uiBegin, uiSize);
2627ae4252f0Sliuyi 		if (!bRet) {
2628ae4252f0Sliuyi 			printf("%s failed, erase partition error\r\n", __func__);
2629ae4252f0Sliuyi 			goto Exit_WriteSparseLBA;
2630ae4252f0Sliuyi 		}
26316ae612beSliuyi 		while(curChunk < header.total_chunks)
26326ae612beSliuyi 		{
26336ae612beSliuyi 			if (!EatSparseChunk(file, chunk)) {
26346ae612beSliuyi 				goto Exit_WriteSparseLBA;
26356ae612beSliuyi 			}
26366ae612beSliuyi 			curChunk++;
26376ae612beSliuyi 			switch (chunk.chunk_type) {
26386ae612beSliuyi 			case CHUNK_TYPE_RAW:
26396ae612beSliuyi 				dwChunkDataSize = chunk.total_sz - sizeof(chunk_header);
26406ae612beSliuyi 				while (dwChunkDataSize) {
26416ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
26426ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
26436ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
26446ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
26456ae612beSliuyi 					} else {
26466ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
26476ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
26486ae612beSliuyi 					}
26496ae612beSliuyi 					if (!EatSparseData(file, pBuf, dwTransferBytes)) {
26506ae612beSliuyi 						goto Exit_WriteSparseLBA;
26516ae612beSliuyi 					}
26526ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
26536ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
26546ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
26556ae612beSliuyi 						iTotalWrite += dwTransferBytes;
26566ae612beSliuyi 						uiBegin += uiTransferSec;
26576ae612beSliuyi 					} else {
26586ae612beSliuyi 						if (g_pLogObject) {
26596ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)",  __func__, iTotalWrite, iRet);
26606ae612beSliuyi 						}
26616ae612beSliuyi 						goto Exit_WriteSparseLBA;
26626ae612beSliuyi 					}
26636ae612beSliuyi 					if (bFirst) {
26646ae612beSliuyi 						if (iTotalWrite >= 1024)
26656ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
26666ae612beSliuyi 						else
26676ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
26686ae612beSliuyi 						bFirst = false;
26696ae612beSliuyi 					} else {
26706ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
26716ae612beSliuyi 						CURSOR_DEL_LINE;
26726ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
26736ae612beSliuyi 					}
26746ae612beSliuyi 				}
26756ae612beSliuyi 				break;
26766ae612beSliuyi 			case CHUNK_TYPE_FILL:
26776ae612beSliuyi 				dwChunkDataSize = chunk.chunk_sz * header.blk_sz;
26786ae612beSliuyi 				if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) {
26796ae612beSliuyi 					goto Exit_WriteSparseLBA;
26806ae612beSliuyi 				}
26816ae612beSliuyi 				while (dwChunkDataSize) {
26826ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
26836ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
26846ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
26856ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
26866ae612beSliuyi 					} else {
26876ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
26886ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
26896ae612beSliuyi 					}
26906ae612beSliuyi 					for (i = 0; i < dwTransferBytes / 4; i++) {
26916ae612beSliuyi 						*(DWORD *)(pBuf + i * 4) = dwFillByte;
26926ae612beSliuyi 					}
26936ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
26946ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
26956ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
26966ae612beSliuyi 						iTotalWrite += dwTransferBytes;
26976ae612beSliuyi 						uiBegin += uiTransferSec;
26986ae612beSliuyi 					} else {
26996ae612beSliuyi 						if (g_pLogObject) {
27006ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet);
27016ae612beSliuyi 						}
27026ae612beSliuyi 						goto Exit_WriteSparseLBA;
27036ae612beSliuyi 					}
27046ae612beSliuyi 					if (bFirst) {
27056ae612beSliuyi 						if (iTotalWrite >= 1024)
27066ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27076ae612beSliuyi 						else
27086ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
27096ae612beSliuyi 						bFirst = false;
27106ae612beSliuyi 					} else {
27116ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
27126ae612beSliuyi 						CURSOR_DEL_LINE;
27136ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27146ae612beSliuyi 					}
27156ae612beSliuyi 				}
27166ae612beSliuyi 				break;
27176ae612beSliuyi 			case CHUNK_TYPE_DONT_CARE:
27186ae612beSliuyi 				dwChunkDataSize = chunk.chunk_sz * header.blk_sz;
27196ae612beSliuyi 				iTotalWrite += dwChunkDataSize;
27206ae612beSliuyi 				uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1));
27216ae612beSliuyi 				uiBegin += uiTransferSec;
27226ae612beSliuyi 				if (bFirst) {
27236ae612beSliuyi 					if (iTotalWrite >= 1024)
27246ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27256ae612beSliuyi 					else
27266ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
27276ae612beSliuyi 					bFirst = false;
27286ae612beSliuyi 				} else {
27296ae612beSliuyi 					CURSOR_MOVEUP_LINE(1);
27306ae612beSliuyi 					CURSOR_DEL_LINE;
27316ae612beSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27326ae612beSliuyi 				}
27336ae612beSliuyi 				break;
27346ae612beSliuyi 			case CHUNK_TYPE_CRC32:
27356ae612beSliuyi 				EatSparseData(file,(PBYTE)&dwCrc,4);
27366ae612beSliuyi 				break;
27376ae612beSliuyi 			}
27386ae612beSliuyi 		}
27396ae612beSliuyi 		bSuccess = true;
27406ae612beSliuyi 	} else {
27416ae612beSliuyi 		printf("Write LBA quit, creating comm object failed!\r\n");
27426ae612beSliuyi 	}
27436ae612beSliuyi Exit_WriteSparseLBA:
27446ae612beSliuyi 	if (pComm) {
27456ae612beSliuyi 		delete pComm;
27466ae612beSliuyi 		pComm = NULL;
27476ae612beSliuyi 	}
27486ae612beSliuyi 	if (file)
27496ae612beSliuyi 		fclose(file);
27506ae612beSliuyi 	return bSuccess;
27516ae612beSliuyi 
27526ae612beSliuyi }
27536ae612beSliuyi 
275476af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
275576af099aSliuyi {
275676af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
275776af099aSliuyi 		return false;
275876af099aSliuyi 	CRKUsbComm *pComm = NULL;
275976af099aSliuyi 	FILE *file = NULL;
276076af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
276176af099aSliuyi 	int iRet;
276276af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
276376af099aSliuyi 	UINT iWrite = 0, iRead = 0;
276476af099aSliuyi 	UINT uiLen;
276576af099aSliuyi 	int nSectorSize = 512;
276676af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
276776af099aSliuyi 
276876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
276976af099aSliuyi 	if (bRet) {
277076af099aSliuyi 		file = fopen(szFile, "rb");
277176af099aSliuyi 		if( !file ) {
277276af099aSliuyi 			printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
277376af099aSliuyi 			goto Exit_WriteLBA;
277476af099aSliuyi 		}
277576af099aSliuyi 
277676af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
277776af099aSliuyi 		iFileSize = ftello(file);
277876af099aSliuyi 		fseeko(file, 0, SEEK_SET);
277976af099aSliuyi 		while(iTotalWrite < iFileSize) {
278076af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
278176af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
278276af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
278376af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
278476af099aSliuyi 			if(ERR_SUCCESS == iRet) {
278576af099aSliuyi 				uiBegin += uiLen;
278676af099aSliuyi 				iTotalWrite += iWrite;
278776af099aSliuyi 				if (bFirst) {
278876af099aSliuyi 					if (iTotalWrite >= 1024)
278976af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
279076af099aSliuyi 					else
279132268622SAndreas Färber 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
279276af099aSliuyi 					bFirst = false;
279376af099aSliuyi 				} else {
279476af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
279576af099aSliuyi 					CURSOR_DEL_LINE;
279676af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
279776af099aSliuyi 				}
279876af099aSliuyi 			} else {
279976af099aSliuyi 				if (g_pLogObject)
280076af099aSliuyi 					g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
280176af099aSliuyi 
280276af099aSliuyi 				printf("Write LBA failed!\r\n");
280376af099aSliuyi 				goto Exit_WriteLBA;
280476af099aSliuyi 			}
280576af099aSliuyi 		}
280676af099aSliuyi 		bSuccess = true;
280776af099aSliuyi 	} else {
280832268622SAndreas Färber 		printf("Write LBA quit, creating comm object failed!\r\n");
280976af099aSliuyi 	}
281076af099aSliuyi Exit_WriteLBA:
281176af099aSliuyi 	if (pComm) {
281276af099aSliuyi 		delete pComm;
281376af099aSliuyi 		pComm = NULL;
281476af099aSliuyi 	}
281576af099aSliuyi 	if (file)
281676af099aSliuyi 		fclose(file);
281776af099aSliuyi 	return bSuccess;
281876af099aSliuyi }
281976af099aSliuyi 
282076af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
282176af099aSliuyi {
282276af099aSliuyi 	string strItem;
282376af099aSliuyi 	char szItem[100];
282476af099aSliuyi 	char *pos = NULL, *pStart;
282576af099aSliuyi 	pStart = pszItems;
282676af099aSliuyi 	pos = strchr(pStart, ',');
282776af099aSliuyi 	while(pos != NULL) {
282802bc7763SChristoph Muellner 		memset(szItem, 0, sizeof(szItem));
282976af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
283076af099aSliuyi 		strItem = szItem;
283176af099aSliuyi 		vecItems.push_back(strItem);
283276af099aSliuyi 		pStart = pos + 1;
283376af099aSliuyi 		if (*pStart == 0)
283476af099aSliuyi 			break;
283576af099aSliuyi 		pos = strchr(pStart, ',');
283676af099aSliuyi 	}
283776af099aSliuyi 	if (strlen(pStart) > 0) {
283802bc7763SChristoph Muellner 		memset(szItem, 0, sizeof(szItem));
283902bc7763SChristoph Muellner 		strncpy(szItem, pStart, sizeof(szItem)-1);
284076af099aSliuyi 		strItem = szItem;
284176af099aSliuyi 		vecItems.push_back(strItem);
284276af099aSliuyi 	}
284376af099aSliuyi }
2844c30d921cSKever Yang 
2845d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
2846d71e8c20SEddie Cai {
2847d71e8c20SEddie Cai 	FILE *file = NULL;
2848d71e8c20SEddie Cai 	int len;
2849d71e8c20SEddie Cai 
2850d71e8c20SEddie Cai 	if(!tag || !spl)
2851d71e8c20SEddie Cai 		return;
2852d71e8c20SEddie Cai 	len = strlen(tag);
2853d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
2854d71e8c20SEddie Cai 	file = fopen(spl, "rb");
2855d71e8c20SEddie Cai 	if( !file ){
2856d71e8c20SEddie Cai 		return;
2857d71e8c20SEddie Cai 	}
2858d71e8c20SEddie Cai 	int iFileSize;
2859d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
2860d71e8c20SEddie Cai 	iFileSize = ftell(file);
2861d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
2862d71e8c20SEddie Cai 	char *Buf = NULL;
2863d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
2864d71e8c20SEddie Cai 	if (!Buf){
2865d71e8c20SEddie Cai 		fclose(file);
2866d71e8c20SEddie Cai 		return;
2867d71e8c20SEddie Cai 	}
2868d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
2869d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
2870d71e8c20SEddie Cai 	int iRead;
2871d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
2872d71e8c20SEddie Cai 	if (iRead != iFileSize){
2873d71e8c20SEddie Cai 		fclose(file);
2874d71e8c20SEddie Cai 		delete []Buf;
2875d71e8c20SEddie Cai 		return;
2876d71e8c20SEddie Cai 	}
2877d71e8c20SEddie Cai 	fclose(file);
2878d71e8c20SEddie Cai 
2879d71e8c20SEddie Cai 	len = strlen(spl);
288032268622SAndreas Färber 	char *taggedspl = new char[len + 5];
288132268622SAndreas Färber 	strcpy(taggedspl, spl);
288232268622SAndreas Färber 	strcpy(taggedspl + len, ".tag");
288332268622SAndreas Färber 	taggedspl[len+4] = 0;
288432268622SAndreas Färber 	printf("Writing tagged spl to %s\n", taggedspl);
2885d71e8c20SEddie Cai 
288632268622SAndreas Färber 	file = fopen(taggedspl, "wb");
2887d71e8c20SEddie Cai 	if( !file ){
288832268622SAndreas Färber 		delete []taggedspl;
2889d71e8c20SEddie Cai 		delete []Buf;
2890d71e8c20SEddie Cai 		return;
2891d71e8c20SEddie Cai 	}
2892d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
2893d71e8c20SEddie Cai 	fclose(file);
289432268622SAndreas Färber 	delete []taggedspl;
2895d71e8c20SEddie Cai 	delete []Buf;
2896d71e8c20SEddie Cai 	printf("done\n");
2897d71e8c20SEddie Cai 	return;
2898d71e8c20SEddie Cai }
2899081d237aSliuyi void list_device(CRKScan *pScan)
2900081d237aSliuyi {
2901081d237aSliuyi 	STRUCT_RKDEVICE_DESC desc;
2902081d237aSliuyi 	string strDevType;
2903081d237aSliuyi 	int i,cnt;
2904081d237aSliuyi 	cnt = pScan->DEVICE_COUNTS;
2905081d237aSliuyi 	if (cnt == 0) {
2906081d237aSliuyi 		printf("not found any devices!\r\n");
2907081d237aSliuyi 		return;
2908081d237aSliuyi 	}
2909081d237aSliuyi 	for (i=0;i<cnt;i++)
2910081d237aSliuyi 	{
2911081d237aSliuyi 		pScan->GetDevice(desc, i);
2912081d237aSliuyi 		if (desc.emUsbType==RKUSB_MASKROM)
2913081d237aSliuyi 			strDevType = "Maskrom";
2914081d237aSliuyi 		else if (desc.emUsbType==RKUSB_LOADER)
2915081d237aSliuyi 			strDevType = "Loader";
2916081d237aSliuyi 		else
2917081d237aSliuyi 			strDevType = "Unknown";
2918081d237aSliuyi 		printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid,
2919081d237aSliuyi 		       desc.usPid,desc.uiLocationID,strDevType.c_str());
2920081d237aSliuyi 	}
2921081d237aSliuyi 
2922081d237aSliuyi }
2923081d237aSliuyi 
2924d71e8c20SEddie Cai 
292576af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
292676af099aSliuyi {
292776af099aSliuyi 	string strCmd;
292876af099aSliuyi 	strCmd = argv[1];
292976af099aSliuyi 	ssize_t cnt;
293076af099aSliuyi 	bool bRet,bSuccess = false;
29318df2d64aSEddie Cai 	char *s;
29328df2d64aSEddie Cai 	int i, ret;
293376af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
2934081d237aSliuyi 	u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE];
29356ae612beSliuyi 	u64 lba, lba_end;
2936081d237aSliuyi 	u32 part_size, part_offset;
293776af099aSliuyi 
293876af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
29398df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
29408df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
29418df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
294278884ef4SEddie Cai 
29438df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
294476af099aSliuyi 		usage();
294576af099aSliuyi 		return true;
29468df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
2947c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
294876af099aSliuyi 		return true;
294978884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
295078884ef4SEddie Cai 		mergeBoot();
295178884ef4SEddie Cai 
295278884ef4SEddie Cai 		return true;
295378884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
295478884ef4SEddie Cai 		string strLoader = argv[2];
295578884ef4SEddie Cai 
295678884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
295778884ef4SEddie Cai 		return true;
2958d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
2959d71e8c20SEddie Cai 		if (argc == 4) {
2960d71e8c20SEddie Cai 			string tag = argv[2];
2961d71e8c20SEddie Cai 			string spl = argv[3];
2962d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
2963d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
2964d71e8c20SEddie Cai 			return true;
2965d71e8c20SEddie Cai 		}
2966d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
2967d71e8c20SEddie Cai 		usage();
296876af099aSliuyi 	}
296976af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
2970081d237aSliuyi 	if(strcmp(strCmd.c_str(), "LD") == 0) {
2971081d237aSliuyi 		list_device(pScan);
2972081d237aSliuyi 		return true;
2973081d237aSliuyi 	}
2974081d237aSliuyi 
297576af099aSliuyi 	if (cnt < 1) {
297676af099aSliuyi 		ERROR_COLOR_ATTR;
297732268622SAndreas Färber 		printf("Did not find any rockusb device, please plug device in!");
297876af099aSliuyi 		NORMAL_COLOR_ATTR;
297976af099aSliuyi 		printf("\r\n");
298076af099aSliuyi 		return bSuccess;
298176af099aSliuyi 	} else if (cnt > 1) {
298276af099aSliuyi 		ERROR_COLOR_ATTR;
298332268622SAndreas Färber 		printf("Found too many rockusb devices, please plug devices out!");
298476af099aSliuyi 		NORMAL_COLOR_ATTR;
298576af099aSliuyi 		printf("\r\n");
298676af099aSliuyi 		return bSuccess;
298776af099aSliuyi 	}
298876af099aSliuyi 
298976af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
299076af099aSliuyi 	if (!bRet) {
299176af099aSliuyi 		ERROR_COLOR_ATTR;
299232268622SAndreas Färber 		printf("Getting information about rockusb device failed!");
299376af099aSliuyi 		NORMAL_COLOR_ATTR;
299476af099aSliuyi 		printf("\r\n");
299576af099aSliuyi 		return bSuccess;
299676af099aSliuyi 	}
299776af099aSliuyi 
299876af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
299976af099aSliuyi 		if ((argc != 2) && (argc != 3))
300076af099aSliuyi 			printf("Parameter of [RD] command is invalid, please check help!\r\n");
300176af099aSliuyi 		else {
300276af099aSliuyi 			if (argc == 2)
300376af099aSliuyi 				bSuccess = reset_device(dev);
300476af099aSliuyi 			else {
300576af099aSliuyi 				UINT uiSubCode;
300676af099aSliuyi 				char *pszEnd;
300776af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
300876af099aSliuyi 				if (*pszEnd)
300976af099aSliuyi 					printf("Subcode is invalid, please check!\r\n");
301076af099aSliuyi 				else {
301176af099aSliuyi 					if (uiSubCode <= 5)
301276af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
301376af099aSliuyi 					else
301476af099aSliuyi 						printf("Subcode is invalid, please check!\r\n");
301576af099aSliuyi 				}
301676af099aSliuyi 			}
301776af099aSliuyi 		}
301876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
301976af099aSliuyi 		bSuccess = test_device(dev);
302076af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
302176af099aSliuyi 		bSuccess = read_flash_id(dev);
302276af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
302376af099aSliuyi 		bSuccess = read_flash_info(dev);
302476af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
302576af099aSliuyi 		bSuccess = read_chip_info(dev);
3026081d237aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability
3027081d237aSliuyi 		bSuccess = read_capability(dev);
302876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
302976af099aSliuyi 		if (argc > 2) {
303076af099aSliuyi 			string strLoader;
303176af099aSliuyi 			strLoader = argv[2];
303276af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
303376af099aSliuyi 		} else if (argc == 2) {
3034c29e5f0fSliuyi 			ret = find_config_item(g_ConfigItemVec, "loader");
303576af099aSliuyi 			if (ret == -1)
303632268622SAndreas Färber 				printf("Did not find loader item in config!\r\n");
303776af099aSliuyi 			else
303876af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
303976af099aSliuyi 		} else
304076af099aSliuyi 			printf("Parameter of [DB] command is invalid, please check help!\r\n");
3041c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
3042c30d921cSKever Yang 		if (argc > 2) {
3043c30d921cSKever Yang 			string strParameter;
3044c30d921cSKever Yang 			strParameter = argv[2];
3045c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
3046c30d921cSKever Yang 		} else
3047c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid, please check help!\r\n");
3048081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PRM") == 0) {
3049081d237aSliuyi 		if (argc > 2) {
3050081d237aSliuyi 			string strParameter;
3051081d237aSliuyi 			strParameter = argv[2];
3052081d237aSliuyi 			bSuccess = write_parameter(dev, (char *)strParameter.c_str());
3053081d237aSliuyi 		} else
3054081d237aSliuyi 			printf("Parameter of [PRM] command is invalid, please check help!\r\n");
3055c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
3056c30d921cSKever Yang 		if (argc > 2) {
3057c30d921cSKever Yang 			string strLoader;
3058c30d921cSKever Yang 			strLoader = argv[2];
3059c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
3060c30d921cSKever Yang 		} else
3061c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid, please check help!\r\n");
306276af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
306376af099aSliuyi 		if (argc == 2) {
306476af099aSliuyi 			bSuccess = erase_flash(dev);
306576af099aSliuyi 		} else
306676af099aSliuyi 			printf("Parameter of [EF] command is invalid, please check help!\r\n");
306776af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
306876af099aSliuyi 		if (argc == 4) {
306976af099aSliuyi 			UINT uiBegin;
307076af099aSliuyi 			char *pszEnd;
307176af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
307276af099aSliuyi 			if (*pszEnd)
307376af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
3074ae4252f0Sliuyi 			else {
3075ae4252f0Sliuyi 				if (is_sparse_image(argv[3]))
3076ae4252f0Sliuyi 						bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]);
307776af099aSliuyi 					else
3078ae4252f0Sliuyi 						bSuccess = write_lba(dev, (u32)uiBegin, argv[3]);
3079ae4252f0Sliuyi 			}
308076af099aSliuyi 		} else
308176af099aSliuyi 			printf("Parameter of [WL] command is invalid, please check help!\r\n");
30826ae612beSliuyi 	} else if(strcmp(strCmd.c_str(), "WLX") == 0) {
30836ae612beSliuyi 		if (argc == 4) {
30846ae612beSliuyi 			bRet = read_gpt(dev, master_gpt);
30856ae612beSliuyi 			if (bRet) {
30866ae612beSliuyi 				bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end);
30876ae612beSliuyi 				if (bRet) {
30886ae612beSliuyi 					if (is_sparse_image(argv[3]))
30896ae612beSliuyi 						bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]);
30906ae612beSliuyi 					else
30916ae612beSliuyi 						bSuccess = write_lba(dev, (u32)lba, argv[3]);
30926ae612beSliuyi 				} else
30936ae612beSliuyi 					printf("No found %s partition\r\n", argv[2]);
3094081d237aSliuyi 			} else {
3095081d237aSliuyi 				bRet = read_param(dev, param_buffer);
3096081d237aSliuyi 				if (bRet) {
3097081d237aSliuyi 					bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size);
3098081d237aSliuyi 					if (bRet) {
3099081d237aSliuyi 						if (is_sparse_image(argv[3]))
3100081d237aSliuyi 							bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]);
3101081d237aSliuyi 						else
3102081d237aSliuyi 							bSuccess = write_lba(dev, part_offset, argv[3]);
3103081d237aSliuyi 					} else
3104081d237aSliuyi 						printf("No found %s partition\r\n", argv[2]);
31056ae612beSliuyi 				}
3106081d237aSliuyi 				else
3107081d237aSliuyi 					printf("Not found any partition table!\r\n");
3108081d237aSliuyi 			}
3109081d237aSliuyi 
31106ae612beSliuyi 		} else
31116ae612beSliuyi 			printf("Parameter of [WLX] command is invalid, please check help!\r\n");
311276af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
311376af099aSliuyi 		char *pszEnd;
311476af099aSliuyi 		UINT uiBegin, uiLen;
311576af099aSliuyi 		if (argc != 5)
311676af099aSliuyi 			printf("Parameter of [RL] command is invalid, please check help!\r\n");
311776af099aSliuyi 		else {
311876af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
311976af099aSliuyi 			if (*pszEnd)
312076af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
312176af099aSliuyi 			else {
312276af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
312376af099aSliuyi 				if (*pszEnd)
312476af099aSliuyi 					printf("Len is invalid, please check!\r\n");
312576af099aSliuyi 				else {
312676af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
312776af099aSliuyi 				}
312876af099aSliuyi 			}
312976af099aSliuyi 		}
3130081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PPT") == 0) {
31313dc7e3ceSliuyi 		if (argc == 2) {
31323dc7e3ceSliuyi 			bSuccess = print_gpt(dev);
3133081d237aSliuyi 			if (!bSuccess) {
3134081d237aSliuyi 				bSuccess = print_parameter(dev);
3135081d237aSliuyi 				if (!bSuccess)
3136081d237aSliuyi 					printf("Not found any partition table!\r\n");
3137081d237aSliuyi 			}
31383dc7e3ceSliuyi 		} else
3139081d237aSliuyi 			printf("Parameter of [PPT] command is invalid, please check help!\r\n");
314076af099aSliuyi 	} else {
31419bc231bdSAndreas Färber 		printf("command is invalid!\r\n");
31429bc231bdSAndreas Färber 		usage();
314376af099aSliuyi 	}
314476af099aSliuyi 	return bSuccess;
314576af099aSliuyi }
314676af099aSliuyi 
314776af099aSliuyi 
314876af099aSliuyi int main(int argc, char* argv[])
314976af099aSliuyi {
315076af099aSliuyi 	CRKScan *pScan = NULL;
315176af099aSliuyi 	int ret;
315276af099aSliuyi 	char szProgramProcPath[100];
315376af099aSliuyi 	char szProgramDir[256];
315476af099aSliuyi 	string strLogDir,strConfigFile;
315576af099aSliuyi 	struct stat statBuf;
315676af099aSliuyi 
315776af099aSliuyi 	g_ConfigItemVec.clear();
315876af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
315976af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
316076af099aSliuyi 		strcpy(szProgramDir, ".");
316176af099aSliuyi 	else {
316276af099aSliuyi 		char *pSlash;
316376af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
316476af099aSliuyi 		if (pSlash)
316576af099aSliuyi 			*pSlash = '\0';
316676af099aSliuyi 	}
316776af099aSliuyi 	strLogDir = szProgramDir;
316876af099aSliuyi 	strLogDir +=  "/log/";
316976af099aSliuyi 	strConfigFile = szProgramDir;
317076af099aSliuyi 	strConfigFile += "/config.ini";
317176af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
317276af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
3173e5ee8cc0Sliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
317476af099aSliuyi 
317576af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
317676af099aSliuyi 		if (g_pLogObject) {
317776af099aSliuyi 			g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
317876af099aSliuyi 		}
317976af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
318076af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
318176af099aSliuyi 	}
318276af099aSliuyi 
318376af099aSliuyi 	ret = libusb_init(NULL);
318476af099aSliuyi 	if (ret < 0) {
318576af099aSliuyi 		if (g_pLogObject) {
318676af099aSliuyi 			g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
318776af099aSliuyi 			delete g_pLogObject;
318876af099aSliuyi 		}
318976af099aSliuyi 		return -1;
319076af099aSliuyi 	}
319176af099aSliuyi 
319276af099aSliuyi 	pScan = new CRKScan();
319376af099aSliuyi 	if (!pScan) {
319476af099aSliuyi 		if (g_pLogObject) {
319532268622SAndreas Färber 			g_pLogObject->Record("Error: failed to create object for searching device");
319676af099aSliuyi 			delete g_pLogObject;
319776af099aSliuyi 		}
319876af099aSliuyi 		libusb_exit(NULL);
319976af099aSliuyi 		return -2;
320076af099aSliuyi 	}
320176af099aSliuyi 	pScan->SetVidPid();
320276af099aSliuyi 
320376af099aSliuyi 	if (argc == 1)
320476af099aSliuyi 		usage();
320576af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
320676af099aSliuyi 			return -0xFF;
320776af099aSliuyi 	if (pScan)
320876af099aSliuyi 		delete pScan;
320976af099aSliuyi 	if (g_pLogObject)
321076af099aSliuyi 		delete g_pLogObject;
321176af099aSliuyi 	libusb_exit(NULL);
321276af099aSliuyi 	return 0;
321376af099aSliuyi }
3214