xref: /rkdeveloptool/main.cpp (revision 304f073752fd25c854e1bcf05d8e7f925b1f4e14)
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 
usage()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");
59554066a0SArnaud Mouiche 	printf("ChangeStorage:\t\tcs [storage: 1=EMMC, 2=SD, 9=SPINOR]\r\n");
60154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
61154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
62154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
63081d237aSliuyi 	printf("ReadCapability:\t\trcb\r\n");
6478884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
6578884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
66d71e8c20SEddie Cai 	printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
6776af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6876af099aSliuyi }
ProgressInfoProc(UINT deviceLayer,ENUM_PROGRESS_PROMPT promptID,long long totalValue,long long currentValue,ENUM_CALL_STEP emCall)6921b25fd4SDave Murphy void ProgressInfoProc(UINT deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
7076af099aSliuyi {
7176af099aSliuyi 	string strInfoText="";
7276af099aSliuyi 	char szText[256];
7376af099aSliuyi 	switch (promptID) {
7476af099aSliuyi 	case TESTDEVICE_PROGRESS:
751831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "Test Device total %lld, current %lld", totalValue, currentValue);
7676af099aSliuyi 		strInfoText = szText;
7776af099aSliuyi 		break;
7876af099aSliuyi 	case LOWERFORMAT_PROGRESS:
791831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "Lowerformat Device total %lld, current %lld", totalValue, currentValue);
8076af099aSliuyi 		strInfoText = szText;
8176af099aSliuyi 		break;
8276af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
831831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8476af099aSliuyi 		strInfoText = szText;
8576af099aSliuyi 		break;
8676af099aSliuyi 	case CHECKIMAGE_PROGRESS:
871831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8876af099aSliuyi 		strInfoText = szText;
8976af099aSliuyi 		break;
9076af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
911831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "Tag Bad Block total %lld, current %lld", totalValue, currentValue);
9276af099aSliuyi 		strInfoText = szText;
9376af099aSliuyi 		break;
9476af099aSliuyi 	case TESTBLOCK_PROGRESS:
951831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "Test Block total %lld, current %lld", totalValue, currentValue);
9676af099aSliuyi 		strInfoText = szText;
9776af099aSliuyi 		break;
9876af099aSliuyi 	case ERASEFLASH_PROGRESS:
991831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "Erase Flash total %lld, current %lld", totalValue, currentValue);
10076af099aSliuyi 		strInfoText = szText;
10176af099aSliuyi 		break;
10276af099aSliuyi 	case ERASESYSTEM_PROGRESS:
1031831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "Erase System partition total %lld, current %lld", totalValue, currentValue);
10476af099aSliuyi 		strInfoText = szText;
10576af099aSliuyi 		break;
10676af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
1071831c99cSQuang Dang 		snprintf(szText, sizeof(szText), "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue);
10876af099aSliuyi 		strInfoText = szText;
10976af099aSliuyi 		break;
11076af099aSliuyi 	}
11176af099aSliuyi 	if (strInfoText.size() > 0){
11276af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
11376af099aSliuyi 		CURSOR_DEL_LINE;
11476af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
11576af099aSliuyi 	}
11676af099aSliuyi 	if (emCall == CALL_LAST)
11776af099aSliuyi 		deviceLayer = 0;
11876af099aSliuyi }
11976af099aSliuyi 
strupr(char * szSrc)12076af099aSliuyi char *strupr(char *szSrc)
12176af099aSliuyi {
12276af099aSliuyi 	char *p = szSrc;
12376af099aSliuyi 	while(*p){
12476af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
12576af099aSliuyi 			*p = *p - 'a' + 'A';
12676af099aSliuyi 		p++;
12776af099aSliuyi 	}
12876af099aSliuyi 	return szSrc;
12976af099aSliuyi }
PrintData(PBYTE pData,int nSize)13076af099aSliuyi void PrintData(PBYTE pData, int nSize)
13176af099aSliuyi {
13276af099aSliuyi 	char szPrint[17] = "\0";
13376af099aSliuyi 	int i;
13476af099aSliuyi 	for( i = 0; i < nSize; i++){
13576af099aSliuyi 		if(i % 16 == 0){
13676af099aSliuyi 			if(i / 16 > 0)
13776af099aSliuyi 				printf("     %s\r\n", szPrint);
13876af099aSliuyi 			printf("%08d ", i / 16);
13976af099aSliuyi 		}
14076af099aSliuyi 		printf("%02X ", pData[i]);
14176af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
14276af099aSliuyi 	}
14376af099aSliuyi 	if(i / 16 > 0)
14476af099aSliuyi 		printf("     %s\r\n", szPrint);
14576af099aSliuyi }
14676af099aSliuyi 
find_config_item(CONFIG_ITEM_VECTOR & vecItems,const char * pszName)147c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName)
14876af099aSliuyi {
14976af099aSliuyi 	unsigned int i;
150c29e5f0fSliuyi 	for(i = 0; i < vecItems.size(); i++){
151c29e5f0fSliuyi 		if (strcasecmp(pszName, vecItems[i].szItemName) == 0){
15276af099aSliuyi 			return i;
15376af099aSliuyi 		}
15476af099aSliuyi 	}
15576af099aSliuyi 	return -1;
15676af099aSliuyi }
string_to_uuid(string strUUid,char * uuid)157c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid)
158c29e5f0fSliuyi {
159c29e5f0fSliuyi 	unsigned int i;
160c29e5f0fSliuyi 	char value;
161c29e5f0fSliuyi 	memset(uuid, 0, 16);
162c29e5f0fSliuyi 	for (i =0; i < strUUid.size(); i++) {
163c29e5f0fSliuyi 		value = 0;
164c29e5f0fSliuyi 		if ((strUUid[i] >= '0')&&(strUUid[i] <= '9'))
165c29e5f0fSliuyi 			value = strUUid[i] - '0';
166c29e5f0fSliuyi 		if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f'))
167c29e5f0fSliuyi 			value = strUUid[i] - 'a' + 10;
168c29e5f0fSliuyi 		if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F'))
169c29e5f0fSliuyi 			value = strUUid[i] - 'A' + 10;
170c29e5f0fSliuyi 		if ((i % 2) == 0)
171c29e5f0fSliuyi 			uuid[i / 2] += (value << 4);
172c29e5f0fSliuyi 		else
173c29e5f0fSliuyi 			uuid[i / 2] += value;
174c29e5f0fSliuyi 	}
175c29e5f0fSliuyi 	unsigned int *p32;
176c29e5f0fSliuyi 	unsigned short *p16;
177c29e5f0fSliuyi 	p32 = (unsigned int*)uuid;
178c29e5f0fSliuyi 	*p32 = cpu_to_be32(*p32);
179c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 4);
180c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
181c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 6);
182c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
183c29e5f0fSliuyi }
18476af099aSliuyi 
parse_config(char * pConfig,CONFIG_ITEM_VECTOR & vecItem)18576af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
18676af099aSliuyi {
18776af099aSliuyi 
18876af099aSliuyi 	stringstream configStream(pConfig);
18976af099aSliuyi 	string strLine, strItemName, strItemValue;
19076af099aSliuyi 	string::size_type line_size,pos;
19176af099aSliuyi 	STRUCT_CONFIG_ITEM item;
19276af099aSliuyi 	vecItem.clear();
19376af099aSliuyi 	while (!configStream.eof()){
19476af099aSliuyi 		getline(configStream, strLine);
19576af099aSliuyi 		line_size = strLine.size();
19676af099aSliuyi 		if (line_size == 0)
19776af099aSliuyi 			continue;
19876af099aSliuyi 		if (strLine[line_size-1] == '\r'){
19976af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
20076af099aSliuyi 		}
201c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
202c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
203c30d921cSKever Yang 		if (strLine.size()==0 )
204c30d921cSKever Yang 			continue;
205c30d921cSKever Yang 		if (strLine[0] == '#')
206c30d921cSKever Yang 			continue;
20776af099aSliuyi 		pos = strLine.find("=");
20876af099aSliuyi 		if (pos == string::npos){
20976af099aSliuyi 			continue;
21076af099aSliuyi 		}
21176af099aSliuyi 		strItemName = strLine.substr(0, pos);
21276af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
21376af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
21476af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
21576af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
21676af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
21776af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
21876af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
21976af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
22076af099aSliuyi 			vecItem.push_back(item);
22176af099aSliuyi 		}
22276af099aSliuyi 	}
22376af099aSliuyi 	return true;
22476af099aSliuyi 
22576af099aSliuyi }
parse_config_file(const char * pConfigFile,CONFIG_ITEM_VECTOR & vecItem)22676af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
22776af099aSliuyi {
22876af099aSliuyi 	FILE *file = NULL;
22976af099aSliuyi 	file = fopen(pConfigFile, "rb");
23076af099aSliuyi 	if( !file ){
23176af099aSliuyi 		if (g_pLogObject)
23232268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile);
23376af099aSliuyi 		return false;
23476af099aSliuyi 	}
23576af099aSliuyi 	int iFileSize;
23676af099aSliuyi 	fseek(file, 0, SEEK_END);
23776af099aSliuyi 	iFileSize = ftell(file);
23876af099aSliuyi 	fseek(file, 0, SEEK_SET);
23976af099aSliuyi 	char *pConfigBuf = NULL;
24076af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
24176af099aSliuyi 	if (!pConfigBuf){
24276af099aSliuyi 		fclose(file);
24376af099aSliuyi 		return false;
24476af099aSliuyi 	}
24576af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
24676af099aSliuyi 	int iRead;
24776af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
24876af099aSliuyi 	if (iRead != iFileSize){
24976af099aSliuyi 		if (g_pLogObject)
25032268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize);
25176af099aSliuyi 		fclose(file);
25276af099aSliuyi 		delete []pConfigBuf;
25376af099aSliuyi 		return false;
25476af099aSliuyi 	}
25576af099aSliuyi 	fclose(file);
25676af099aSliuyi 	bool bRet;
25776af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
25876af099aSliuyi 	delete []pConfigBuf;
25976af099aSliuyi 	return bRet;
26076af099aSliuyi }
ParsePartitionInfo(string & strPartInfo,string & strName,UINT & uiOffset,UINT & uiLen)261c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
262c30d921cSKever Yang {
263c30d921cSKever Yang 	string::size_type pos,prevPos;
264c30d921cSKever Yang 	string strOffset,strLen;
265c30d921cSKever Yang 	int iCount;
266c30d921cSKever Yang 	prevPos = pos = 0;
267c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
268c30d921cSKever Yang 		return false;
269c30d921cSKever Yang 	}
270c30d921cSKever Yang 	pos = strPartInfo.find('@');
271c30d921cSKever Yang 	if (pos == string::npos) {
272c30d921cSKever Yang 		return false;
273c30d921cSKever Yang 	}
274c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
275c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
276c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
277c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
278c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
279c30d921cSKever Yang 	} else {
280c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
281c30d921cSKever Yang 		if (iCount != 1) {
282c30d921cSKever Yang 			return false;
283c30d921cSKever Yang 		}
284c30d921cSKever Yang 	}
285c30d921cSKever Yang 
286c30d921cSKever Yang 	prevPos = pos + 1;
287c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
288c30d921cSKever Yang 	if (pos == string::npos) {
289c30d921cSKever Yang 		return false;
290c30d921cSKever Yang 	}
291c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
292c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
293c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
294c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
295c30d921cSKever Yang 	if (iCount != 1) {
296c30d921cSKever Yang 		return false;
297c30d921cSKever Yang 	}
298c30d921cSKever Yang 	prevPos = pos + 1;
299c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
300c30d921cSKever Yang 	if (pos == string::npos) {
301c30d921cSKever Yang 		return false;
302c30d921cSKever Yang 	}
303c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
304c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
305c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
306c30d921cSKever Yang 
307c30d921cSKever Yang 	return true;
308c30d921cSKever Yang }
ParseUuidInfo(string & strUuidInfo,string & strName,string & strUUid)309c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid)
310c29e5f0fSliuyi {
311c29e5f0fSliuyi 	string::size_type pos(0);
312c30d921cSKever Yang 
313c29e5f0fSliuyi 	if (strUuidInfo.size() <= 0) {
314c29e5f0fSliuyi 		return false;
315c29e5f0fSliuyi 	}
316c29e5f0fSliuyi 	pos = strUuidInfo.find('=');
317c29e5f0fSliuyi 	if (pos == string::npos) {
318c29e5f0fSliuyi 		return false;
319c29e5f0fSliuyi 	}
320c29e5f0fSliuyi 	strName = strUuidInfo.substr(0, pos);
321c29e5f0fSliuyi 	strName.erase(0, strName.find_first_not_of(" "));
322c29e5f0fSliuyi 	strName.erase(strName.find_last_not_of(" ") + 1);
323c29e5f0fSliuyi 
324c29e5f0fSliuyi 	strUUid = strUuidInfo.substr(pos+1);
325c29e5f0fSliuyi 	strUUid.erase(0, strUUid.find_first_not_of(" "));
326c29e5f0fSliuyi 	strUUid.erase(strUUid.find_last_not_of(" ") + 1);
327c29e5f0fSliuyi 
328c29e5f0fSliuyi 	while(true) {
329c29e5f0fSliuyi 		pos = 0;
330c29e5f0fSliuyi 		if( (pos = strUUid.find("-")) != string::npos)
331c29e5f0fSliuyi 			strUUid.replace(pos,1,"");
332c29e5f0fSliuyi 		else
333c29e5f0fSliuyi 			break;
334c29e5f0fSliuyi 	}
335c29e5f0fSliuyi 	if (strUUid.size() != 32)
336c29e5f0fSliuyi 		return false;
337c29e5f0fSliuyi 	return true;
338c29e5f0fSliuyi }
339c29e5f0fSliuyi 
340c29e5f0fSliuyi 
parse_parameter(char * pParameter,PARAM_ITEM_VECTOR & vecItem,CONFIG_ITEM_VECTOR & vecUuidItem)341c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
342c30d921cSKever Yang {
343c30d921cSKever Yang 	stringstream paramStream(pParameter);
344c30d921cSKever Yang 	bool bRet,bFind = false;
345c29e5f0fSliuyi 	string strLine, strPartition, strPartInfo, strPartName, strUUid;
346c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
347c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
348c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
349c29e5f0fSliuyi 	STRUCT_CONFIG_ITEM uuid_item;
350c30d921cSKever Yang 	vecItem.clear();
351c29e5f0fSliuyi 	vecUuidItem.clear();
352c30d921cSKever Yang 	while (!paramStream.eof()) {
353c30d921cSKever Yang 		getline(paramStream,strLine);
354c30d921cSKever Yang 		line_size = strLine.size();
355c30d921cSKever Yang 		if (line_size == 0)
356c30d921cSKever Yang 			continue;
357c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
358c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
359c30d921cSKever Yang 		}
360c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
361c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
362c30d921cSKever Yang 		if (strLine.size()==0 )
363c30d921cSKever Yang 			continue;
364c30d921cSKever Yang 		if (strLine[0] == '#')
365c30d921cSKever Yang 			continue;
366c29e5f0fSliuyi 		pos = strLine.find("uuid:");
367c29e5f0fSliuyi 		if (pos != string::npos) {
368c29e5f0fSliuyi 			strPartInfo = strLine.substr(pos+5);
369c29e5f0fSliuyi 			bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid);
370c29e5f0fSliuyi 			if (bRet) {
371c29e5f0fSliuyi 				strcpy(uuid_item.szItemName, strPartName.c_str());
372c29e5f0fSliuyi 				string_to_uuid(strUUid,uuid_item.szItemValue);
373c29e5f0fSliuyi 				vecUuidItem.push_back(uuid_item);
374c29e5f0fSliuyi 			}
375c29e5f0fSliuyi 			continue;
376c29e5f0fSliuyi 		}
377c29e5f0fSliuyi 
378c30d921cSKever Yang 		pos = strLine.find("mtdparts");
379c30d921cSKever Yang 		if (pos == string::npos) {
380c30d921cSKever Yang 			continue;
381c30d921cSKever Yang 		}
382c30d921cSKever Yang 		bFind = true;
383c30d921cSKever Yang 		posColon = strLine.find(':', pos);
384c30d921cSKever Yang 		if (posColon == string::npos) {
385c30d921cSKever Yang 			continue;
386c30d921cSKever Yang 		}
387c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
388c30d921cSKever Yang 		pos = 0;
389c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
390c30d921cSKever Yang 		while (posComma != string::npos) {
391c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
392c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
393c30d921cSKever Yang 			if (bRet) {
394c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
395c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
396c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
397c30d921cSKever Yang 				vecItem.push_back(item);
398c30d921cSKever Yang 			}
399c30d921cSKever Yang 			pos = posComma + 1;
400c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
401c30d921cSKever Yang 		}
402c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
403c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
404c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
405c30d921cSKever Yang 			if (bRet) {
406c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
407c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
408c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
409c30d921cSKever Yang 				vecItem.push_back(item);
410c30d921cSKever Yang 			}
411c30d921cSKever Yang 		}
412c30d921cSKever Yang 	}
413c30d921cSKever Yang 	return bFind;
414c30d921cSKever Yang 
415c30d921cSKever Yang }
parse_parameter_file(char * pParamFile,PARAM_ITEM_VECTOR & vecItem,CONFIG_ITEM_VECTOR & vecUuidItem)416c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
417c30d921cSKever Yang {
418c30d921cSKever Yang 	FILE *file = NULL;
419c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
420c30d921cSKever Yang 	if( !file ) {
421c30d921cSKever Yang 		if (g_pLogObject)
42232268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
423c30d921cSKever Yang 		return false;
424c30d921cSKever Yang 	}
425c30d921cSKever Yang 	int iFileSize;
426c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
427c30d921cSKever Yang 	iFileSize = ftell(file);
428c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
429c30d921cSKever Yang 	char *pParamBuf = NULL;
430c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
431c30d921cSKever Yang 	if (!pParamBuf) {
432c30d921cSKever Yang 		fclose(file);
433c30d921cSKever Yang 		return false;
434c30d921cSKever Yang 	}
435c30d921cSKever Yang 	int iRead;
436c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
437c30d921cSKever Yang 	if (iRead != iFileSize) {
438c30d921cSKever Yang 		if (g_pLogObject)
43932268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
440c30d921cSKever Yang 		fclose(file);
441c30d921cSKever Yang 		delete []pParamBuf;
442c30d921cSKever Yang 		return false;
443c30d921cSKever Yang 	}
444c30d921cSKever Yang 	fclose(file);
445c30d921cSKever Yang 	bool bRet;
446c29e5f0fSliuyi 	bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem);
447c30d921cSKever Yang 	delete []pParamBuf;
448c30d921cSKever Yang 	return bRet;
449c30d921cSKever Yang }
is_sparse_image(char * szImage)4506ae612beSliuyi bool is_sparse_image(char *szImage)
4516ae612beSliuyi {
4526ae612beSliuyi 	FILE *file = NULL;
4536ae612beSliuyi 	sparse_header head;
4546ae612beSliuyi 	u32 uiRead;
4556ae612beSliuyi 	file = fopen(szImage, "rb");
4566ae612beSliuyi 	if( !file ) {
4576ae612beSliuyi 		if (g_pLogObject)
4586ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
4596ae612beSliuyi 		return false;
4606ae612beSliuyi 	}
4616ae612beSliuyi 	uiRead = fread(&head, 1, sizeof(head), file);
4626ae612beSliuyi 	if (uiRead != sizeof(head)) {
4636ae612beSliuyi 		if (g_pLogObject)
4646ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head));
4656ae612beSliuyi 		fclose(file);
4666ae612beSliuyi 		return false;
4676ae612beSliuyi 	}
4686ae612beSliuyi 	fclose(file);
4696ae612beSliuyi 	if (head.magic!=SPARSE_HEADER_MAGIC)
4706ae612beSliuyi 	{
4716ae612beSliuyi 		return false;
4726ae612beSliuyi 	}
4736ae612beSliuyi 	return true;
4746ae612beSliuyi 
4756ae612beSliuyi }
is_ubifs_image(char * szImage)4760dcb0a4cSliuyi bool is_ubifs_image(char *szImage)
4770dcb0a4cSliuyi {
4780dcb0a4cSliuyi 	FILE *file = NULL;
4790dcb0a4cSliuyi 	u32 magic;
4800dcb0a4cSliuyi 	u32 uiRead;
4810dcb0a4cSliuyi 	file = fopen(szImage, "rb");
4820dcb0a4cSliuyi 	if( !file ) {
4830dcb0a4cSliuyi 		if (g_pLogObject)
4840dcb0a4cSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
4850dcb0a4cSliuyi 		return false;
4860dcb0a4cSliuyi 	}
4870dcb0a4cSliuyi 	uiRead = fread(&magic, 1, sizeof(magic), file);
4880dcb0a4cSliuyi 	if (uiRead != sizeof(magic)) {
4890dcb0a4cSliuyi 		if (g_pLogObject)
4900dcb0a4cSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(magic));
4910dcb0a4cSliuyi 		fclose(file);
4920dcb0a4cSliuyi 		return false;
4930dcb0a4cSliuyi 	}
4940dcb0a4cSliuyi 	fclose(file);
4950dcb0a4cSliuyi 	if (magic!=UBI_HEADER_MAGIC)
4960dcb0a4cSliuyi 	{
4970dcb0a4cSliuyi 		return false;
4980dcb0a4cSliuyi 	}
4990dcb0a4cSliuyi 	return true;
5000dcb0a4cSliuyi }
gen_rand_uuid(unsigned char * uuid_bin)501c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
502c30d921cSKever Yang {
503c30d921cSKever Yang 	efi_guid_t id;
504c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
505c30d921cSKever Yang 	unsigned int i;
506c30d921cSKever Yang 
507c30d921cSKever Yang 	/* Set all fields randomly */
508c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
509c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
510c30d921cSKever Yang 
511c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
512c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
513c30d921cSKever Yang 
514c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
515c30d921cSKever Yang }
516c30d921cSKever Yang 
prepare_gpt_backup(u8 * master,u8 * backup)517c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup)
518c29e5f0fSliuyi {
519c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
520c29e5f0fSliuyi 	gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
521c29e5f0fSliuyi 	u32 calc_crc32;
522c29e5f0fSliuyi 	u64 val;
523c29e5f0fSliuyi 
524c29e5f0fSliuyi 	/* recalculate the values for the Backup GPT Header */
525c29e5f0fSliuyi 	val = le64_to_cpu(gptMasterHead->my_lba);
526c29e5f0fSliuyi 	gptBackupHead->my_lba = gptMasterHead->alternate_lba;
527c29e5f0fSliuyi 	gptBackupHead->alternate_lba = cpu_to_le64(val);
528c29e5f0fSliuyi 	gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
529c29e5f0fSliuyi 	gptBackupHead->header_crc32 = 0;
530c29e5f0fSliuyi 
531c29e5f0fSliuyi 	calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
532c29e5f0fSliuyi 	gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
533c29e5f0fSliuyi }
get_lba_from_gpt(u8 * master,char * pszName,u64 * lba,u64 * lba_end)5346ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end)
5356ae612beSliuyi {
5366ae612beSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
5376ae612beSliuyi 	gpt_entry  *gptEntry  = NULL;
5386ae612beSliuyi 	u32 i,j;
5396ae612beSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
5406ae612beSliuyi 	bool bFound = false;
5416ae612beSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
5426ae612beSliuyi 
5436ae612beSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
5446ae612beSliuyi 		gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
5456ae612beSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
5466ae612beSliuyi 			break;
5476ae612beSliuyi 		for (j = 0; j < strlen(pszName); j++)
5486ae612beSliuyi 			if (gptEntry->partition_name[j] != pszName[j])
5496ae612beSliuyi 				break;
5506ae612beSliuyi 		if (gptEntry->partition_name[j] != 0)
5516ae612beSliuyi 			continue;
5526ae612beSliuyi 		if (j == strlen(pszName)) {
5536ae612beSliuyi 			bFound = true;
5546ae612beSliuyi 			break;
5556ae612beSliuyi 		}
5566ae612beSliuyi 	}
5576ae612beSliuyi 	if (bFound) {
5586ae612beSliuyi 		*lba = le64_to_cpu(gptEntry->starting_lba);
559e541b7bbSliuyi 		if (gptMasterHead->last_usable_lba == gptEntry->ending_lba)
560e541b7bbSliuyi 			*lba_end = 0xFFFFFFFF;
561e541b7bbSliuyi 		else
5626ae612beSliuyi 			*lba_end =  le64_to_cpu(gptEntry->ending_lba);
5636ae612beSliuyi 		return true;
5646ae612beSliuyi 	}
5656ae612beSliuyi 	return false;
5666ae612beSliuyi }
get_lba_from_param(u8 * param,char * pszName,u32 * part_offset,u32 * part_size)567081d237aSliuyi bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size)
568081d237aSliuyi {
569081d237aSliuyi 	u32 i;
570081d237aSliuyi 	bool bFound = false, bRet;
571081d237aSliuyi 	PARAM_ITEM_VECTOR vecItem;
572081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
573081d237aSliuyi 
574081d237aSliuyi 	bRet = parse_parameter((char *)param, vecItem, vecUuid);
575081d237aSliuyi 	if (!bRet)
576081d237aSliuyi 		return false;
577081d237aSliuyi 
578081d237aSliuyi 	for (i = 0; i < vecItem.size(); i++) {
579081d237aSliuyi 		if (strcasecmp(pszName, vecItem[i].szItemName)==0) {
580081d237aSliuyi 			bFound = true;
581081d237aSliuyi 			break;
582081d237aSliuyi 		}
583081d237aSliuyi 	}
584081d237aSliuyi 	if (bFound) {
585081d237aSliuyi 		*part_offset = vecItem[i].uiItemOffset;
586081d237aSliuyi 		*part_size =  vecItem[i].uiItemSize;
587081d237aSliuyi 		return true;
588081d237aSliuyi 	}
589081d237aSliuyi 	return false;
590081d237aSliuyi }
591081d237aSliuyi 
update_gpt_disksize(u8 * master,u8 * backup,u32 total_sector)592c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector)
593c29e5f0fSliuyi {
594c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
595c29e5f0fSliuyi 	gpt_entry  *gptLastPartEntry  = NULL;
596c29e5f0fSliuyi 	u32 i;
597c29e5f0fSliuyi 	u64 old_disksize;
598c29e5f0fSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
599c29e5f0fSliuyi 
600c29e5f0fSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
601c29e5f0fSliuyi 	old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1;
602c29e5f0fSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
603c29e5f0fSliuyi 		gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
604c29e5f0fSliuyi 		if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0)
605c29e5f0fSliuyi 			break;
606c29e5f0fSliuyi 	}
607c29e5f0fSliuyi 	i--;
608c29e5f0fSliuyi 	gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry));
609c29e5f0fSliuyi 
610c29e5f0fSliuyi 	gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1);
611c29e5f0fSliuyi 	gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34);
612c29e5f0fSliuyi 
613c29e5f0fSliuyi 	if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition
614c29e5f0fSliuyi 		gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34);
615c29e5f0fSliuyi 		gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
616c29e5f0fSliuyi 	}
617c29e5f0fSliuyi 	gptMasterHead->header_crc32 = 0;
618c29e5f0fSliuyi 	gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header)));
619c29e5f0fSliuyi 	memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS);
620c29e5f0fSliuyi 	memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE);
621c29e5f0fSliuyi 	prepare_gpt_backup(master, backup);
622c29e5f0fSliuyi 
623c29e5f0fSliuyi }
load_gpt_buffer(char * pParamFile,u8 * master,u8 * backup)624c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup)
625c29e5f0fSliuyi {
626c29e5f0fSliuyi 	FILE *file = NULL;
627c29e5f0fSliuyi 	file = fopen(pParamFile, "rb");
628c29e5f0fSliuyi 	if( !file ) {
629c29e5f0fSliuyi 		if (g_pLogObject)
630c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
631c29e5f0fSliuyi 		return false;
632c29e5f0fSliuyi 	}
633c29e5f0fSliuyi 	int iFileSize;
634c29e5f0fSliuyi 	fseek(file, 0, SEEK_END);
635c29e5f0fSliuyi 	iFileSize = ftell(file);
636c29e5f0fSliuyi 	fseek(file, 0, SEEK_SET);
637c29e5f0fSliuyi 	if (iFileSize != 67 * SECTOR_SIZE) {
638c29e5f0fSliuyi 		if (g_pLogObject)
639c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile);
640c29e5f0fSliuyi 		fclose(file);
641c29e5f0fSliuyi 		return false;
642c29e5f0fSliuyi 	}
643c29e5f0fSliuyi 
644c29e5f0fSliuyi 	int iRead;
645c29e5f0fSliuyi 	iRead = fread(master, 1, 34 * SECTOR_SIZE, file);
646c29e5f0fSliuyi 	if (iRead != 34 * SECTOR_SIZE) {
647c29e5f0fSliuyi 		if (g_pLogObject)
648c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE);
649c29e5f0fSliuyi 		fclose(file);
650c29e5f0fSliuyi 		return false;
651c29e5f0fSliuyi 	}
652c29e5f0fSliuyi 	iRead = fread(backup, 1, 33 * SECTOR_SIZE, file);
653c29e5f0fSliuyi 	if (iRead != 33 * SECTOR_SIZE) {
654c29e5f0fSliuyi 		if (g_pLogObject)
655c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE);
656c29e5f0fSliuyi 		fclose(file);
657c29e5f0fSliuyi 		return false;
658c29e5f0fSliuyi 	}
659c29e5f0fSliuyi 	fclose(file);
660c29e5f0fSliuyi 	return true;
661c29e5f0fSliuyi }
create_gpt_buffer(u8 * gpt,PARAM_ITEM_VECTOR & vecParts,CONFIG_ITEM_VECTOR & vecUuid,u64 diskSectors)662c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
663c30d921cSKever Yang {
664c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
665c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
666c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
667c30d921cSKever Yang 	u32 i,j;
668c29e5f0fSliuyi 	int pos;
669c30d921cSKever Yang 	string strPartName;
670c30d921cSKever Yang 	string::size_type colonPos;
671c30d921cSKever Yang 	/*1.protective mbr*/
672c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
673c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
674c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
675c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
676c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
677c30d921cSKever Yang 	/*2.gpt header*/
678c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
679c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
680c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
681c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
682c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
683c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
684c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
685c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
686c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
687c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
688c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
689c30d921cSKever Yang 	gptHead->header_crc32 = 0;
690c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
691c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
692c30d921cSKever Yang 
693c30d921cSKever Yang 	/*3.gpt partition entry*/
694c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
695c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
696c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
697c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
698c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
699c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
700c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
701c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
702c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
703c30d921cSKever Yang 		if (colonPos != string::npos) {
704c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
705c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
706c29e5f0fSliuyi 			if (strPartName.find("grow") != string::npos)
707c29e5f0fSliuyi 				gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
708c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
709c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
710c30d921cSKever Yang 		}
711c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
712c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
713c29e5f0fSliuyi 		if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1)
714c29e5f0fSliuyi 			memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
715c30d921cSKever Yang 		gptEntry++;
716c30d921cSKever Yang 	}
717c30d921cSKever Yang 
718c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
719c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
720c30d921cSKever Yang 
721c30d921cSKever Yang }
MakeSector0(PBYTE pSector,USHORT usFlashDataSec,USHORT usFlashBootSec,bool rc4Flag)722b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
723c30d921cSKever Yang {
724c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
725c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
726c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
727c30d921cSKever Yang 
728c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
729b38fe5fcSliuyi 	pSec0->uiRc4Flag = rc4Flag;
730c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
731c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
732c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
733c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
734c30d921cSKever Yang 	return true;
735c30d921cSKever Yang }
736c30d921cSKever Yang 
737c30d921cSKever Yang 
MakeSector1(PBYTE pSector)738c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
739c30d921cSKever Yang {
740c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
741c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
742c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
743c30d921cSKever Yang 
744c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
745c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
746c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
747c30d921cSKever Yang 	return true;
748c30d921cSKever Yang }
749c30d921cSKever Yang 
MakeSector2(PBYTE pSector)750c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
751c30d921cSKever Yang {
752c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
753c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
754c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
755c30d921cSKever Yang 
756c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
757c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
758c30d921cSKever Yang 	return true;
759c30d921cSKever Yang }
760c30d921cSKever Yang 
MakeSector3(PBYTE pSector)761c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
762c30d921cSKever Yang {
763c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
764c30d921cSKever Yang 	return true;
765c30d921cSKever Yang }
766c30d921cSKever Yang 
MakeIDBlockData(PBYTE pDDR,PBYTE pLoader,PBYTE lpIDBlock,USHORT usFlashDataSec,USHORT usFlashBootSec,DWORD dwLoaderDataSize,DWORD dwLoaderSize,bool rc4Flag)767b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
768c30d921cSKever Yang {
769c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
770c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
771c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
772c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
773c30d921cSKever Yang 	UINT i;
774b38fe5fcSliuyi 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
775c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
776c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
777c30d921cSKever Yang 		return -6;
778c30d921cSKever Yang 	}
779c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
780c30d921cSKever Yang 		return -7;
781c30d921cSKever Yang 	}
782c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
783c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
784c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
785c30d921cSKever Yang 
786c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
787c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
788c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
789b38fe5fcSliuyi 
790b38fe5fcSliuyi 	if (rc4Flag) {
791b38fe5fcSliuyi 		for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
792b38fe5fcSliuyi 			P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
793b38fe5fcSliuyi 		for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
794b38fe5fcSliuyi 			P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
795b38fe5fcSliuyi 	}
796b38fe5fcSliuyi 
797c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
798c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
799c30d921cSKever Yang 
800c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
801c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
802c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
803c30d921cSKever Yang 		if(i == 1) {
804c30d921cSKever Yang 			continue;
805c30d921cSKever Yang 		} else {
806c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
807c30d921cSKever Yang 		}
808c30d921cSKever Yang 	}
809c30d921cSKever Yang 	return 0;
810c30d921cSKever Yang }
811c30d921cSKever Yang 
812c30d921cSKever Yang 
81376af099aSliuyi 
check_device_type(STRUCT_RKDEVICE_DESC & dev,UINT uiSupportType)81476af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
81576af099aSliuyi {
81606ea143eSKlaus Goger 	if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType)
81776af099aSliuyi 		return true;
81876af099aSliuyi 	else
81976af099aSliuyi 	{
82076af099aSliuyi 		ERROR_COLOR_ATTR;
82132268622SAndreas Färber 		printf("The device does not support this operation!");
82276af099aSliuyi 		NORMAL_COLOR_ATTR;
82376af099aSliuyi 		printf("\r\n");
82476af099aSliuyi 		return false;
82576af099aSliuyi 	}
82676af099aSliuyi }
MakeParamBuffer(char * pParamFile,char * & pParamData)827081d237aSliuyi bool MakeParamBuffer(char *pParamFile, char* &pParamData)
828081d237aSliuyi {
829081d237aSliuyi 	FILE *file=NULL;
830081d237aSliuyi 	file = fopen(pParamFile, "rb");
831081d237aSliuyi 	if( !file )
832081d237aSliuyi 	{
833081d237aSliuyi 		if (g_pLogObject)
834081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile);
835081d237aSliuyi 		return false;
836081d237aSliuyi 	}
837081d237aSliuyi 	int iFileSize;
838081d237aSliuyi 	fseek(file,0,SEEK_END);
839081d237aSliuyi 	iFileSize = ftell(file);
840081d237aSliuyi 	fseek(file,0,SEEK_SET);
841081d237aSliuyi 	char *pParamBuf=NULL;
842081d237aSliuyi 	pParamBuf = new char[iFileSize + 12];
843081d237aSliuyi 	if (!pParamBuf)
844081d237aSliuyi 	{
845081d237aSliuyi 		fclose(file);
846081d237aSliuyi 		return false;
847081d237aSliuyi 	}
848081d237aSliuyi 	memset(pParamBuf,0,iFileSize+12);
849081d237aSliuyi 	*(UINT *)(pParamBuf) = 0x4D524150;
850081d237aSliuyi 
851081d237aSliuyi 	int iRead;
852081d237aSliuyi 	iRead = fread(pParamBuf+8,1,iFileSize,file);
853081d237aSliuyi 	if (iRead!=iFileSize)
854081d237aSliuyi 	{
855081d237aSliuyi 		if (g_pLogObject)
856081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize);
857081d237aSliuyi 		fclose(file);
858081d237aSliuyi 		delete []pParamBuf;
859081d237aSliuyi 		return false;
860081d237aSliuyi 	}
861081d237aSliuyi 	fclose(file);
862081d237aSliuyi 
863081d237aSliuyi 	*(UINT *)(pParamBuf+4) = iFileSize;
864081d237aSliuyi 	*(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize);
865081d237aSliuyi 	pParamData = pParamBuf;
866081d237aSliuyi 	return true;
867081d237aSliuyi }
868081d237aSliuyi 
write_parameter(STRUCT_RKDEVICE_DESC & dev,char * szParameter)869081d237aSliuyi bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
870081d237aSliuyi {
871081d237aSliuyi 	CRKComm *pComm = NULL;
872081d237aSliuyi 	char *pParamBuf = NULL, writeBuf[512*1024];
873081d237aSliuyi 	int iRet, nParamSec, nParamSize;
874081d237aSliuyi 	bool bRet, bSuccess = false;
875081d237aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER))
876081d237aSliuyi 		return false;
877081d237aSliuyi 
878081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
879081d237aSliuyi 	if (!bRet) {
880081d237aSliuyi 		ERROR_COLOR_ATTR;
881081d237aSliuyi 		printf("Creating Comm Object failed!");
882081d237aSliuyi 		NORMAL_COLOR_ATTR;
883081d237aSliuyi 		printf("\r\n");
884081d237aSliuyi 		return bSuccess;
885081d237aSliuyi 	}
886081d237aSliuyi 	if (!MakeParamBuffer(szParameter, pParamBuf)) {
887081d237aSliuyi 		ERROR_COLOR_ATTR;
888081d237aSliuyi 		printf("Generating parameter failed!");
889081d237aSliuyi 		NORMAL_COLOR_ATTR;
890081d237aSliuyi 		printf("\r\n");
891081d237aSliuyi 		return bSuccess;
892081d237aSliuyi 	}
893081d237aSliuyi 	printf("Writing parameter...\r\n");
894081d237aSliuyi 	nParamSize = *(UINT *)(pParamBuf+4) + 12;
895081d237aSliuyi 	nParamSec = BYTE2SECTOR(nParamSize);
896081d237aSliuyi 	if (nParamSec > 1024) {
897081d237aSliuyi 		ERROR_COLOR_ATTR;
898081d237aSliuyi 		printf("parameter is too large!");
899081d237aSliuyi 		NORMAL_COLOR_ATTR;
900081d237aSliuyi 		printf("\r\n");
901081d237aSliuyi 		return bSuccess;
902081d237aSliuyi 	}
903081d237aSliuyi 	memset(writeBuf, 0, nParamSec*512);
904081d237aSliuyi 	memcpy(writeBuf, pParamBuf, nParamSize);
905081d237aSliuyi 	iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf);
906081d237aSliuyi 	if (iRet != ERR_SUCCESS) {
907081d237aSliuyi 		ERROR_COLOR_ATTR;
908081d237aSliuyi 		printf("Writing parameter failed!");
909081d237aSliuyi 		NORMAL_COLOR_ATTR;
910081d237aSliuyi 		printf("\r\n");
911081d237aSliuyi 		return bSuccess;
912081d237aSliuyi 	}
913081d237aSliuyi 
914081d237aSliuyi 	bSuccess = true;
915081d237aSliuyi 	CURSOR_MOVEUP_LINE(1);
916081d237aSliuyi 	CURSOR_DEL_LINE;
917081d237aSliuyi 	printf("Writing parameter succeeded.\r\n");
918081d237aSliuyi 	return bSuccess;
919081d237aSliuyi }
920081d237aSliuyi 
write_gpt(STRUCT_RKDEVICE_DESC & dev,char * szParameter)921c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
922c30d921cSKever Yang {
923c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
924c30d921cSKever Yang 	u32 total_size_sector;
925c30d921cSKever Yang 	CRKComm *pComm = NULL;
926c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
927c29e5f0fSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
928c30d921cSKever Yang 	int iRet;
929c30d921cSKever Yang 	bool bRet, bSuccess = false;
930c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
931c30d921cSKever Yang 		return false;
932c30d921cSKever Yang 
933c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
934c30d921cSKever Yang 	if (!bRet) {
935c30d921cSKever Yang 		ERROR_COLOR_ATTR;
936c30d921cSKever Yang 		printf("Creating Comm Object failed!");
937c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
938c30d921cSKever Yang 		printf("\r\n");
939c30d921cSKever Yang 		return bSuccess;
940c30d921cSKever Yang 	}
94132268622SAndreas Färber 	printf("Writing gpt...\r\n");
942c30d921cSKever Yang 	//1.get flash info
943c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
944c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
945c30d921cSKever Yang 		ERROR_COLOR_ATTR;
946c30d921cSKever Yang 		printf("Reading Flash Info failed!");
947c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
948c30d921cSKever Yang 		printf("\r\n");
949c30d921cSKever Yang 		return bSuccess;
950c30d921cSKever Yang 	}
951c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
952c29e5f0fSliuyi 	if (strstr(szParameter, ".img")) {
953c29e5f0fSliuyi 		if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) {
954c29e5f0fSliuyi 			ERROR_COLOR_ATTR;
955c29e5f0fSliuyi 			printf("Loading partition image failed!");
956c29e5f0fSliuyi 			NORMAL_COLOR_ATTR;
957c29e5f0fSliuyi 			printf("\r\n");
958c29e5f0fSliuyi 			return bSuccess;
959c29e5f0fSliuyi 		}
960c29e5f0fSliuyi 		update_gpt_disksize(master_gpt, backup_gpt, total_size_sector);
961c29e5f0fSliuyi 	} else {
962c30d921cSKever Yang 		//2.get partition from parameter
963c29e5f0fSliuyi 		bRet = parse_parameter_file(szParameter, vecItems, vecUuid);
964c30d921cSKever Yang 		if (!bRet) {
965c30d921cSKever Yang 			ERROR_COLOR_ATTR;
966c30d921cSKever Yang 			printf("Parsing parameter failed!");
967c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
968c30d921cSKever Yang 			printf("\r\n");
969c30d921cSKever Yang 			return bSuccess;
970c30d921cSKever Yang 		}
971c30d921cSKever Yang 		//3.generate gpt info
972c29e5f0fSliuyi 		create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector);
973c30d921cSKever Yang 		memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
974c30d921cSKever Yang 		memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
975c29e5f0fSliuyi 		prepare_gpt_backup(master_gpt, backup_gpt);
976c29e5f0fSliuyi 	}
977c29e5f0fSliuyi 
978c30d921cSKever Yang 	//4. write gpt
979c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
980c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
981c30d921cSKever Yang 		ERROR_COLOR_ATTR;
982c30d921cSKever Yang 		printf("Writing master gpt failed!");
983c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
984c30d921cSKever Yang 		printf("\r\n");
985c30d921cSKever Yang 		return bSuccess;
986c30d921cSKever Yang 	}
987c29e5f0fSliuyi 	iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt);
988c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
989c30d921cSKever Yang 		ERROR_COLOR_ATTR;
990c30d921cSKever Yang 		printf("Writing backup gpt failed!");
991c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
992c30d921cSKever Yang 		printf("\r\n");
993c30d921cSKever Yang 		return bSuccess;
994c30d921cSKever Yang 	}
995c29e5f0fSliuyi 
996c30d921cSKever Yang 	bSuccess = true;
997c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
998c30d921cSKever Yang 	CURSOR_DEL_LINE;
99932268622SAndreas Färber 	printf("Writing gpt succeeded.\r\n");
1000c30d921cSKever Yang 	return bSuccess;
1001c30d921cSKever Yang }
100276af099aSliuyi 
100378884ef4SEddie Cai #include "boot_merger.h"
100478884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
100578884ef4SEddie Cai options gOpts;
100678884ef4SEddie Cai 
100778884ef4SEddie Cai 
100878884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
100978884ef4SEddie Cai char* gConfigPath;
101078884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
101178884ef4SEddie Cai 
fixPath(char * path)101278884ef4SEddie Cai static inline void fixPath(char* path) {
101378884ef4SEddie Cai 	int i, len = strlen(path);
101478884ef4SEddie Cai 	for(i=0; i<len; i++) {
101578884ef4SEddie Cai 		if (path[i] == '\\')
101678884ef4SEddie Cai 			path[i] = '/';
101778884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
101878884ef4SEddie Cai 			path[i] = '\0';
101978884ef4SEddie Cai 	}
102078884ef4SEddie Cai }
102178884ef4SEddie Cai 
parseChip(FILE * file)102278884ef4SEddie Cai static bool parseChip(FILE* file) {
102378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
102478884ef4SEddie Cai 		return false;
102578884ef4SEddie Cai 	}
102678884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
102778884ef4SEddie Cai 		return false;
102878884ef4SEddie Cai 	}
102978884ef4SEddie Cai 	printf("chip: %s\n", gOpts.chip);
103078884ef4SEddie Cai 	return true;
103178884ef4SEddie Cai }
103278884ef4SEddie Cai 
parseVersion(FILE * file)103378884ef4SEddie Cai static bool parseVersion(FILE* file) {
103478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
103578884ef4SEddie Cai 		return false;
103678884ef4SEddie Cai 	}
103778884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
103878884ef4SEddie Cai 		return false;
103978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
104078884ef4SEddie Cai 		return false;
104178884ef4SEddie Cai 	}
104278884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
104378884ef4SEddie Cai 		return false;
104478884ef4SEddie Cai 	printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
104578884ef4SEddie Cai 	return true;
104678884ef4SEddie Cai }
104778884ef4SEddie Cai 
parse471(FILE * file)104878884ef4SEddie Cai static bool parse471(FILE* file) {
104978884ef4SEddie Cai 	int i, index, pos;
105078884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
105178884ef4SEddie Cai 
105278884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
105378884ef4SEddie Cai 		return false;
105478884ef4SEddie Cai 	}
105578884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
105678884ef4SEddie Cai 		return false;
105778884ef4SEddie Cai 	printf("num: %d\n", gOpts.code471Num);
105878884ef4SEddie Cai 	if (!gOpts.code471Num)
105978884ef4SEddie Cai 		return true;
106078884ef4SEddie Cai 	if (gOpts.code471Num < 0)
106178884ef4SEddie Cai 		return false;
106278884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
106378884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
106478884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
106578884ef4SEddie Cai 			return false;
106678884ef4SEddie Cai 		}
106778884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
106878884ef4SEddie Cai 				!= 2)
106978884ef4SEddie Cai 			return false;
107078884ef4SEddie Cai 		index--;
107178884ef4SEddie Cai 		fixPath(buf);
107278884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
107378884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code471Path[index]);
107478884ef4SEddie Cai 	}
107578884ef4SEddie Cai 	pos = ftell(file);
107678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
107778884ef4SEddie Cai 		return false;
107878884ef4SEddie Cai 	}
107978884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
108078884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
108178884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code471Sleep);
108278884ef4SEddie Cai 	return true;
108378884ef4SEddie Cai }
108478884ef4SEddie Cai 
parse472(FILE * file)108578884ef4SEddie Cai static bool parse472(FILE* file) {
108678884ef4SEddie Cai 	int i, index, pos;
108778884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
108878884ef4SEddie Cai 
108978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
109078884ef4SEddie Cai 		return false;
109178884ef4SEddie Cai 	}
109278884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
109378884ef4SEddie Cai 		return false;
109478884ef4SEddie Cai 	printf("num: %d\n", gOpts.code472Num);
109578884ef4SEddie Cai 	if (!gOpts.code472Num)
109678884ef4SEddie Cai 		return true;
109778884ef4SEddie Cai 	if (gOpts.code472Num < 0)
109878884ef4SEddie Cai 		return false;
109978884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
110078884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
110178884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
110278884ef4SEddie Cai 			return false;
110378884ef4SEddie Cai 		}
110478884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
110578884ef4SEddie Cai 				!= 2)
110678884ef4SEddie Cai 			return false;
110778884ef4SEddie Cai 		fixPath(buf);
110878884ef4SEddie Cai 		index--;
110978884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
111078884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code472Path[index]);
111178884ef4SEddie Cai 	}
111278884ef4SEddie Cai 	pos = ftell(file);
111378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
111478884ef4SEddie Cai 		return false;
111578884ef4SEddie Cai 	}
111678884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
111778884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
111878884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code472Sleep);
111978884ef4SEddie Cai 	return true;
112078884ef4SEddie Cai }
112178884ef4SEddie Cai 
parseLoader(FILE * file)112278884ef4SEddie Cai static bool parseLoader(FILE* file) {
112378884ef4SEddie Cai 	int i, j, index, pos;
112478884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
112578884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
112678884ef4SEddie Cai 
112778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
112878884ef4SEddie Cai 		return false;
112978884ef4SEddie Cai 	}
113078884ef4SEddie Cai 	pos = ftell(file);
113178884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
113278884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
113378884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
113478884ef4SEddie Cai 			return false;
113578884ef4SEddie Cai 		}
113678884ef4SEddie Cai 	}
113778884ef4SEddie Cai 	printf("num: %d\n", gOpts.loaderNum);
113878884ef4SEddie Cai 	if (!gOpts.loaderNum)
113978884ef4SEddie Cai 		return false;
114078884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
114178884ef4SEddie Cai 		return false;
114278884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
114378884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
114478884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
114578884ef4SEddie Cai 			return false;
114678884ef4SEddie Cai 		}
114778884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
114878884ef4SEddie Cai 				!= 2)
114978884ef4SEddie Cai 			return false;
115078884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
115178884ef4SEddie Cai 		printf("name%d: %s\n", index, gOpts.loader[index].name);
1152544ec1d4SKlaus Goger 		index++;
115378884ef4SEddie Cai 	}
115478884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
115578884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
115678884ef4SEddie Cai 			return false;
115778884ef4SEddie Cai 		}
115878884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
115978884ef4SEddie Cai 				!= 2)
116078884ef4SEddie Cai 			return false;
116178884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
116278884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
116378884ef4SEddie Cai 				fixPath(buf2);
116478884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
116578884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
116678884ef4SEddie Cai 				break;
116778884ef4SEddie Cai 			}
116878884ef4SEddie Cai 		}
116978884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
117078884ef4SEddie Cai 			return false;
117178884ef4SEddie Cai 		}
117278884ef4SEddie Cai 	}
117378884ef4SEddie Cai 	return true;
117478884ef4SEddie Cai }
117578884ef4SEddie Cai 
parseOut(FILE * file)117678884ef4SEddie Cai static bool parseOut(FILE* file) {
117778884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
117878884ef4SEddie Cai 		return false;
117978884ef4SEddie Cai 	}
118078884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
118178884ef4SEddie Cai 		return false;
118278884ef4SEddie Cai 	fixPath(gOpts.outPath);
118378884ef4SEddie Cai 	printf("out: %s\n", gOpts.outPath);
118478884ef4SEddie Cai 	return true;
118578884ef4SEddie Cai }
118678884ef4SEddie Cai 
118778884ef4SEddie Cai 
printOpts(FILE * out)118878884ef4SEddie Cai void printOpts(FILE* out) {
118978884ef4SEddie Cai 	int i;
119078884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
119178884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
119278884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
119378884ef4SEddie Cai 
119478884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
119578884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
119678884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
119778884ef4SEddie Cai 	}
119878884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
119978884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
120078884ef4SEddie Cai 
120178884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
120278884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
120378884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
120478884ef4SEddie Cai 	}
120578884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
120678884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
120778884ef4SEddie Cai 
120878884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
120978884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
121078884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
121178884ef4SEddie Cai 	}
121278884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
121378884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
121478884ef4SEddie Cai 	}
121578884ef4SEddie Cai 
121678884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
121778884ef4SEddie Cai }
121878884ef4SEddie Cai 
parseOpts(void)121978884ef4SEddie Cai static bool parseOpts(void) {
122078884ef4SEddie Cai 	bool ret = false;
122178884ef4SEddie Cai 	bool chipOk = false;
122278884ef4SEddie Cai 	bool versionOk = false;
122378884ef4SEddie Cai 	bool code471Ok = true;
122478884ef4SEddie Cai 	bool code472Ok = true;
122578884ef4SEddie Cai 	bool loaderOk = false;
122678884ef4SEddie Cai 	bool outOk = false;
122778884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
122878884ef4SEddie Cai 
122978884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
123078884ef4SEddie Cai 	FILE* file;
123178884ef4SEddie Cai 	file = fopen(configPath, "r");
123278884ef4SEddie Cai 	if (!file) {
123378884ef4SEddie Cai 		fprintf(stderr, "config (%s) not found!\n", configPath);
123408c0d218SKlaus Goger 		if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) {
123578884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
123678884ef4SEddie Cai 			if (file) {
123732268622SAndreas Färber 				fprintf(stderr, "creating defconfig\n");
123878884ef4SEddie Cai 				printOpts(file);
123978884ef4SEddie Cai 			}
124078884ef4SEddie Cai 		}
124178884ef4SEddie Cai 		goto end;
124278884ef4SEddie Cai 	}
124378884ef4SEddie Cai 
124432268622SAndreas Färber 	printf("Starting to parse...\n");
124578884ef4SEddie Cai 
124678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
124778884ef4SEddie Cai 		goto end;
124878884ef4SEddie Cai 	}
124978884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
125078884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
125178884ef4SEddie Cai 			chipOk = parseChip(file);
125278884ef4SEddie Cai 			if (!chipOk) {
125378884ef4SEddie Cai 				printf("parseChip failed!\n");
125478884ef4SEddie Cai 				goto end;
125578884ef4SEddie Cai 			}
125678884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
125778884ef4SEddie Cai 			versionOk = parseVersion(file);
125878884ef4SEddie Cai 			if (!versionOk) {
125978884ef4SEddie Cai 				printf("parseVersion failed!\n");
126078884ef4SEddie Cai 				goto end;
126178884ef4SEddie Cai 			}
126278884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
126378884ef4SEddie Cai 			code471Ok = parse471(file);
126478884ef4SEddie Cai 			if (!code471Ok) {
126578884ef4SEddie Cai 				printf("parse471 failed!\n");
126678884ef4SEddie Cai 				goto end;
126778884ef4SEddie Cai 			}
126878884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
126978884ef4SEddie Cai 			code472Ok = parse472(file);
127078884ef4SEddie Cai 			if (!code472Ok) {
127178884ef4SEddie Cai 				printf("parse472 failed!\n");
127278884ef4SEddie Cai 				goto end;
127378884ef4SEddie Cai 			}
127478884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
127578884ef4SEddie Cai 			loaderOk = parseLoader(file);
127678884ef4SEddie Cai 			if (!loaderOk) {
127778884ef4SEddie Cai 				printf("parseLoader failed!\n");
127878884ef4SEddie Cai 				goto end;
127978884ef4SEddie Cai 			}
128078884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
128178884ef4SEddie Cai 			outOk = parseOut(file);
128278884ef4SEddie Cai 			if (!outOk) {
128378884ef4SEddie Cai 				printf("parseOut failed!\n");
128478884ef4SEddie Cai 				goto end;
128578884ef4SEddie Cai 			}
128678884ef4SEddie Cai 		} else if (buf[0] == '#') {
128778884ef4SEddie Cai 			continue;
128878884ef4SEddie Cai 		} else {
128978884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
129078884ef4SEddie Cai 			goto end;
129178884ef4SEddie Cai 		}
129278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
129378884ef4SEddie Cai 			goto end;
129478884ef4SEddie Cai 		}
129578884ef4SEddie Cai 	}
129678884ef4SEddie Cai 
129778884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
129878884ef4SEddie Cai 			&& loaderOk && outOk)
129978884ef4SEddie Cai 		ret = true;
130078884ef4SEddie Cai end:
130178884ef4SEddie Cai 	if (file)
130278884ef4SEddie Cai 		fclose(file);
130378884ef4SEddie Cai 	return ret;
130478884ef4SEddie Cai }
130578884ef4SEddie Cai 
initOpts(void)130678884ef4SEddie Cai bool initOpts(void) {
130778884ef4SEddie Cai 	//set default opts
130878884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
130978884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
131078884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
131178884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
131278884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
131378884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
131478884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
131578884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
131678884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
131778884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
131878884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
131978884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
132078884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
132178884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
132278884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
132378884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
132478884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
132578884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
132678884ef4SEddie Cai 
132778884ef4SEddie Cai 	return parseOpts();
132878884ef4SEddie Cai }
132978884ef4SEddie Cai 
133078884ef4SEddie Cai /************merge code****************/
133178884ef4SEddie Cai 
getBCD(unsigned short value)133278884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
133378884ef4SEddie Cai 	uint8_t tmp[2] = {0};
133478884ef4SEddie Cai 	int i;
133578884ef4SEddie Cai 	uint32_t ret;
133678884ef4SEddie Cai 	//if (value > 0xFFFF) {
133778884ef4SEddie Cai 	//	return 0;
133878884ef4SEddie Cai 	//}
133978884ef4SEddie Cai 	for(i=0; i < 2; i++) {
134078884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
134178884ef4SEddie Cai 		value /= 100;
134278884ef4SEddie Cai 	}
134378884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
134478884ef4SEddie Cai 
134578884ef4SEddie Cai 	printf("ret: %x\n",ret);
134678884ef4SEddie Cai 	return ret&0xFF;
134778884ef4SEddie Cai }
134878884ef4SEddie Cai 
str2wide(const char * str,uint16_t * wide,int len)134978884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
135078884ef4SEddie Cai {
135178884ef4SEddie Cai 	int i;
135278884ef4SEddie Cai 	for (i = 0; i < len; i++) {
135378884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
135478884ef4SEddie Cai 	}
135578884ef4SEddie Cai 	wide[len] = 0;
135678884ef4SEddie Cai }
135778884ef4SEddie Cai 
getName(char * path,uint16_t * dst)135878884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
135978884ef4SEddie Cai 	char* end;
136078884ef4SEddie Cai 	char* start;
136178884ef4SEddie Cai 	int len;
136278884ef4SEddie Cai 	if (!path || !dst)
136378884ef4SEddie Cai 		return;
136478884ef4SEddie Cai 	start = strrchr(path, '/');
136578884ef4SEddie Cai 	if (!start)
136678884ef4SEddie Cai 		start = path;
136778884ef4SEddie Cai 	else
136878884ef4SEddie Cai 		start++;
136978884ef4SEddie Cai 	end = strrchr(path, '.');
1370641cfa16SEddie Cai 	if (!end || (end < start))
137178884ef4SEddie Cai 		end = path + strlen(path);
137278884ef4SEddie Cai 	len = end - start;
137378884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
137478884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
137578884ef4SEddie Cai 	str2wide(start, dst, len);
137678884ef4SEddie Cai 
137778884ef4SEddie Cai 
137878884ef4SEddie Cai 		char name[MAX_NAME_LEN];
137978884ef4SEddie Cai 		memset(name, 0, sizeof(name));
138078884ef4SEddie Cai 		memcpy(name, start, len);
138178884ef4SEddie Cai 		printf("path: %s, name: %s\n", path, name);
138278884ef4SEddie Cai 
138378884ef4SEddie Cai }
138478884ef4SEddie Cai 
getFileSize(const char * path,uint32_t * size)138578884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
138678884ef4SEddie Cai 	struct stat st;
138778884ef4SEddie Cai 	if(stat(path, &st) < 0)
138878884ef4SEddie Cai 		return false;
138978884ef4SEddie Cai 	*size = st.st_size;
139078884ef4SEddie Cai 	printf("path: %s, size: %d\n", path, *size);
139178884ef4SEddie Cai 	return true;
139278884ef4SEddie Cai }
139378884ef4SEddie Cai 
getTime(void)139478884ef4SEddie Cai static inline rk_time getTime(void) {
139578884ef4SEddie Cai 	rk_time rkTime;
139678884ef4SEddie Cai 
139778884ef4SEddie Cai 	struct tm *tm;
139878884ef4SEddie Cai 	time_t tt = time(NULL);
139978884ef4SEddie Cai 	tm = localtime(&tt);
140078884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
140178884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
140278884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
140378884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
140478884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
140578884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
140678884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
140778884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
140878884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
140978884ef4SEddie Cai 	return rkTime;
141078884ef4SEddie Cai }
141178884ef4SEddie Cai 
writeFile(FILE * outFile,const char * path,bool fix)141278884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
141378884ef4SEddie Cai 	bool ret = false;
141478884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
141578884ef4SEddie Cai 	uint8_t* buf;
141678884ef4SEddie Cai 
141778884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
141878884ef4SEddie Cai 	if (!inFile)
141978884ef4SEddie Cai 		goto end;
142078884ef4SEddie Cai 
142178884ef4SEddie Cai 	if (!getFileSize(path, &size))
142278884ef4SEddie Cai 		goto end;
142378884ef4SEddie Cai 	if (fix) {
142478884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
142578884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
142678884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
142778884ef4SEddie Cai 		fixSize +=tmp;
142878884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
142978884ef4SEddie Cai 	} else {
143078884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
143178884ef4SEddie Cai 	}
143278884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
143378884ef4SEddie Cai 		goto end;
143478884ef4SEddie Cai 
143578884ef4SEddie Cai 	if (fix) {
143678884ef4SEddie Cai 
143778884ef4SEddie Cai 		buf = gBuf;
143878884ef4SEddie Cai 		size = fixSize;
143978884ef4SEddie Cai 		while(1) {
144078884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
144178884ef4SEddie Cai 			buf += SMALL_PACKET;
144278884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
144378884ef4SEddie Cai 				break;
144478884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
144578884ef4SEddie Cai 		}
144678884ef4SEddie Cai 	} else {
144778884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
144878884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
144978884ef4SEddie Cai 		size +=tmp;
145078884ef4SEddie Cai 		P_RC4(gBuf, size);
145178884ef4SEddie Cai 	}
145278884ef4SEddie Cai 
145378884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
145478884ef4SEddie Cai 		goto end;
145578884ef4SEddie Cai 	ret = true;
145678884ef4SEddie Cai end:
145778884ef4SEddie Cai 	if (inFile)
145878884ef4SEddie Cai 		fclose(inFile);
145978884ef4SEddie Cai 	if (!ret)
146032268622SAndreas Färber 		printf("writing entry (%s) failed\n", path);
146178884ef4SEddie Cai 	return ret;
146278884ef4SEddie Cai }
146378884ef4SEddie Cai 
saveEntry(FILE * outFile,char * path,rk_entry_type type,uint16_t delay,uint32_t * offset,char * fixName,bool fix)146478884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
146578884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
146678884ef4SEddie Cai 	uint32_t size;
146778884ef4SEddie Cai 	rk_boot_entry entry;
146878884ef4SEddie Cai 
146932268622SAndreas Färber 	printf("writing: %s\n", path);
1470641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
147178884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
147278884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
147378884ef4SEddie Cai 	entry.type = type;
147478884ef4SEddie Cai 	entry.dataOffset = *offset;
147578884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
147632268622SAndreas Färber 		printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
147778884ef4SEddie Cai 		return false;
147878884ef4SEddie Cai 	}
147978884ef4SEddie Cai 	if (fix)
148078884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
148178884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
148278884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
148332268622SAndreas Färber 	printf("alignment size: %d\n", size);
148478884ef4SEddie Cai 	entry.dataSize = size;
148578884ef4SEddie Cai 	entry.dataDelay = delay;
148678884ef4SEddie Cai 	*offset += size;
148778884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
148878884ef4SEddie Cai 	return true;
148978884ef4SEddie Cai }
149078884ef4SEddie Cai 
convertChipType(const char * chip)149178884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
149278884ef4SEddie Cai 	char buffer[5];
149378884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
14948ca2bcc6SDan Horák 	memccpy(buffer, chip, '\0', sizeof(buffer));
149578884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
149678884ef4SEddie Cai }
149778884ef4SEddie Cai 
getChipType(const char * chip)149878884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
149978884ef4SEddie Cai 	printf("chip: %s\n", chip);
150078884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
150178884ef4SEddie Cai 	if(!chip) {
150278884ef4SEddie Cai 		goto end;
150378884ef4SEddie Cai 	}
150478884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
150578884ef4SEddie Cai 		chipType = RK28_DEVICE;
150678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
150778884ef4SEddie Cai 		chipType = RK28_DEVICE;
150878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
150978884ef4SEddie Cai 		chipType = RK281X_DEVICE;
151078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
151178884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
151278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
151378884ef4SEddie Cai 		chipType = RK27_DEVICE;
151478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
151578884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
151678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
151778884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
151878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
151978884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
152078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
152178884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
152278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
152378884ef4SEddie Cai 		chipType = RK29_DEVICE;
152478884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
152578884ef4SEddie Cai 		chipType = RK292X_DEVICE;
152678884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
152778884ef4SEddie Cai 		chipType = RK30_DEVICE;
152878884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
152978884ef4SEddie Cai 		chipType = RK30B_DEVICE;
153078884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
153178884ef4SEddie Cai 		chipType = RK31_DEVICE;
153278884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
153378884ef4SEddie Cai 		chipType = RK32_DEVICE;
153478884ef4SEddie Cai 	} else {
153578884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
153678884ef4SEddie Cai 	}
153778884ef4SEddie Cai 
153878884ef4SEddie Cai end:
153978884ef4SEddie Cai 	printf("type: 0x%x\n", chipType);
154078884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
154132268622SAndreas Färber 		printf("chip type not supported!\n");
154278884ef4SEddie Cai 	}
154378884ef4SEddie Cai 	return chipType;
154478884ef4SEddie Cai }
154578884ef4SEddie Cai 
getBoothdr(rk_boot_header * hdr)154678884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
154778884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
154878884ef4SEddie Cai 	hdr->tag = TAG;
154978884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
155078884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
155178884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
155278884ef4SEddie Cai 	hdr->releaseTime = getTime();
155378884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
155478884ef4SEddie Cai 
155578884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
155678884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
155778884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
155878884ef4SEddie Cai 
155978884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
156078884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
156178884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
156278884ef4SEddie Cai 
156378884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
156478884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
156578884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
156678884ef4SEddie Cai #ifndef USE_P_RC4
156778884ef4SEddie Cai 	hdr->rc4Flag = 1;
156878884ef4SEddie Cai #endif
156978884ef4SEddie Cai }
157078884ef4SEddie Cai 
getCrc(const char * path)157178884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
157278884ef4SEddie Cai 	uint32_t size = 0;
157378884ef4SEddie Cai 	uint32_t crc = 0;
157478884ef4SEddie Cai 
157578884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
157678884ef4SEddie Cai 	getFileSize(path, &size);
157778884ef4SEddie Cai 	if (!file)
157878884ef4SEddie Cai 		goto end;
157978884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
158078884ef4SEddie Cai 		goto end;
158178884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
158278884ef4SEddie Cai 	printf("crc: 0x%08x\n", crc);
158378884ef4SEddie Cai end:
158478884ef4SEddie Cai 	if (file)
158578884ef4SEddie Cai 		fclose(file);
158678884ef4SEddie Cai 	return crc;
158778884ef4SEddie Cai }
158878884ef4SEddie Cai 
mergeBoot(void)158978884ef4SEddie Cai bool mergeBoot(void) {
159078884ef4SEddie Cai 	uint32_t dataOffset;
159178884ef4SEddie Cai 	bool ret = false;
159278884ef4SEddie Cai 	int i;
159378884ef4SEddie Cai 	FILE* outFile;
159478884ef4SEddie Cai 	uint32_t crc;
159578884ef4SEddie Cai 	rk_boot_header hdr;
159678884ef4SEddie Cai 
159778884ef4SEddie Cai 	if (!initOpts())
159878884ef4SEddie Cai 		return false;
159978884ef4SEddie Cai 	{
160078884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
160178884ef4SEddie Cai 		char version[MAX_LINE_LEN];
160278884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
160378884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
160478884ef4SEddie Cai 			subfix[0] = '\0';
160578884ef4SEddie Cai 		}
160678884ef4SEddie Cai 		strcat(gOpts.outPath, version);
160778884ef4SEddie Cai 		printf("fix opt: %s\n", gOpts.outPath);
160878884ef4SEddie Cai 	}
160978884ef4SEddie Cai 
161078884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
161178884ef4SEddie Cai 	printOpts(stdout);
161278884ef4SEddie Cai 	printf("---------------\n\n");
161378884ef4SEddie Cai 
161478884ef4SEddie Cai 
161578884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
161678884ef4SEddie Cai 	if (!outFile) {
161732268622SAndreas Färber 		printf("Opening output file (%s) failed\n", gOpts.outPath);
161878884ef4SEddie Cai 		goto end;
161978884ef4SEddie Cai 	}
162078884ef4SEddie Cai 
162178884ef4SEddie Cai 	getBoothdr(&hdr);
162232268622SAndreas Färber 	printf("Writing header...\n");
162378884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
162478884ef4SEddie Cai 
162578884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
162678884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
162778884ef4SEddie Cai 		sizeof(rk_boot_entry);
162878884ef4SEddie Cai 
162932268622SAndreas Färber 	printf("Writing code 471 entry...\n");
163078884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
163178884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
163278884ef4SEddie Cai 					&dataOffset, NULL, false))
163378884ef4SEddie Cai 			goto end;
163478884ef4SEddie Cai 	}
163532268622SAndreas Färber 	printf("Writing code 472 entry...\n");
163678884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
163778884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
163878884ef4SEddie Cai 					&dataOffset, NULL, false))
163978884ef4SEddie Cai 			goto end;
164078884ef4SEddie Cai 	}
164132268622SAndreas Färber 	printf("Writing loader entry...\n");
164278884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
164378884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
164478884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
164578884ef4SEddie Cai 			goto end;
164678884ef4SEddie Cai 	}
164778884ef4SEddie Cai 
164832268622SAndreas Färber 	printf("Writing code 471...\n");
164978884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
165078884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
165178884ef4SEddie Cai 			goto end;
165278884ef4SEddie Cai 	}
165332268622SAndreas Färber 	printf("Writing code 472...\n");
165478884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
165578884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
165678884ef4SEddie Cai 			goto end;
165778884ef4SEddie Cai 	}
165832268622SAndreas Färber 	printf("Writing loader...\n");
165978884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
166078884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
166178884ef4SEddie Cai 			goto end;
166278884ef4SEddie Cai 	}
166378884ef4SEddie Cai 	fflush(outFile);
166478884ef4SEddie Cai 
166532268622SAndreas Färber 	printf("Writing crc...\n");
166678884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
166778884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
166878884ef4SEddie Cai 		goto end;
166932268622SAndreas Färber 	printf("Done.\n");
167078884ef4SEddie Cai 	ret = true;
167178884ef4SEddie Cai end:
167278884ef4SEddie Cai 	if (outFile)
167378884ef4SEddie Cai 		fclose(outFile);
167478884ef4SEddie Cai 	return ret;
167578884ef4SEddie Cai }
167678884ef4SEddie Cai 
167778884ef4SEddie Cai /************merge code end************/
167878884ef4SEddie Cai /************unpack code***************/
167978884ef4SEddie Cai 
wide2str(const uint16_t * wide,char * str,int len)168078884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
168178884ef4SEddie Cai {
168278884ef4SEddie Cai 	int i;
168378884ef4SEddie Cai 	for (i = 0; i < len; i++) {
168478884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
168578884ef4SEddie Cai 	}
168678884ef4SEddie Cai }
168778884ef4SEddie Cai 
unpackEntry(rk_boot_entry * entry,const char * name,FILE * inFile)168878884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
168978884ef4SEddie Cai 		FILE* inFile) {
169078884ef4SEddie Cai 	bool ret = false;
169178884ef4SEddie Cai 	int size, i;
169278884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
169378884ef4SEddie Cai 	if (!outFile)
169478884ef4SEddie Cai 		goto end;
169532268622SAndreas Färber 	printf("unpacking entry (%s)\n", name);
169678884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
169778884ef4SEddie Cai 	size = entry->dataSize;
169878884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
169978884ef4SEddie Cai 		goto end;
170078884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
170178884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
170278884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
170378884ef4SEddie Cai 		if (size % SMALL_PACKET)
170478884ef4SEddie Cai 		{
170578884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
170678884ef4SEddie Cai 		}
170778884ef4SEddie Cai 	} else {
170878884ef4SEddie Cai 		P_RC4(gBuf, size);
170978884ef4SEddie Cai 	}
171078884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
171178884ef4SEddie Cai 		goto end;
171278884ef4SEddie Cai 	ret = true;
171378884ef4SEddie Cai end:
171478884ef4SEddie Cai 	if (outFile)
171578884ef4SEddie Cai 		fclose(outFile);
171678884ef4SEddie Cai 	return ret;
171778884ef4SEddie Cai }
171878884ef4SEddie Cai 
unpackBoot(char * path)171978884ef4SEddie Cai bool unpackBoot(char* path) {
172078884ef4SEddie Cai 	bool ret = false;
172178884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
172278884ef4SEddie Cai 	int entryNum, i;
172378884ef4SEddie Cai 	char name[MAX_NAME_LEN];
172478884ef4SEddie Cai 	rk_boot_entry* entrys;
172578884ef4SEddie Cai 	if (!inFile) {
172678884ef4SEddie Cai 		fprintf(stderr, "loader (%s) not found\n", path);
172778884ef4SEddie Cai 		goto end;
172878884ef4SEddie Cai 	}
172978884ef4SEddie Cai 
173078884ef4SEddie Cai 	rk_boot_header hdr;
173178884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
173232268622SAndreas Färber 		fprintf(stderr, "reading header failed\n");
173378884ef4SEddie Cai 		goto end;
173478884ef4SEddie Cai 	}
173578884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
173678884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
173778884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
173878884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
173932268622SAndreas Färber 		fprintf(stderr, "reading data failed\n");
174078884ef4SEddie Cai 		goto end;
174178884ef4SEddie Cai 	}
174278884ef4SEddie Cai 
174378884ef4SEddie Cai 	printf("entry num: %d\n", entryNum);
174478884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
174578884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
174678884ef4SEddie Cai 
174778884ef4SEddie Cai 		printf("entry: t=%d, name=%s, off=%d, size=%d\n",
174878884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
174978884ef4SEddie Cai 				entrys[i].dataSize);
175078884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
175132268622SAndreas Färber 			fprintf(stderr, "unpacking entry (%s) failed\n", name);
175278884ef4SEddie Cai 			goto end;
175378884ef4SEddie Cai 		}
175478884ef4SEddie Cai 	}
175578884ef4SEddie Cai 	printf("done\n");
175678884ef4SEddie Cai 	ret = true;
175778884ef4SEddie Cai end:
175878884ef4SEddie Cai 	if (inFile)
175978884ef4SEddie Cai 		fclose(inFile);
176078884ef4SEddie Cai 	return ret;
176178884ef4SEddie Cai }
176278884ef4SEddie Cai 
download_boot(STRUCT_RKDEVICE_DESC & dev,char * szLoader)176376af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
176476af099aSliuyi {
176576af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
176676af099aSliuyi 		return false;
176776af099aSliuyi 	CRKImage *pImage = NULL;
176876af099aSliuyi 	CRKBoot *pBoot = NULL;
176976af099aSliuyi 	bool bRet, bSuccess = false;
177076af099aSliuyi 	int iRet;
177176af099aSliuyi 
177276af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
177376af099aSliuyi 	if (!bRet){
177476af099aSliuyi 		ERROR_COLOR_ATTR;
177532268622SAndreas Färber 		printf("Opening loader failed, exiting download boot!");
177676af099aSliuyi 		NORMAL_COLOR_ATTR;
177776af099aSliuyi 		printf("\r\n");
177876af099aSliuyi 		return bSuccess;
177976af099aSliuyi 	} else {
178076af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
178176af099aSliuyi 		CRKComm *pComm = NULL;
178276af099aSliuyi 		CRKDevice *pDevice = NULL;
178376af099aSliuyi 
178476af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
178576af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
178676af099aSliuyi 		if (!bRet) {
178776af099aSliuyi 			if (pImage)
178876af099aSliuyi 				delete pImage;
178976af099aSliuyi 			ERROR_COLOR_ATTR;
179076af099aSliuyi 			printf("Creating Comm Object failed!");
179176af099aSliuyi 			NORMAL_COLOR_ATTR;
179276af099aSliuyi 			printf("\r\n");
179376af099aSliuyi 			return bSuccess;
179476af099aSliuyi 		}
179576af099aSliuyi 
179676af099aSliuyi 		pDevice = new CRKDevice(dev);
179776af099aSliuyi 		if (!pDevice) {
179876af099aSliuyi 			if (pImage)
179976af099aSliuyi 				delete pImage;
180076af099aSliuyi 			if (pComm)
180176af099aSliuyi 				delete pComm;
180276af099aSliuyi 			ERROR_COLOR_ATTR;
180376af099aSliuyi 			printf("Creating device object failed!");
180476af099aSliuyi 			NORMAL_COLOR_ATTR;
180576af099aSliuyi 			printf("\r\n");
180676af099aSliuyi 			return bSuccess;
180776af099aSliuyi 		}
180876af099aSliuyi 
180976af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
181032268622SAndreas Färber 		printf("Downloading bootloader...\r\n");
181176af099aSliuyi 		iRet = pDevice->DownloadBoot();
181276af099aSliuyi 
181376af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
181476af099aSliuyi 		CURSOR_DEL_LINE;
181576af099aSliuyi 		if (iRet == 0) {
181676af099aSliuyi 			bSuccess = true;
181732268622SAndreas Färber 			printf("Downloading bootloader succeeded.\r\n");
181876af099aSliuyi 		}
181976af099aSliuyi 		else
182032268622SAndreas Färber 			printf("Downloading bootloader failed!\r\n");
182176af099aSliuyi 
182276af099aSliuyi 		if (pImage)
182376af099aSliuyi 			delete pImage;
182476af099aSliuyi 		if(pDevice)
182576af099aSliuyi 			delete pDevice;
182676af099aSliuyi 	}
182776af099aSliuyi 	return bSuccess;
182876af099aSliuyi }
upgrade_loader(STRUCT_RKDEVICE_DESC & dev,char * szLoader)1829c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1830c30d921cSKever Yang {
1831c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1832c30d921cSKever Yang 		return false;
1833c30d921cSKever Yang 	CRKImage *pImage = NULL;
1834c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1835c30d921cSKever Yang 	CRKComm *pComm = NULL;
183646bb4c07Sliuyi 	bool bRet,bNewIDBlock=false, bSuccess = false;
1837c30d921cSKever Yang 	int iRet;
183846bb4c07Sliuyi 	unsigned int i;
1839aca206f7SPeter Robinson 	signed char index;
184046bb4c07Sliuyi 	USHORT usFlashDataSec, usFlashBootSec, usFlashHeadSec;
184146bb4c07Sliuyi 	DWORD dwLoaderSize, dwLoaderDataSize, dwLoaderHeadSize, dwDelay, dwSectorNum;
1842c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1843c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
184446bb4c07Sliuyi 	char loaderHeadName[] = "FlashHead";
1845c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1846c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
184746bb4c07Sliuyi 	PBYTE loaderHeadBuffer = NULL;
1848c30d921cSKever Yang 	PBYTE pIDBData = NULL;
184946bb4c07Sliuyi 	BYTE capability[8];
1850c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1851c30d921cSKever Yang 	if (!bRet){
1852c30d921cSKever Yang 		ERROR_COLOR_ATTR;
185332268622SAndreas Färber 		printf("Opening loader failed, exiting upgrade loader!");
1854c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1855c30d921cSKever Yang 		printf("\r\n");
1856c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1857c30d921cSKever Yang 	} else {
1858c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1859c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1860c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1861c30d921cSKever Yang 		if (!bRet) {
1862c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1863c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1864c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1865c30d921cSKever Yang 			printf("\r\n");
1866c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1867c30d921cSKever Yang 		}
1868c30d921cSKever Yang 
186932268622SAndreas Färber 		printf("Upgrading loader...\r\n");
1870c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1871c30d921cSKever Yang 		if (index == -1) {
1872c30d921cSKever Yang 			if (g_pLogObject) {
187332268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1874c30d921cSKever Yang 			}
1875c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1876c30d921cSKever Yang 		}
1877c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1878c30d921cSKever Yang 		if (!bRet) {
1879c30d921cSKever Yang 			if (g_pLogObject) {
188032268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1881c30d921cSKever Yang 			}
1882c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1883c30d921cSKever Yang 		}
1884c30d921cSKever Yang 
1885c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1886c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1887c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1888c30d921cSKever Yang 			if (g_pLogObject) {
188932268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1890c30d921cSKever Yang 			}
1891c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1892c30d921cSKever Yang 		}
1893c30d921cSKever Yang 
1894c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1895c30d921cSKever Yang 		if (index == -1) {
1896c30d921cSKever Yang 			if (g_pLogObject) {
189732268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1898c30d921cSKever Yang 			}
1899c30d921cSKever Yang 			delete []loaderCodeBuffer;
1900c30d921cSKever Yang 			return -4;
1901c30d921cSKever Yang 		}
1902c30d921cSKever Yang 
1903c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1904c30d921cSKever Yang 		if (!bRet) {
1905c30d921cSKever Yang 			if (g_pLogObject) {
190632268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1907c30d921cSKever Yang 			}
1908c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1909c30d921cSKever Yang 		}
1910c30d921cSKever Yang 
1911c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1912c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1913c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1914c30d921cSKever Yang 			if (g_pLogObject) {
191532268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1916c30d921cSKever Yang 			}
1917c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1918c30d921cSKever Yang 		}
1919c30d921cSKever Yang 
192046bb4c07Sliuyi 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderHeadName);
192146bb4c07Sliuyi 		if (index != -1) {
192246bb4c07Sliuyi 			bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderHeadSize, dwDelay);
192346bb4c07Sliuyi 			if (!bRet) {
192446bb4c07Sliuyi 				if (g_pLogObject) {
192546bb4c07Sliuyi 					g_pLogObject->Record("ERROR: %s --> Get LoaderHead Entry Size failed", __func__);
192646bb4c07Sliuyi 				}
192746bb4c07Sliuyi 				goto Exit_UpgradeLoader;
192846bb4c07Sliuyi 			}
192946bb4c07Sliuyi 
193046bb4c07Sliuyi 			loaderHeadBuffer= new BYTE[dwLoaderHeadSize];
193146bb4c07Sliuyi 			memset(loaderHeadBuffer, 0, dwLoaderHeadSize);
193246bb4c07Sliuyi 			if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderHeadBuffer)) {
193346bb4c07Sliuyi 				if (g_pLogObject) {
193446bb4c07Sliuyi 					g_pLogObject->Record("ERROR: %s --> Get LoaderHead Data failed", __func__);
193546bb4c07Sliuyi 				}
193646bb4c07Sliuyi 				goto Exit_UpgradeLoader;
193746bb4c07Sliuyi 			}
193846bb4c07Sliuyi 
193946bb4c07Sliuyi 			iRet = pComm->RKU_ReadCapability(capability);
194046bb4c07Sliuyi 			if (iRet != ERR_SUCCESS)
194146bb4c07Sliuyi 			{
194246bb4c07Sliuyi 				if (g_pLogObject)
194346bb4c07Sliuyi 					g_pLogObject->Record("ERROR: %s --> read capability failed", __func__);
194446bb4c07Sliuyi 				goto Exit_UpgradeLoader;
194546bb4c07Sliuyi 			}
194646bb4c07Sliuyi 			if ((capability[1] & 1) == 0) {
194746bb4c07Sliuyi 				if (g_pLogObject)
194846bb4c07Sliuyi 					g_pLogObject->Record("ERROR: %s --> device did not support to upgrade the loader", __func__);
194946bb4c07Sliuyi 				ERROR_COLOR_ATTR;
195046bb4c07Sliuyi 				printf("Device not support to upgrade the loader!");
195146bb4c07Sliuyi 				NORMAL_COLOR_ATTR;
195246bb4c07Sliuyi 				printf("\r\n");
195346bb4c07Sliuyi 				goto Exit_UpgradeLoader;
195446bb4c07Sliuyi 			}
195546bb4c07Sliuyi 			bNewIDBlock = true;
195646bb4c07Sliuyi 		}
195746bb4c07Sliuyi 
1958c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1959c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
196046bb4c07Sliuyi 		if (bNewIDBlock) {
196146bb4c07Sliuyi 			usFlashHeadSec = (ALIGN(dwLoaderHeadSize, 2048)) / SECTOR_SIZE;
196246bb4c07Sliuyi 			dwSectorNum = usFlashHeadSec + usFlashDataSec + usFlashBootSec;
196346bb4c07Sliuyi 		} else
1964c30d921cSKever Yang 			dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1965c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1966c30d921cSKever Yang 		if (!pIDBData) {
1967c30d921cSKever Yang 			ERROR_COLOR_ATTR;
196832268622SAndreas Färber 			printf("Allocating memory failed!");
1969c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1970c30d921cSKever Yang 			printf("\r\n");
1971c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1972c30d921cSKever Yang 		}
1973c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
197446bb4c07Sliuyi 		if (bNewIDBlock) {
197546bb4c07Sliuyi 			if (pBoot->Rc4DisableFlag)
197646bb4c07Sliuyi 			{//close rc4 encryption
197746bb4c07Sliuyi 				for (i=0;i<dwLoaderHeadSize/SECTOR_SIZE;i++)
197846bb4c07Sliuyi 				{
197946bb4c07Sliuyi 					P_RC4(loaderHeadBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
198046bb4c07Sliuyi 				}
198146bb4c07Sliuyi 				for (i=0;i<dwLoaderDataSize/SECTOR_SIZE;i++)
198246bb4c07Sliuyi 				{
198346bb4c07Sliuyi 					P_RC4(loaderDataBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
198446bb4c07Sliuyi 				}
198546bb4c07Sliuyi 				for (i=0;i<dwLoaderSize/SECTOR_SIZE;i++)
198646bb4c07Sliuyi 				{
198746bb4c07Sliuyi 					P_RC4(loaderCodeBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
198846bb4c07Sliuyi 				}
198946bb4c07Sliuyi 			}
199046bb4c07Sliuyi 			memcpy(pIDBData, loaderHeadBuffer, dwLoaderHeadSize);
199146bb4c07Sliuyi 			memcpy(pIDBData+SECTOR_SIZE*usFlashHeadSec, loaderDataBuffer, dwLoaderDataSize);
199246bb4c07Sliuyi 			memcpy(pIDBData+SECTOR_SIZE*(usFlashHeadSec+usFlashDataSec), loaderCodeBuffer, dwLoaderSize);
199346bb4c07Sliuyi 		} else {
1994b38fe5fcSliuyi 			iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
1995c30d921cSKever Yang 			if (iRet != 0) {
1996c30d921cSKever Yang 				ERROR_COLOR_ATTR;
199732268622SAndreas Färber 				printf("Making idblock failed!");
1998c30d921cSKever Yang 				NORMAL_COLOR_ATTR;
1999c30d921cSKever Yang 				printf("\r\n");
2000c30d921cSKever Yang 				goto Exit_UpgradeLoader;
2001c30d921cSKever Yang 			}
200246bb4c07Sliuyi 		}
200346bb4c07Sliuyi 
2004c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
2005c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
2006c30d921cSKever Yang 		CURSOR_DEL_LINE;
2007c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
2008b38fe5fcSliuyi 			//pComm->Reset_Usb_Device();
2009c30d921cSKever Yang 			bSuccess = true;
201032268622SAndreas Färber 			printf("Upgrading loader succeeded.\r\n");
2011c30d921cSKever Yang 		} else {
201232268622SAndreas Färber 			printf("Upgrading loader failed!\r\n");
2013c30d921cSKever Yang 			goto Exit_UpgradeLoader;
2014c30d921cSKever Yang 		}
2015c30d921cSKever Yang 	}
2016c30d921cSKever Yang Exit_UpgradeLoader:
2017c30d921cSKever Yang 	if (pImage)
2018c30d921cSKever Yang 		delete pImage;
2019c30d921cSKever Yang 	if (pComm)
2020c30d921cSKever Yang 		delete pComm;
2021c30d921cSKever Yang 	if (loaderCodeBuffer)
2022c30d921cSKever Yang 		delete []loaderCodeBuffer;
2023c30d921cSKever Yang 	if (loaderDataBuffer)
2024c30d921cSKever Yang 		delete []loaderDataBuffer;
202546bb4c07Sliuyi 	if (loaderHeadBuffer)
202646bb4c07Sliuyi 		delete []loaderHeadBuffer;
2027c30d921cSKever Yang 	if (pIDBData)
2028c30d921cSKever Yang 		delete []pIDBData;
2029c30d921cSKever Yang 	return bSuccess;
2030c30d921cSKever Yang }
print_gpt(STRUCT_RKDEVICE_DESC & dev)20313dc7e3ceSliuyi bool print_gpt(STRUCT_RKDEVICE_DESC &dev)
20323dc7e3ceSliuyi {
20333dc7e3ceSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
20343dc7e3ceSliuyi 		return false;
20353dc7e3ceSliuyi 	u8 master_gpt[34 * SECTOR_SIZE];
20363dc7e3ceSliuyi 	gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE);
20373dc7e3ceSliuyi 	bool bRet, bSuccess = false;
20383dc7e3ceSliuyi 	int iRet;
20393dc7e3ceSliuyi 	gpt_entry  *gptEntry  = NULL;
20403dc7e3ceSliuyi 	u32 i,j;
20413dc7e3ceSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
20423dc7e3ceSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
20433dc7e3ceSliuyi 	CRKComm *pComm = NULL;
20443dc7e3ceSliuyi 	char partName[36];
20453dc7e3ceSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
20463dc7e3ceSliuyi 	if (!bRet) {
20473dc7e3ceSliuyi 		ERROR_COLOR_ATTR;
20483dc7e3ceSliuyi 		printf("Creating Comm Object failed!");
20493dc7e3ceSliuyi 		NORMAL_COLOR_ATTR;
20503dc7e3ceSliuyi 		printf("\r\n");
20513dc7e3ceSliuyi 		return bSuccess;
20523dc7e3ceSliuyi 	}
20533dc7e3ceSliuyi 	iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt);
20543dc7e3ceSliuyi 	if(ERR_SUCCESS == iRet) {
20553dc7e3ceSliuyi 		if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
20563dc7e3ceSliuyi 			goto Exit_PrintGpt;
20573dc7e3ceSliuyi 		}
20583dc7e3ceSliuyi 
20593dc7e3ceSliuyi 	} else {
20603dc7e3ceSliuyi 		if (g_pLogObject)
20613dc7e3ceSliuyi 				g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
20623dc7e3ceSliuyi 		printf("Read GPT failed!\r\n");
20633dc7e3ceSliuyi 		goto Exit_PrintGpt;
20643dc7e3ceSliuyi 	}
20653dc7e3ceSliuyi 
2066081d237aSliuyi 	printf("**********Partition Info(GPT)**********\r\n");
20673dc7e3ceSliuyi 	printf("NO  LBA       Name                \r\n");
20683dc7e3ceSliuyi 	for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) {
20693dc7e3ceSliuyi 		gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
20703dc7e3ceSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
20713dc7e3ceSliuyi 			break;
20723dc7e3ceSliuyi 		memset(partName, 0 , 36);
20733dc7e3ceSliuyi 		j = 0;
20743dc7e3ceSliuyi 		while (gptEntry->partition_name[j]) {
20753dc7e3ceSliuyi 			partName[j] = (char)gptEntry->partition_name[j];
20763dc7e3ceSliuyi 			j++;
20773dc7e3ceSliuyi 		}
20783dc7e3ceSliuyi 		printf("%02d  %08X  %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName);
20793dc7e3ceSliuyi 	}
20803dc7e3ceSliuyi 	bSuccess = true;
20813dc7e3ceSliuyi Exit_PrintGpt:
20823dc7e3ceSliuyi 	if (pComm)
20833dc7e3ceSliuyi 		delete pComm;
20843dc7e3ceSliuyi 	return bSuccess;
20853dc7e3ceSliuyi }
print_parameter(STRUCT_RKDEVICE_DESC & dev)2086081d237aSliuyi bool print_parameter(STRUCT_RKDEVICE_DESC &dev)
2087081d237aSliuyi {
2088081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2089081d237aSliuyi 		return false;
2090081d237aSliuyi 	u8 param_buf[512 * SECTOR_SIZE];
2091081d237aSliuyi 	bool bRet, bSuccess = false;
2092081d237aSliuyi 	int iRet;
2093081d237aSliuyi 	u32 i, nParamSize;
2094081d237aSliuyi 	CRKComm *pComm = NULL;
2095081d237aSliuyi 	PARAM_ITEM_VECTOR vecParamItem;
2096081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuidItem;
2097081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2098081d237aSliuyi 	if (!bRet) {
2099081d237aSliuyi 		ERROR_COLOR_ATTR;
2100081d237aSliuyi 		printf("Creating Comm Object failed!");
2101081d237aSliuyi 		NORMAL_COLOR_ATTR;
2102081d237aSliuyi 		printf("\r\n");
2103081d237aSliuyi 		return bSuccess;
2104081d237aSliuyi 	}
2105081d237aSliuyi 	iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf);
2106081d237aSliuyi 	if(ERR_SUCCESS == iRet) {
2107081d237aSliuyi 		if (*(u32 *)param_buf != 0x4D524150) {
2108081d237aSliuyi 			goto Exit_PrintParam;
2109081d237aSliuyi 		}
2110081d237aSliuyi 
2111081d237aSliuyi 	} else {
2112081d237aSliuyi 		if (g_pLogObject)
2113081d237aSliuyi 				g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2114081d237aSliuyi 		printf("Read parameter failed!\r\n");
2115081d237aSliuyi 		goto Exit_PrintParam;
2116081d237aSliuyi 	}
2117081d237aSliuyi 	nParamSize = *(u32 *)(param_buf + 4);
2118081d237aSliuyi 	memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8);
2119081d237aSliuyi 
2120081d237aSliuyi 	bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem);
2121081d237aSliuyi 	if (!bRet) {
2122081d237aSliuyi 		if (g_pLogObject)
2123081d237aSliuyi 				g_pLogObject->Record("Error: parse parameter failed");
2124081d237aSliuyi 		printf("Parse parameter failed!\r\n");
2125081d237aSliuyi 		goto Exit_PrintParam;
2126081d237aSliuyi 	}
2127081d237aSliuyi 	printf("**********Partition Info(parameter)**********\r\n");
2128081d237aSliuyi 	printf("NO  LBA       Name                \r\n");
2129081d237aSliuyi 	for (i = 0; i < vecParamItem.size(); i++) {
2130081d237aSliuyi 		printf("%02d  %08X  %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName);
2131081d237aSliuyi 	}
2132081d237aSliuyi 	bSuccess = true;
2133081d237aSliuyi Exit_PrintParam:
2134081d237aSliuyi 	if (pComm)
2135081d237aSliuyi 		delete pComm;
2136081d237aSliuyi 	return bSuccess;
2137081d237aSliuyi }
2138c30d921cSKever Yang 
erase_flash(STRUCT_RKDEVICE_DESC & dev)213976af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
214076af099aSliuyi {
214176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
214276af099aSliuyi 		return false;
214376af099aSliuyi 	CRKImage *pImage = NULL;
214476af099aSliuyi 	bool bRet, bSuccess = false;
214576af099aSliuyi 	int iRet;
214676af099aSliuyi 	CRKScan *pScan = NULL;
214776af099aSliuyi 	pScan = new CRKScan();
214876af099aSliuyi 	pScan->SetVidPid();
214976af099aSliuyi 
215076af099aSliuyi 	CRKComm *pComm = NULL;
215176af099aSliuyi 	CRKDevice *pDevice = NULL;
215276af099aSliuyi 
215376af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
215476af099aSliuyi 	if (!bRet) {
215576af099aSliuyi 		if (pScan)
215676af099aSliuyi 			delete pScan;
215776af099aSliuyi 		ERROR_COLOR_ATTR;
215876af099aSliuyi 		printf("Creating Comm Object failed!");
215976af099aSliuyi 		NORMAL_COLOR_ATTR;
216076af099aSliuyi 		printf("\r\n");
216176af099aSliuyi 		return bSuccess;
216276af099aSliuyi 	}
216376af099aSliuyi 
216476af099aSliuyi 	pDevice = new CRKDevice(dev);
216576af099aSliuyi 	if (!pDevice) {
216676af099aSliuyi 		if (pComm)
216776af099aSliuyi 			delete pComm;
216876af099aSliuyi 		if (pScan)
216976af099aSliuyi 			delete pScan;
217076af099aSliuyi 		ERROR_COLOR_ATTR;
217176af099aSliuyi 		printf("Creating device object failed!");
217276af099aSliuyi 		NORMAL_COLOR_ATTR;
217376af099aSliuyi 		printf("\r\n");
217476af099aSliuyi 		return bSuccess;
217576af099aSliuyi 	}
217676af099aSliuyi 
217776af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
217876af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
217976af099aSliuyi 
218032268622SAndreas Färber 	printf("Starting to erase flash...\r\n");
21816502326dSliuyi 	bRet = pDevice->GetFlashInfo();
21826502326dSliuyi 	if (!bRet) {
21836502326dSliuyi 		if (pDevice)
21846502326dSliuyi 			delete pDevice;
21856502326dSliuyi 		if (pScan)
21866502326dSliuyi 			delete pScan;
21876502326dSliuyi 		ERROR_COLOR_ATTR;
21886502326dSliuyi 		printf("Getting flash info from device failed!");
21896502326dSliuyi 		NORMAL_COLOR_ATTR;
21906502326dSliuyi 		printf("\r\n");
21916502326dSliuyi 		return bSuccess;
21926502326dSliuyi 	}
219376af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
219476af099aSliuyi 	if (pDevice)
219576af099aSliuyi 		delete pDevice;
219676af099aSliuyi 
219776af099aSliuyi 	if (iRet == 0) {
219876af099aSliuyi 		if (pScan) {
219976af099aSliuyi 			pScan->SetVidPid();
220076af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
220176af099aSliuyi 			delete pScan;
220276af099aSliuyi 		}
220376af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
220476af099aSliuyi 		CURSOR_DEL_LINE;
220576af099aSliuyi 		bSuccess = true;
220632268622SAndreas Färber 		printf("Erasing flash complete.\r\n");
220776af099aSliuyi 	}
220876af099aSliuyi 
220976af099aSliuyi 	return bSuccess;
221076af099aSliuyi }
221176af099aSliuyi 
test_device(STRUCT_RKDEVICE_DESC & dev)221276af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
221376af099aSliuyi {
221476af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
221576af099aSliuyi 		return false;
221676af099aSliuyi 	CRKUsbComm *pComm = NULL;
221776af099aSliuyi 	bool bRet, bSuccess = false;
221876af099aSliuyi 	int iRet;
221976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
222076af099aSliuyi 	if (bRet) {
222176af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
222276af099aSliuyi 		if (iRet != ERR_SUCCESS) {
222376af099aSliuyi 			if (g_pLogObject)
222476af099aSliuyi 				g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
222532268622SAndreas Färber 			printf("Test Device failed!\r\n");
222676af099aSliuyi 		} else {
222776af099aSliuyi 			bSuccess = true;
222876af099aSliuyi 			printf("Test Device OK.\r\n");
222976af099aSliuyi 		}
223076af099aSliuyi 	} else {
223132268622SAndreas Färber 		printf("Test Device quit, creating comm object failed!\r\n");
223276af099aSliuyi 	}
223376af099aSliuyi 	if (pComm) {
223476af099aSliuyi 		delete pComm;
223576af099aSliuyi 		pComm = NULL;
223676af099aSliuyi 	}
223776af099aSliuyi 	return bSuccess;
223876af099aSliuyi }
reset_device(STRUCT_RKDEVICE_DESC & dev,BYTE subCode=RST_NONE_SUBCODE)223976af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
224076af099aSliuyi {
224176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
224276af099aSliuyi 		return false;
224376af099aSliuyi 	CRKUsbComm *pComm = NULL;
224476af099aSliuyi 	bool bRet, bSuccess = false;
224576af099aSliuyi 	int iRet;
224676af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
224776af099aSliuyi 	if (bRet) {
224876af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
224976af099aSliuyi 		if (iRet != ERR_SUCCESS) {
225076af099aSliuyi 			if (g_pLogObject)
225176af099aSliuyi 				g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
225232268622SAndreas Färber 			printf("Reset Device failed!\r\n");
225376af099aSliuyi 		} else {
225476af099aSliuyi 			bSuccess = true;
225576af099aSliuyi 			printf("Reset Device OK.\r\n");
225676af099aSliuyi 		}
225776af099aSliuyi 	} else {
225832268622SAndreas Färber 		printf("Reset Device quit, creating comm object failed!\r\n");
225976af099aSliuyi 	}
226076af099aSliuyi 	if (pComm) {
226176af099aSliuyi 		delete pComm;
226276af099aSliuyi 		pComm = NULL;
226376af099aSliuyi 	}
226476af099aSliuyi 	return bSuccess;
226576af099aSliuyi }
226676af099aSliuyi 
change_storage(STRUCT_RKDEVICE_DESC & dev,BYTE storage)2267554066a0SArnaud Mouiche bool change_storage(STRUCT_RKDEVICE_DESC &dev, BYTE storage)
2268554066a0SArnaud Mouiche {
2269554066a0SArnaud Mouiche 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2270554066a0SArnaud Mouiche 		return false;
2271554066a0SArnaud Mouiche 	CRKUsbComm *pComm = NULL;
2272554066a0SArnaud Mouiche 	bool bRet, bSuccess = false;
2273554066a0SArnaud Mouiche 	int iRet;
2274554066a0SArnaud Mouiche 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2275554066a0SArnaud Mouiche 	if (bRet) {
2276554066a0SArnaud Mouiche 		iRet = pComm->RKU_ChangeStorage(storage);
2277554066a0SArnaud Mouiche 		if (iRet != ERR_SUCCESS) {
2278554066a0SArnaud Mouiche 			if (g_pLogObject)
2279554066a0SArnaud Mouiche 				g_pLogObject->Record("Error: RKU_ChangeStorage failed, err=%d", iRet);
2280554066a0SArnaud Mouiche 			printf("Change Storage failed!\r\n");
2281554066a0SArnaud Mouiche 			goto failed;
2282554066a0SArnaud Mouiche 		}
2283554066a0SArnaud Mouiche 		/* No error is returned if the selected storage is not available.
2284554066a0SArnaud Mouiche 		 * Read back the current storage to know if the change is effective.
2285554066a0SArnaud Mouiche 		 */
2286554066a0SArnaud Mouiche 		BYTE current_storage;
2287554066a0SArnaud Mouiche 		iRet = pComm->RKU_ReadStorage(&current_storage);
2288554066a0SArnaud Mouiche 		if (iRet != ERR_SUCCESS) {
2289554066a0SArnaud Mouiche 			if (g_pLogObject)
2290554066a0SArnaud Mouiche 				g_pLogObject->Record("Error: RKU_ReadStorage failed, err=%d", iRet);
2291554066a0SArnaud Mouiche 			printf("Change Storage failed!\r\n");
2292554066a0SArnaud Mouiche 			goto failed;
2293554066a0SArnaud Mouiche 		}
2294554066a0SArnaud Mouiche 		if (storage == current_storage) {
2295554066a0SArnaud Mouiche 		    bSuccess = true;
2296554066a0SArnaud Mouiche 		    printf("Change Storage OK.\r\n");
2297554066a0SArnaud Mouiche 		} else {
2298554066a0SArnaud Mouiche 		    printf("Change Storage failed! Storage %u is not available.\r\n", storage);
2299554066a0SArnaud Mouiche 		}
2300554066a0SArnaud Mouiche 	} else {
2301554066a0SArnaud Mouiche 		printf("Change Storage quit, creating comm object failed!\r\n");
2302554066a0SArnaud Mouiche 	}
2303554066a0SArnaud Mouiche failed:
2304554066a0SArnaud Mouiche 	if (pComm) {
2305554066a0SArnaud Mouiche 		delete pComm;
2306554066a0SArnaud Mouiche 		pComm = NULL;
2307554066a0SArnaud Mouiche 	}
2308554066a0SArnaud Mouiche 	return bSuccess;
2309554066a0SArnaud Mouiche }
2310554066a0SArnaud Mouiche 
2311554066a0SArnaud Mouiche 
2312554066a0SArnaud Mouiche 
read_flash_id(STRUCT_RKDEVICE_DESC & dev)231376af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
231476af099aSliuyi {
231576af099aSliuyi 	CRKUsbComm *pComm = NULL;
231676af099aSliuyi 	bool bRet, bSuccess = false;
231776af099aSliuyi 	int iRet;
231876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
231976af099aSliuyi 		return bSuccess;
232076af099aSliuyi 
232176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
232276af099aSliuyi 	if (bRet) {
232376af099aSliuyi 		BYTE flashID[5];
232476af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
232576af099aSliuyi 		if (iRet != ERR_SUCCESS) {
232676af099aSliuyi 			if (g_pLogObject)
232776af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
232832268622SAndreas Färber 			printf("Reading flash ID failed!\r\n");
232976af099aSliuyi 		} else {
233076af099aSliuyi 			printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
233176af099aSliuyi 			bSuccess = true;
233276af099aSliuyi 		}
233376af099aSliuyi 	} else {
233432268622SAndreas Färber 		printf("Read Flash ID quit, creating comm object failed!\r\n");
233576af099aSliuyi 	}
233676af099aSliuyi 	if (pComm) {
233776af099aSliuyi 		delete pComm;
233876af099aSliuyi 		pComm = NULL;
233976af099aSliuyi 	}
234076af099aSliuyi 	return bSuccess;
234176af099aSliuyi }
read_flash_info(STRUCT_RKDEVICE_DESC & dev)234276af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
234376af099aSliuyi {
234476af099aSliuyi 	CRKUsbComm *pComm = NULL;
234576af099aSliuyi 	bool bRet, bSuccess = false;
234676af099aSliuyi 	int iRet;
234776af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
234876af099aSliuyi 		return bSuccess;
234976af099aSliuyi 
235076af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
235176af099aSliuyi 	if (bRet) {
235276af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
235376af099aSliuyi 		UINT uiRead;
235476af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
235576af099aSliuyi 		if (iRet != ERR_SUCCESS) {
235676af099aSliuyi 			if (g_pLogObject)
235776af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
235832268622SAndreas Färber 			printf("Read Flash Info failed!\r\n");
235976af099aSliuyi 		} else {
236076af099aSliuyi 			printf("Flash Info:\r\n");
236176af099aSliuyi 			if (info.bManufCode <= 7) {
236276af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
236376af099aSliuyi 			}
236476af099aSliuyi 			else
236576af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
236676af099aSliuyi 
236776af099aSliuyi 			printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
23680dcb0a4cSliuyi 			printf("\tFlash Size: %d Sectors\r\n", info.uiFlashSize);
236976af099aSliuyi 			printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
237076af099aSliuyi 			printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
237176af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
237276af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
237376af099aSliuyi 			printf("\tFlash CS: ");
237476af099aSliuyi 			for(int i = 0; i < 8; i++) {
237576af099aSliuyi 				if( info.bFlashCS & (1 << i) )
237676af099aSliuyi 					printf("Flash<%d> ", i);
237776af099aSliuyi 			}
237876af099aSliuyi 			printf("\r\n");
237976af099aSliuyi 			bSuccess = true;
238076af099aSliuyi 		}
238176af099aSliuyi 	}else {
238232268622SAndreas Färber 		printf("Read Flash Info quit, creating comm object failed!\r\n");
238376af099aSliuyi 	}
238476af099aSliuyi 	if (pComm) {
238576af099aSliuyi 		delete pComm;
238676af099aSliuyi 		pComm = NULL;
238776af099aSliuyi 	}
238876af099aSliuyi 	return bSuccess;
238976af099aSliuyi }
read_chip_info(STRUCT_RKDEVICE_DESC & dev)239076af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
239176af099aSliuyi {
239276af099aSliuyi 	CRKUsbComm *pComm = NULL;
239376af099aSliuyi 	bool bRet, bSuccess = false;
239476af099aSliuyi 	int iRet;
239576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
239676af099aSliuyi 		return bSuccess;
239776af099aSliuyi 
239876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
239976af099aSliuyi 	if (bRet) {
240076af099aSliuyi 		BYTE chipInfo[16];
240176af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
240276af099aSliuyi 		if (iRet != ERR_SUCCESS) {
240376af099aSliuyi 			if (g_pLogObject)
240476af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
240532268622SAndreas Färber 			printf("Read Chip Info failed!\r\n");
240676af099aSliuyi 		} else {
240776af099aSliuyi 			string strChipInfo;
240876af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
240976af099aSliuyi 			printf("Chip Info: %s\r\n", strChipInfo.c_str());
241076af099aSliuyi 			bSuccess = true;
241176af099aSliuyi 		}
241276af099aSliuyi 	} else {
241332268622SAndreas Färber 		printf("Read Chip Info quit, creating comm object failed!\r\n");
241476af099aSliuyi 	}
241576af099aSliuyi 	if (pComm) {
241676af099aSliuyi 		delete pComm;
241776af099aSliuyi 		pComm = NULL;
241876af099aSliuyi 	}
241976af099aSliuyi 	return bSuccess;
242076af099aSliuyi }
read_capability(STRUCT_RKDEVICE_DESC & dev)2421081d237aSliuyi bool read_capability(STRUCT_RKDEVICE_DESC &dev)
2422081d237aSliuyi {
2423081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2424081d237aSliuyi 	bool bRet, bSuccess = false;
2425081d237aSliuyi 	int iRet;
2426081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2427081d237aSliuyi 		return bSuccess;
2428081d237aSliuyi 
2429081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2430081d237aSliuyi 	if (bRet) {
2431081d237aSliuyi 
2432081d237aSliuyi 		BYTE capability[8];
2433081d237aSliuyi 		iRet = pComm->RKU_ReadCapability(capability);
2434081d237aSliuyi 		if (iRet != ERR_SUCCESS)
2435081d237aSliuyi 		{
2436081d237aSliuyi 			if (g_pLogObject)
2437081d237aSliuyi 				g_pLogObject->Record("Error:read_capability failed,err=%d", iRet);
2438081d237aSliuyi 			printf("Read capability Fail!\r\n");
2439081d237aSliuyi 		} else {
2440081d237aSliuyi 			printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n",
2441081d237aSliuyi 			capability[0], capability[1], capability[2], capability[3],
2442081d237aSliuyi 			capability[4], capability[5], capability[6], capability[7]);
2443081d237aSliuyi 			if (capability[0] & 1)
2444081d237aSliuyi 			{
2445081d237aSliuyi 				printf("Direct LBA:\tenabled\r\n");
2446081d237aSliuyi 			}
2447081d237aSliuyi 
2448081d237aSliuyi 			if (capability[0] & 2)
2449081d237aSliuyi 			{
2450081d237aSliuyi 				printf("Vendor Storage:\tenabled\r\n");
2451081d237aSliuyi 			}
2452081d237aSliuyi 
2453081d237aSliuyi 			if (capability[0] & 4)
2454081d237aSliuyi 			{
2455081d237aSliuyi 				printf("First 4m Access:\tenabled\r\n");
2456081d237aSliuyi 			}
245746bb4c07Sliuyi 			if (capability[0] & 8)
245846bb4c07Sliuyi 			{
245946bb4c07Sliuyi 				printf("Read LBA:\tenabled\r\n");
246046bb4c07Sliuyi 			}
246146bb4c07Sliuyi 
246246bb4c07Sliuyi 			if (capability[0] & 20)
246346bb4c07Sliuyi 			{
246446bb4c07Sliuyi 				printf("Read Com Log:\tenabled\r\n");
246546bb4c07Sliuyi 			}
246646bb4c07Sliuyi 
246746bb4c07Sliuyi 			if (capability[0] & 40)
246846bb4c07Sliuyi 			{
246946bb4c07Sliuyi 				printf("Read IDB Config:\tenabled\r\n");
247046bb4c07Sliuyi 			}
247146bb4c07Sliuyi 
247246bb4c07Sliuyi 			if (capability[0] & 80)
247346bb4c07Sliuyi 			{
247446bb4c07Sliuyi 				printf("Read Secure Mode:\tenabled\r\n");
247546bb4c07Sliuyi 			}
247646bb4c07Sliuyi 
247746bb4c07Sliuyi 			if (capability[1] & 1)
247846bb4c07Sliuyi 			{
247946bb4c07Sliuyi 				printf("New IDB:\tenabled\r\n");
248046bb4c07Sliuyi 			}
2481081d237aSliuyi 			bSuccess = true;
2482081d237aSliuyi 		}
2483081d237aSliuyi 	} else {
2484081d237aSliuyi 		printf("Read capability quit, creating comm object failed!\r\n");
2485081d237aSliuyi 	}
2486081d237aSliuyi 	if (pComm) {
2487081d237aSliuyi 		delete pComm;
2488081d237aSliuyi 		pComm = NULL;
2489081d237aSliuyi 	}
2490081d237aSliuyi 	return bSuccess;
2491081d237aSliuyi }
read_param(STRUCT_RKDEVICE_DESC & dev,u8 * pParam)2492081d237aSliuyi bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam)
2493081d237aSliuyi {
2494081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2495081d237aSliuyi 		return false;
2496081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2497081d237aSliuyi 	bool bRet, bSuccess = false;
2498081d237aSliuyi 	int iRet;
2499081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2500081d237aSliuyi 	if (bRet) {
2501081d237aSliuyi 		iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam);
2502081d237aSliuyi 		if(ERR_SUCCESS == iRet) {
2503081d237aSliuyi 			if (*(u32 *)pParam != 0x4D524150) {
2504081d237aSliuyi 				goto Exit_ReadParam;
2505081d237aSliuyi 			}
2506081d237aSliuyi 		} else {
2507081d237aSliuyi 			if (g_pLogObject)
2508081d237aSliuyi 					g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2509081d237aSliuyi 			printf("Read parameter failed!\r\n");
2510081d237aSliuyi 			goto Exit_ReadParam;
2511081d237aSliuyi 		}
2512081d237aSliuyi 		bSuccess = true;
2513081d237aSliuyi 	}
2514081d237aSliuyi Exit_ReadParam:
2515081d237aSliuyi 	if (pComm) {
2516081d237aSliuyi 		delete pComm;
2517081d237aSliuyi 		pComm = NULL;
2518081d237aSliuyi 	}
2519081d237aSliuyi 	return bSuccess;
2520081d237aSliuyi }
2521081d237aSliuyi 
2522081d237aSliuyi 
read_gpt(STRUCT_RKDEVICE_DESC & dev,u8 * pGpt)25236ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt)
25246ae612beSliuyi {
25256ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
25266ae612beSliuyi 		return false;
25276ae612beSliuyi 	gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE);
25286ae612beSliuyi 	CRKUsbComm *pComm = NULL;
25296ae612beSliuyi 	bool bRet, bSuccess = false;
25306ae612beSliuyi 	int iRet;
25316ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
25326ae612beSliuyi 	if (bRet) {
25336ae612beSliuyi 		iRet = pComm->RKU_ReadLBA( 0, 34, pGpt);
25346ae612beSliuyi 		if(ERR_SUCCESS == iRet) {
25356ae612beSliuyi 			if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
25366ae612beSliuyi 				goto Exit_ReadGPT;
25376ae612beSliuyi 			}
25386ae612beSliuyi 		} else {
25396ae612beSliuyi 			if (g_pLogObject)
25406ae612beSliuyi 					g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
25416ae612beSliuyi 			printf("Read GPT failed!\r\n");
25426ae612beSliuyi 			goto Exit_ReadGPT;
25436ae612beSliuyi 		}
25446ae612beSliuyi 		bSuccess = true;
25456ae612beSliuyi 	}
25466ae612beSliuyi Exit_ReadGPT:
25476ae612beSliuyi 	if (pComm) {
25486ae612beSliuyi 		delete pComm;
25496ae612beSliuyi 		pComm = NULL;
25506ae612beSliuyi 	}
25516ae612beSliuyi 	return bSuccess;
25526ae612beSliuyi }
read_lba(STRUCT_RKDEVICE_DESC & dev,UINT uiBegin,UINT uiLen,char * szFile)255376af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
255476af099aSliuyi {
255576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
255676af099aSliuyi 		return false;
255776af099aSliuyi 	CRKUsbComm *pComm = NULL;
255876af099aSliuyi 	FILE *file = NULL;
255976af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
256076af099aSliuyi 	int iRet;
256176af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
256276af099aSliuyi 	int nSectorSize = 512;
256376af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
256476af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
256576af099aSliuyi 	if (bRet) {
256676af099aSliuyi 		if(szFile) {
256776af099aSliuyi 			file = fopen(szFile, "wb+");
256876af099aSliuyi 			if( !file ) {
256976af099aSliuyi 				printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
257076af099aSliuyi 				goto Exit_ReadLBA;
257176af099aSliuyi 			}
257276af099aSliuyi 		}
257376af099aSliuyi 
257476af099aSliuyi 		while(uiLen > 0) {
257576af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
257676af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
257776af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
257876af099aSliuyi 			if(ERR_SUCCESS == iRet) {
257976af099aSliuyi 				uiLen -= iRead;
258076af099aSliuyi 				iTotalRead += iRead;
258176af099aSliuyi 
258276af099aSliuyi 				if(szFile) {
258376af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
258476af099aSliuyi 					if (bFirst){
258576af099aSliuyi 						if (iTotalRead >= 1024)
258632268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
258776af099aSliuyi 						else
258832268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
258976af099aSliuyi 						bFirst = false;
259076af099aSliuyi 					} else {
259176af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
259276af099aSliuyi 						CURSOR_DEL_LINE;
259376af099aSliuyi 						if (iTotalRead >= 1024)
259432268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
259576af099aSliuyi 						else
259632268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
259776af099aSliuyi 					}
259876af099aSliuyi 				}
259976af099aSliuyi 				else
260076af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
260176af099aSliuyi 			} else {
260276af099aSliuyi 				if (g_pLogObject)
260376af099aSliuyi 					g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
260476af099aSliuyi 
260576af099aSliuyi 				printf("Read LBA failed!\r\n");
260676af099aSliuyi 				goto Exit_ReadLBA;
260776af099aSliuyi 			}
260876af099aSliuyi 		}
260976af099aSliuyi 		bSuccess = true;
261076af099aSliuyi 	} else {
261132268622SAndreas Färber 		printf("Read LBA quit, creating comm object failed!\r\n");
261276af099aSliuyi 	}
261376af099aSliuyi Exit_ReadLBA:
261476af099aSliuyi 	if (pComm) {
261576af099aSliuyi 		delete pComm;
261676af099aSliuyi 		pComm = NULL;
261776af099aSliuyi 	}
261876af099aSliuyi 	if (file)
261976af099aSliuyi 		fclose(file);
262076af099aSliuyi 	return bSuccess;
262176af099aSliuyi }
erase_ubi_block(STRUCT_RKDEVICE_DESC & dev,u32 uiOffset,u32 uiPartSize)26220dcb0a4cSliuyi bool erase_ubi_block(STRUCT_RKDEVICE_DESC &dev, u32 uiOffset, u32 uiPartSize)
26230dcb0a4cSliuyi {
26240dcb0a4cSliuyi 	STRUCT_FLASHINFO_CMD info;
26250dcb0a4cSliuyi 	CRKComm *pComm = NULL;
26260dcb0a4cSliuyi 	BYTE flashID[5];
26270dcb0a4cSliuyi 	bool bRet,bSuccess=false;
26280dcb0a4cSliuyi 	UINT uiReadCount,uiStartBlock,uiEraseBlock,uiBlockCount,uiErasePos;
26290dcb0a4cSliuyi 	int iRet;
26300dcb0a4cSliuyi 	DWORD *pID=NULL;
26311e890c4fSliuyi 
2632e541b7bbSliuyi 	printf("Erase ubi in, offset=0x%08x,size=0x%08x!\r\n",uiOffset,uiPartSize);
26330dcb0a4cSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
26340dcb0a4cSliuyi 		return false;
26350dcb0a4cSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
26360dcb0a4cSliuyi 	if (!bRet)
26370dcb0a4cSliuyi 	{
26380dcb0a4cSliuyi 		printf("Erase ubi quit, creating comm object failed!\r\n");
26390dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
26400dcb0a4cSliuyi 	}
26410dcb0a4cSliuyi 	iRet = pComm->RKU_ReadFlashID(flashID);
26420dcb0a4cSliuyi 	if(iRet!=ERR_SUCCESS)
26430dcb0a4cSliuyi 	{
26440dcb0a4cSliuyi 		if (g_pLogObject)
26450dcb0a4cSliuyi 		{
26460dcb0a4cSliuyi 			g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashID failed,RetCode(%d)",iRet);
26470dcb0a4cSliuyi 		}
26480dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
26490dcb0a4cSliuyi 	}
26500dcb0a4cSliuyi 	pID = (DWORD *)flashID;
26511e890c4fSliuyi 
26520dcb0a4cSliuyi 	if (*pID==0x434d4d45)//emmc
26530dcb0a4cSliuyi 	{
26540dcb0a4cSliuyi 		bSuccess = true;
26550dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
26560dcb0a4cSliuyi 	}
26570dcb0a4cSliuyi 
26580dcb0a4cSliuyi 	iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info,&uiReadCount);
26590dcb0a4cSliuyi 	if (iRet!=ERR_SUCCESS)
26600dcb0a4cSliuyi 	{
26610dcb0a4cSliuyi 		if (g_pLogObject)
26620dcb0a4cSliuyi 			g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashInfo err=%d", iRet);
26630dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
26640dcb0a4cSliuyi 	}
26650dcb0a4cSliuyi 	if (uiPartSize==0xFFFFFFFF)
2666e607a5d6Sliuyi 		uiPartSize = info.uiFlashSize - uiOffset;
26670dcb0a4cSliuyi 
26680dcb0a4cSliuyi 	uiStartBlock = uiOffset / info.usBlockSize;
2669e607a5d6Sliuyi 	uiEraseBlock = (uiPartSize + info.usBlockSize -1) / info.usBlockSize;
2670e607a5d6Sliuyi 
26710dcb0a4cSliuyi 
2672e541b7bbSliuyi 	printf("Erase block start, offset=0x%08x,count=0x%08x!\r\n",uiStartBlock,uiEraseBlock);
26730dcb0a4cSliuyi 	uiErasePos=uiStartBlock;
26740dcb0a4cSliuyi 	while (uiEraseBlock>0)
26750dcb0a4cSliuyi 	{
26760dcb0a4cSliuyi 		uiBlockCount = (uiEraseBlock<MAX_ERASE_BLOCKS)?uiEraseBlock:MAX_ERASE_BLOCKS;
26770dcb0a4cSliuyi 
26780dcb0a4cSliuyi 		iRet = pComm->RKU_EraseBlock(0,uiErasePos,uiBlockCount,ERASE_FORCE);
26790dcb0a4cSliuyi 		if ((iRet!=ERR_SUCCESS)&&(iRet!=ERR_FOUND_BAD_BLOCK))
26800dcb0a4cSliuyi 		{
26810dcb0a4cSliuyi 			if (g_pLogObject)
26820dcb0a4cSliuyi 			{
26830dcb0a4cSliuyi 				g_pLogObject->Record("Error:EraseUBIBlock-->RKU_EraseBlock failed,RetCode(%d)",iRet);
26840dcb0a4cSliuyi 			}
26850dcb0a4cSliuyi 			goto EXIT_UBI_ERASE;
26860dcb0a4cSliuyi 		}
26870dcb0a4cSliuyi 
26880dcb0a4cSliuyi 		uiErasePos += uiBlockCount;
26890dcb0a4cSliuyi 		uiEraseBlock -= uiBlockCount;
26900dcb0a4cSliuyi 	}
26910dcb0a4cSliuyi 	bSuccess = true;
26920dcb0a4cSliuyi EXIT_UBI_ERASE:
26930dcb0a4cSliuyi 	if (pComm)
26940dcb0a4cSliuyi 		delete pComm;
26950dcb0a4cSliuyi 	return bSuccess;
26960dcb0a4cSliuyi }
erase_partition(CRKUsbComm * pComm,UINT uiOffset,UINT uiSize)26976ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize)
26986ae612beSliuyi {
2699ae4252f0Sliuyi 	UINT uiErase=1024*32;
27006ae612beSliuyi 	bool bSuccess = true;
27016ae612beSliuyi 	int iRet;
27026ae612beSliuyi 	while (uiSize)
27036ae612beSliuyi 	{
27046ae612beSliuyi 		if (uiSize>=uiErase)
27056ae612beSliuyi 		{
27066ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiErase);
27076ae612beSliuyi 			uiSize -= uiErase;
27086ae612beSliuyi 			uiOffset += uiErase;
27096ae612beSliuyi 		}
27106ae612beSliuyi 		else
27116ae612beSliuyi 		{
27126ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiSize);
27136ae612beSliuyi 			uiSize = 0;
27146ae612beSliuyi 			uiOffset += uiSize;
27156ae612beSliuyi 		}
27166ae612beSliuyi 		if (iRet!=ERR_SUCCESS)
27176ae612beSliuyi 		{
27186ae612beSliuyi 			if (g_pLogObject)
27196ae612beSliuyi 			{
27206ae612beSliuyi 				g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet);
27216ae612beSliuyi 			}
27226ae612beSliuyi 			bSuccess = false;
27236ae612beSliuyi 			break;
27246ae612beSliuyi 		}
27256ae612beSliuyi 	}
27266ae612beSliuyi 	return bSuccess;
27276ae612beSliuyi 
27286ae612beSliuyi }
EatSparseChunk(FILE * file,chunk_header & chunk)27296ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk)
27306ae612beSliuyi {
27316ae612beSliuyi 	UINT uiRead;
27326ae612beSliuyi 	uiRead = fread(&chunk, 1, sizeof(chunk_header), file);
27336ae612beSliuyi 	if (uiRead != sizeof(chunk_header)) {
27346ae612beSliuyi 		if (g_pLogObject)
27356ae612beSliuyi 		{
27366ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno);
27376ae612beSliuyi 		}
27386ae612beSliuyi 		return false;
27396ae612beSliuyi 	}
27406ae612beSliuyi 	return true;
27416ae612beSliuyi }
EatSparseData(FILE * file,PBYTE pBuf,DWORD dwSize)27426ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize)
27436ae612beSliuyi {
27446ae612beSliuyi 	UINT uiRead;
27456ae612beSliuyi 	uiRead = fread(pBuf, 1, dwSize, file);
27466ae612beSliuyi 	if (uiRead!=dwSize)
27476ae612beSliuyi 	{
27486ae612beSliuyi 		if (g_pLogObject)
27496ae612beSliuyi 		{
27506ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno);
27516ae612beSliuyi 		}
27526ae612beSliuyi 		return false;
27536ae612beSliuyi 	}
27546ae612beSliuyi 	return true;
27556ae612beSliuyi }
27566ae612beSliuyi 
write_sparse_lba(STRUCT_RKDEVICE_DESC & dev,UINT uiBegin,UINT uiSize,char * szFile)27576ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile)
27586ae612beSliuyi {
27596ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
27606ae612beSliuyi 		return false;
27616ae612beSliuyi 	CRKUsbComm *pComm = NULL;
27626ae612beSliuyi 	FILE *file = NULL;
27636ae612beSliuyi 	bool bRet, bSuccess = false, bFirst = true;
27646ae612beSliuyi 	int iRet;
2765e541b7bbSliuyi 	u64 iTotalWrite = 0, iFileSize = 0,dwChunkDataSize;
27666ae612beSliuyi 	UINT iRead = 0, uiTransferSec, curChunk, i;
2767e541b7bbSliuyi 	UINT dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc;
27686ae612beSliuyi 	BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA];
27696ae612beSliuyi 	sparse_header header;
27706ae612beSliuyi 	chunk_header  chunk;
27716ae612beSliuyi 	dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE;
27726ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
27736ae612beSliuyi 	if (bRet) {
2774ae4252f0Sliuyi 
27756ae612beSliuyi 		file = fopen(szFile, "rb");
27766ae612beSliuyi 		if( !file ) {
27776ae612beSliuyi 			printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile);
27786ae612beSliuyi 			goto Exit_WriteSparseLBA;
27796ae612beSliuyi 		}
27806ae612beSliuyi 		fseeko(file, 0, SEEK_SET);
27816ae612beSliuyi 		iRead = fread(&header, 1, sizeof(header), file);
27826ae612beSliuyi 		if (iRead != sizeof(sparse_header))
27836ae612beSliuyi 		{
27846ae612beSliuyi 			if (g_pLogObject)
27856ae612beSliuyi 			{
27866ae612beSliuyi 				g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno);
27876ae612beSliuyi 			}
27886ae612beSliuyi 			goto Exit_WriteSparseLBA;
27896ae612beSliuyi 		}
27906ae612beSliuyi 		iFileSize = header.blk_sz * (u64)header.total_blks;
27916ae612beSliuyi 		iTotalWrite = 0;
27926ae612beSliuyi 		curChunk = 0;
2793ae4252f0Sliuyi 		if (uiSize==(u32)-1)
2794ae4252f0Sliuyi 			uiSize = ALIGN(iFileSize, SECTOR_SIZE);
2795ae4252f0Sliuyi 		bRet = erase_partition(pComm, uiBegin, uiSize);
2796ae4252f0Sliuyi 		if (!bRet) {
2797ae4252f0Sliuyi 			printf("%s failed, erase partition error\r\n", __func__);
2798ae4252f0Sliuyi 			goto Exit_WriteSparseLBA;
2799ae4252f0Sliuyi 		}
28006ae612beSliuyi 		while(curChunk < header.total_chunks)
28016ae612beSliuyi 		{
28026ae612beSliuyi 			if (!EatSparseChunk(file, chunk)) {
28036ae612beSliuyi 				goto Exit_WriteSparseLBA;
28046ae612beSliuyi 			}
28056ae612beSliuyi 			curChunk++;
28066ae612beSliuyi 			switch (chunk.chunk_type) {
28076ae612beSliuyi 			case CHUNK_TYPE_RAW:
28086ae612beSliuyi 				dwChunkDataSize = chunk.total_sz - sizeof(chunk_header);
28096ae612beSliuyi 				while (dwChunkDataSize) {
28106ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
28116ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
28126ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
28136ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
28146ae612beSliuyi 					} else {
28156ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
28166ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
28176ae612beSliuyi 					}
28186ae612beSliuyi 					if (!EatSparseData(file, pBuf, dwTransferBytes)) {
28196ae612beSliuyi 						goto Exit_WriteSparseLBA;
28206ae612beSliuyi 					}
28216ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
28226ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
28236ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
28246ae612beSliuyi 						iTotalWrite += dwTransferBytes;
28256ae612beSliuyi 						uiBegin += uiTransferSec;
28266ae612beSliuyi 					} else {
28276ae612beSliuyi 						if (g_pLogObject) {
28286ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)",  __func__, iTotalWrite, iRet);
28296ae612beSliuyi 						}
28306ae612beSliuyi 						goto Exit_WriteSparseLBA;
28316ae612beSliuyi 					}
28326ae612beSliuyi 					if (bFirst) {
28336ae612beSliuyi 						if (iTotalWrite >= 1024)
28346ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28356ae612beSliuyi 						else
28366ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
28376ae612beSliuyi 						bFirst = false;
28386ae612beSliuyi 					} else {
28396ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
28406ae612beSliuyi 						CURSOR_DEL_LINE;
28416ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28426ae612beSliuyi 					}
28436ae612beSliuyi 				}
28446ae612beSliuyi 				break;
28456ae612beSliuyi 			case CHUNK_TYPE_FILL:
2846e541b7bbSliuyi 				dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz;
28476ae612beSliuyi 				if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) {
28486ae612beSliuyi 					goto Exit_WriteSparseLBA;
28496ae612beSliuyi 				}
28506ae612beSliuyi 				while (dwChunkDataSize) {
28516ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
28526ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
28536ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
28546ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
28556ae612beSliuyi 					} else {
28566ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
28576ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
28586ae612beSliuyi 					}
28596ae612beSliuyi 					for (i = 0; i < dwTransferBytes / 4; i++) {
28606ae612beSliuyi 						*(DWORD *)(pBuf + i * 4) = dwFillByte;
28616ae612beSliuyi 					}
28626ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
28636ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
28646ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
28656ae612beSliuyi 						iTotalWrite += dwTransferBytes;
28666ae612beSliuyi 						uiBegin += uiTransferSec;
28676ae612beSliuyi 					} else {
28686ae612beSliuyi 						if (g_pLogObject) {
28696ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet);
28706ae612beSliuyi 						}
28716ae612beSliuyi 						goto Exit_WriteSparseLBA;
28726ae612beSliuyi 					}
28736ae612beSliuyi 					if (bFirst) {
28746ae612beSliuyi 						if (iTotalWrite >= 1024)
28756ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28766ae612beSliuyi 						else
28776ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
28786ae612beSliuyi 						bFirst = false;
28796ae612beSliuyi 					} else {
28806ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
28816ae612beSliuyi 						CURSOR_DEL_LINE;
28826ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28836ae612beSliuyi 					}
28846ae612beSliuyi 				}
28856ae612beSliuyi 				break;
28866ae612beSliuyi 			case CHUNK_TYPE_DONT_CARE:
2887e541b7bbSliuyi 				dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz;
28886ae612beSliuyi 				iTotalWrite += dwChunkDataSize;
28896ae612beSliuyi 				uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1));
28906ae612beSliuyi 				uiBegin += uiTransferSec;
28916ae612beSliuyi 				if (bFirst) {
28926ae612beSliuyi 					if (iTotalWrite >= 1024)
28936ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28946ae612beSliuyi 					else
28956ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
28966ae612beSliuyi 					bFirst = false;
28976ae612beSliuyi 				} else {
28986ae612beSliuyi 					CURSOR_MOVEUP_LINE(1);
28996ae612beSliuyi 					CURSOR_DEL_LINE;
29006ae612beSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
29016ae612beSliuyi 				}
29026ae612beSliuyi 				break;
29036ae612beSliuyi 			case CHUNK_TYPE_CRC32:
29046ae612beSliuyi 				EatSparseData(file,(PBYTE)&dwCrc,4);
29056ae612beSliuyi 				break;
29066ae612beSliuyi 			}
29076ae612beSliuyi 		}
29086ae612beSliuyi 		bSuccess = true;
29096ae612beSliuyi 	} else {
29106ae612beSliuyi 		printf("Write LBA quit, creating comm object failed!\r\n");
29116ae612beSliuyi 	}
29126ae612beSliuyi Exit_WriteSparseLBA:
29136ae612beSliuyi 	if (pComm) {
29146ae612beSliuyi 		delete pComm;
29156ae612beSliuyi 		pComm = NULL;
29166ae612beSliuyi 	}
29176ae612beSliuyi 	if (file)
29186ae612beSliuyi 		fclose(file);
29196ae612beSliuyi 	return bSuccess;
29206ae612beSliuyi 
29216ae612beSliuyi }
29226ae612beSliuyi 
write_lba(STRUCT_RKDEVICE_DESC & dev,UINT uiBegin,char * szFile)292376af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
292476af099aSliuyi {
292576af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
292676af099aSliuyi 		return false;
292776af099aSliuyi 	CRKUsbComm *pComm = NULL;
292876af099aSliuyi 	FILE *file = NULL;
292976af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
293076af099aSliuyi 	int iRet;
293176af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
293276af099aSliuyi 	UINT iWrite = 0, iRead = 0;
293376af099aSliuyi 	UINT uiLen;
293476af099aSliuyi 	int nSectorSize = 512;
293576af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
293676af099aSliuyi 
29370dcb0a4cSliuyi 
293876af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
293976af099aSliuyi 	if (bRet) {
294076af099aSliuyi 		file = fopen(szFile, "rb");
294176af099aSliuyi 		if( !file ) {
294276af099aSliuyi 			printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
294376af099aSliuyi 			goto Exit_WriteLBA;
294476af099aSliuyi 		}
294576af099aSliuyi 
294676af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
294776af099aSliuyi 		iFileSize = ftello(file);
294876af099aSliuyi 		fseeko(file, 0, SEEK_SET);
294976af099aSliuyi 		while(iTotalWrite < iFileSize) {
295076af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
295176af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
295276af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
295376af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
295476af099aSliuyi 			if(ERR_SUCCESS == iRet) {
295576af099aSliuyi 				uiBegin += uiLen;
295676af099aSliuyi 				iTotalWrite += iWrite;
295776af099aSliuyi 				if (bFirst) {
295876af099aSliuyi 					if (iTotalWrite >= 1024)
295976af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
296076af099aSliuyi 					else
296132268622SAndreas Färber 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
296276af099aSliuyi 					bFirst = false;
296376af099aSliuyi 				} else {
296476af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
296576af099aSliuyi 					CURSOR_DEL_LINE;
296676af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
296776af099aSliuyi 				}
296876af099aSliuyi 			} else {
296976af099aSliuyi 				if (g_pLogObject)
297076af099aSliuyi 					g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
297176af099aSliuyi 
297276af099aSliuyi 				printf("Write LBA failed!\r\n");
297376af099aSliuyi 				goto Exit_WriteLBA;
297476af099aSliuyi 			}
297576af099aSliuyi 		}
297676af099aSliuyi 		bSuccess = true;
297776af099aSliuyi 	} else {
297832268622SAndreas Färber 		printf("Write LBA quit, creating comm object failed!\r\n");
297976af099aSliuyi 	}
298076af099aSliuyi Exit_WriteLBA:
298176af099aSliuyi 	if (pComm) {
298276af099aSliuyi 		delete pComm;
298376af099aSliuyi 		pComm = NULL;
298476af099aSliuyi 	}
298576af099aSliuyi 	if (file)
298676af099aSliuyi 		fclose(file);
298776af099aSliuyi 	return bSuccess;
298876af099aSliuyi }
298976af099aSliuyi 
split_item(STRING_VECTOR & vecItems,char * pszItems)299076af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
299176af099aSliuyi {
299276af099aSliuyi 	string strItem;
299376af099aSliuyi 	char szItem[100];
299476af099aSliuyi 	char *pos = NULL, *pStart;
299576af099aSliuyi 	pStart = pszItems;
299676af099aSliuyi 	pos = strchr(pStart, ',');
299776af099aSliuyi 	while(pos != NULL) {
299802bc7763SChristoph Muellner 		memset(szItem, 0, sizeof(szItem));
299976af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
300076af099aSliuyi 		strItem = szItem;
300176af099aSliuyi 		vecItems.push_back(strItem);
300276af099aSliuyi 		pStart = pos + 1;
300376af099aSliuyi 		if (*pStart == 0)
300476af099aSliuyi 			break;
300576af099aSliuyi 		pos = strchr(pStart, ',');
300676af099aSliuyi 	}
300776af099aSliuyi 	if (strlen(pStart) > 0) {
300802bc7763SChristoph Muellner 		memset(szItem, 0, sizeof(szItem));
300902bc7763SChristoph Muellner 		strncpy(szItem, pStart, sizeof(szItem)-1);
301076af099aSliuyi 		strItem = szItem;
301176af099aSliuyi 		vecItems.push_back(strItem);
301276af099aSliuyi 	}
301376af099aSliuyi }
3014c30d921cSKever Yang 
tag_spl(char * tag,char * spl)3015d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
3016d71e8c20SEddie Cai {
3017d71e8c20SEddie Cai 	FILE *file = NULL;
3018d71e8c20SEddie Cai 	int len;
3019d71e8c20SEddie Cai 
3020d71e8c20SEddie Cai 	if(!tag || !spl)
3021d71e8c20SEddie Cai 		return;
3022d71e8c20SEddie Cai 	len = strlen(tag);
3023d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
3024d71e8c20SEddie Cai 	file = fopen(spl, "rb");
3025d71e8c20SEddie Cai 	if( !file ){
3026d71e8c20SEddie Cai 		return;
3027d71e8c20SEddie Cai 	}
3028d71e8c20SEddie Cai 	int iFileSize;
3029d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
3030d71e8c20SEddie Cai 	iFileSize = ftell(file);
3031d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
3032d71e8c20SEddie Cai 	char *Buf = NULL;
3033d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
3034d71e8c20SEddie Cai 	if (!Buf){
3035d71e8c20SEddie Cai 		fclose(file);
3036d71e8c20SEddie Cai 		return;
3037d71e8c20SEddie Cai 	}
3038d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
3039d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
3040d71e8c20SEddie Cai 	int iRead;
3041d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
3042d71e8c20SEddie Cai 	if (iRead != iFileSize){
3043d71e8c20SEddie Cai 		fclose(file);
3044d71e8c20SEddie Cai 		delete []Buf;
3045d71e8c20SEddie Cai 		return;
3046d71e8c20SEddie Cai 	}
3047d71e8c20SEddie Cai 	fclose(file);
3048d71e8c20SEddie Cai 
3049d71e8c20SEddie Cai 	len = strlen(spl);
305032268622SAndreas Färber 	char *taggedspl = new char[len + 5];
305132268622SAndreas Färber 	strcpy(taggedspl, spl);
305232268622SAndreas Färber 	strcpy(taggedspl + len, ".tag");
305332268622SAndreas Färber 	taggedspl[len+4] = 0;
305432268622SAndreas Färber 	printf("Writing tagged spl to %s\n", taggedspl);
3055d71e8c20SEddie Cai 
305632268622SAndreas Färber 	file = fopen(taggedspl, "wb");
3057d71e8c20SEddie Cai 	if( !file ){
305832268622SAndreas Färber 		delete []taggedspl;
3059d71e8c20SEddie Cai 		delete []Buf;
3060d71e8c20SEddie Cai 		return;
3061d71e8c20SEddie Cai 	}
3062d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
3063d71e8c20SEddie Cai 	fclose(file);
306432268622SAndreas Färber 	delete []taggedspl;
3065d71e8c20SEddie Cai 	delete []Buf;
3066d71e8c20SEddie Cai 	printf("done\n");
3067d71e8c20SEddie Cai 	return;
3068d71e8c20SEddie Cai }
list_device(CRKScan * pScan)3069081d237aSliuyi void list_device(CRKScan *pScan)
3070081d237aSliuyi {
3071081d237aSliuyi 	STRUCT_RKDEVICE_DESC desc;
3072081d237aSliuyi 	string strDevType;
3073081d237aSliuyi 	int i,cnt;
3074081d237aSliuyi 	cnt = pScan->DEVICE_COUNTS;
3075081d237aSliuyi 	if (cnt == 0) {
3076081d237aSliuyi 		printf("not found any devices!\r\n");
3077081d237aSliuyi 		return;
3078081d237aSliuyi 	}
3079081d237aSliuyi 	for (i=0;i<cnt;i++)
3080081d237aSliuyi 	{
3081081d237aSliuyi 		pScan->GetDevice(desc, i);
3082081d237aSliuyi 		if (desc.emUsbType==RKUSB_MASKROM)
3083081d237aSliuyi 			strDevType = "Maskrom";
3084081d237aSliuyi 		else if (desc.emUsbType==RKUSB_LOADER)
3085081d237aSliuyi 			strDevType = "Loader";
3086081d237aSliuyi 		else
3087081d237aSliuyi 			strDevType = "Unknown";
3088081d237aSliuyi 		printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid,
3089081d237aSliuyi 		       desc.usPid,desc.uiLocationID,strDevType.c_str());
3090081d237aSliuyi 	}
3091081d237aSliuyi 
3092081d237aSliuyi }
3093081d237aSliuyi 
3094d71e8c20SEddie Cai 
handle_command(int argc,char * argv[],CRKScan * pScan)309576af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
309676af099aSliuyi {
309776af099aSliuyi 	string strCmd;
309876af099aSliuyi 	strCmd = argv[1];
309976af099aSliuyi 	ssize_t cnt;
310076af099aSliuyi 	bool bRet,bSuccess = false;
31018df2d64aSEddie Cai 	char *s;
31028df2d64aSEddie Cai 	int i, ret;
310376af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
3104081d237aSliuyi 	u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE];
31056ae612beSliuyi 	u64 lba, lba_end;
3106081d237aSliuyi 	u32 part_size, part_offset;
310776af099aSliuyi 
310876af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
31098df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
31108df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
31118df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
311278884ef4SEddie Cai 
31138df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
311476af099aSliuyi 		usage();
311576af099aSliuyi 		return true;
31168df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
3117c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
311876af099aSliuyi 		return true;
311978884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
312078884ef4SEddie Cai 		mergeBoot();
312178884ef4SEddie Cai 		return true;
312278884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
312378884ef4SEddie Cai 		string strLoader = argv[2];
312478884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
312578884ef4SEddie Cai 		return true;
3126d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
3127d71e8c20SEddie Cai 		if (argc == 4) {
3128d71e8c20SEddie Cai 			string tag = argv[2];
3129d71e8c20SEddie Cai 			string spl = argv[3];
3130d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
3131d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
3132d71e8c20SEddie Cai 			return true;
3133d71e8c20SEddie Cai 		}
3134d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
3135d71e8c20SEddie Cai 		usage();
313676af099aSliuyi 	}
313776af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
3138081d237aSliuyi 	if(strcmp(strCmd.c_str(), "LD") == 0) {
3139081d237aSliuyi 		list_device(pScan);
31400dcb0a4cSliuyi 		return (cnt>0)?true:false;
3141081d237aSliuyi 	}
3142081d237aSliuyi 
314376af099aSliuyi 	if (cnt < 1) {
314476af099aSliuyi 		ERROR_COLOR_ATTR;
314532268622SAndreas Färber 		printf("Did not find any rockusb device, please plug device in!");
314676af099aSliuyi 		NORMAL_COLOR_ATTR;
314776af099aSliuyi 		printf("\r\n");
314876af099aSliuyi 		return bSuccess;
314976af099aSliuyi 	} else if (cnt > 1) {
315076af099aSliuyi 		ERROR_COLOR_ATTR;
315132268622SAndreas Färber 		printf("Found too many rockusb devices, please plug devices out!");
315276af099aSliuyi 		NORMAL_COLOR_ATTR;
315376af099aSliuyi 		printf("\r\n");
315476af099aSliuyi 		return bSuccess;
315576af099aSliuyi 	}
315676af099aSliuyi 
315776af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
315876af099aSliuyi 	if (!bRet) {
315976af099aSliuyi 		ERROR_COLOR_ATTR;
316032268622SAndreas Färber 		printf("Getting information about rockusb device failed!");
316176af099aSliuyi 		NORMAL_COLOR_ATTR;
316276af099aSliuyi 		printf("\r\n");
316376af099aSliuyi 		return bSuccess;
316476af099aSliuyi 	}
316576af099aSliuyi 
316676af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
316776af099aSliuyi 		if ((argc != 2) && (argc != 3))
316876af099aSliuyi 			printf("Parameter of [RD] command is invalid, please check help!\r\n");
316976af099aSliuyi 		else {
317076af099aSliuyi 			if (argc == 2)
317176af099aSliuyi 				bSuccess = reset_device(dev);
317276af099aSliuyi 			else {
317376af099aSliuyi 				UINT uiSubCode;
317476af099aSliuyi 				char *pszEnd;
317576af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
317676af099aSliuyi 				if (*pszEnd)
317776af099aSliuyi 					printf("Subcode is invalid, please check!\r\n");
317876af099aSliuyi 				else {
317976af099aSliuyi 					if (uiSubCode <= 5)
318076af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
318176af099aSliuyi 					else
318276af099aSliuyi 						printf("Subcode is invalid, please check!\r\n");
318376af099aSliuyi 				}
318476af099aSliuyi 			}
318576af099aSliuyi 		}
3186554066a0SArnaud Mouiche 	} else if(strcmp(strCmd.c_str(), "CS") == 0) {
3187554066a0SArnaud Mouiche 		if (argc != 3)
3188554066a0SArnaud Mouiche 			printf("Parameter of [CS] command is invalid, please check help!\r\n");
3189554066a0SArnaud Mouiche 		else {
3190554066a0SArnaud Mouiche 			UINT uiSubCode;
3191554066a0SArnaud Mouiche 			char *pszEnd;
3192554066a0SArnaud Mouiche 			uiSubCode = strtoul(argv[2], &pszEnd, 0);
3193554066a0SArnaud Mouiche 			if (*pszEnd)
3194554066a0SArnaud Mouiche 				printf("Storage is invalid, please check!\r\n");
3195554066a0SArnaud Mouiche 			else {
3196554066a0SArnaud Mouiche 				bSuccess = change_storage(dev, uiSubCode);
3197554066a0SArnaud Mouiche 			}
3198554066a0SArnaud Mouiche 		}
319976af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
320076af099aSliuyi 		bSuccess = test_device(dev);
320176af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
320276af099aSliuyi 		bSuccess = read_flash_id(dev);
320376af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
320476af099aSliuyi 		bSuccess = read_flash_info(dev);
320576af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
320676af099aSliuyi 		bSuccess = read_chip_info(dev);
3207081d237aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability
3208081d237aSliuyi 		bSuccess = read_capability(dev);
320976af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
321076af099aSliuyi 		if (argc > 2) {
321176af099aSliuyi 			string strLoader;
321276af099aSliuyi 			strLoader = argv[2];
321376af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
321476af099aSliuyi 		} else if (argc == 2) {
3215c29e5f0fSliuyi 			ret = find_config_item(g_ConfigItemVec, "loader");
321676af099aSliuyi 			if (ret == -1)
321732268622SAndreas Färber 				printf("Did not find loader item in config!\r\n");
321876af099aSliuyi 			else
321976af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
322076af099aSliuyi 		} else
322176af099aSliuyi 			printf("Parameter of [DB] command is invalid, please check help!\r\n");
3222c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
3223c30d921cSKever Yang 		if (argc > 2) {
3224c30d921cSKever Yang 			string strParameter;
3225c30d921cSKever Yang 			strParameter = argv[2];
3226c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
3227c30d921cSKever Yang 		} else
3228c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid, please check help!\r\n");
3229081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PRM") == 0) {
3230081d237aSliuyi 		if (argc > 2) {
3231081d237aSliuyi 			string strParameter;
3232081d237aSliuyi 			strParameter = argv[2];
3233081d237aSliuyi 			bSuccess = write_parameter(dev, (char *)strParameter.c_str());
3234081d237aSliuyi 		} else
3235081d237aSliuyi 			printf("Parameter of [PRM] command is invalid, please check help!\r\n");
3236c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
3237c30d921cSKever Yang 		if (argc > 2) {
3238c30d921cSKever Yang 			string strLoader;
3239c30d921cSKever Yang 			strLoader = argv[2];
3240c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
3241c30d921cSKever Yang 		} else
3242c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid, please check help!\r\n");
324376af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
324476af099aSliuyi 		if (argc == 2) {
324576af099aSliuyi 			bSuccess = erase_flash(dev);
324676af099aSliuyi 		} else
324776af099aSliuyi 			printf("Parameter of [EF] command is invalid, please check help!\r\n");
324876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
324976af099aSliuyi 		if (argc == 4) {
325076af099aSliuyi 			UINT uiBegin;
325176af099aSliuyi 			char *pszEnd;
325276af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
325376af099aSliuyi 			if (*pszEnd)
325476af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
3255ae4252f0Sliuyi 			else {
3256ae4252f0Sliuyi 				if (is_sparse_image(argv[3]))
3257ae4252f0Sliuyi 						bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]);
32580dcb0a4cSliuyi 				else {
32590dcb0a4cSliuyi 					bSuccess = true;
32600dcb0a4cSliuyi 					if (is_ubifs_image(argv[3]))
32610dcb0a4cSliuyi 						bSuccess = erase_ubi_block(dev, (u32)uiBegin, (u32)-1);
32620dcb0a4cSliuyi 					if (bSuccess)
3263ae4252f0Sliuyi 						bSuccess = write_lba(dev, (u32)uiBegin, argv[3]);
32640dcb0a4cSliuyi 					else
32650dcb0a4cSliuyi 						printf("Failure of Erase for writing ubi image!\r\n");
32660dcb0a4cSliuyi 				}
3267ae4252f0Sliuyi 			}
326876af099aSliuyi 		} else
326976af099aSliuyi 			printf("Parameter of [WL] command is invalid, please check help!\r\n");
32706ae612beSliuyi 	} else if(strcmp(strCmd.c_str(), "WLX") == 0) {
32716ae612beSliuyi 		if (argc == 4) {
32726ae612beSliuyi 			bRet = read_gpt(dev, master_gpt);
32736ae612beSliuyi 			if (bRet) {
32746ae612beSliuyi 				bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end);
32756ae612beSliuyi 				if (bRet) {
32766ae612beSliuyi 					if (is_sparse_image(argv[3]))
32776ae612beSliuyi 						bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]);
32780dcb0a4cSliuyi 					else {
32790dcb0a4cSliuyi 						bSuccess = true;
32800dcb0a4cSliuyi 						if (is_ubifs_image(argv[3]))
3281e607a5d6Sliuyi 						{
3282e607a5d6Sliuyi 							if (lba_end == 0xFFFFFFFF)
3283e607a5d6Sliuyi 								bSuccess = erase_ubi_block(dev, (u32)lba, (u32)lba_end);
3284e607a5d6Sliuyi 							else
32850dcb0a4cSliuyi 								bSuccess = erase_ubi_block(dev, (u32)lba, (u32)(lba_end - lba + 1));
3286e607a5d6Sliuyi 						}
32870dcb0a4cSliuyi 						if (bSuccess)
32886ae612beSliuyi 							bSuccess = write_lba(dev, (u32)lba, argv[3]);
32890dcb0a4cSliuyi 						else
32900dcb0a4cSliuyi 							printf("Failure of Erase for writing ubi image!\r\n");
32910dcb0a4cSliuyi 					}
32926ae612beSliuyi 				} else
32936ae612beSliuyi 					printf("No found %s partition\r\n", argv[2]);
3294081d237aSliuyi 			} else {
3295081d237aSliuyi 				bRet = read_param(dev, param_buffer);
3296081d237aSliuyi 				if (bRet) {
3297081d237aSliuyi 					bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size);
3298081d237aSliuyi 					if (bRet) {
3299081d237aSliuyi 						if (is_sparse_image(argv[3]))
3300081d237aSliuyi 							bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]);
33010dcb0a4cSliuyi 						else {
33021e890c4fSliuyi 
33030dcb0a4cSliuyi 							bSuccess = true;
33040dcb0a4cSliuyi 							if (is_ubifs_image(argv[3]))
33050dcb0a4cSliuyi 								bSuccess = erase_ubi_block(dev, part_offset, part_size);
33060dcb0a4cSliuyi 							if (bSuccess)
3307081d237aSliuyi 								bSuccess = write_lba(dev, part_offset, argv[3]);
33080dcb0a4cSliuyi 							else
33090dcb0a4cSliuyi 								printf("Failure of Erase for writing ubi image!\r\n");
33100dcb0a4cSliuyi 						}
3311081d237aSliuyi 					} else
3312081d237aSliuyi 						printf("No found %s partition\r\n", argv[2]);
33136ae612beSliuyi 				}
3314081d237aSliuyi 				else
3315081d237aSliuyi 					printf("Not found any partition table!\r\n");
3316081d237aSliuyi 			}
3317081d237aSliuyi 
33186ae612beSliuyi 		} else
33196ae612beSliuyi 			printf("Parameter of [WLX] command is invalid, please check help!\r\n");
332076af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
332176af099aSliuyi 		char *pszEnd;
332276af099aSliuyi 		UINT uiBegin, uiLen;
332376af099aSliuyi 		if (argc != 5)
332476af099aSliuyi 			printf("Parameter of [RL] command is invalid, please check help!\r\n");
332576af099aSliuyi 		else {
332676af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
332776af099aSliuyi 			if (*pszEnd)
332876af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
332976af099aSliuyi 			else {
333076af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
333176af099aSliuyi 				if (*pszEnd)
333276af099aSliuyi 					printf("Len is invalid, please check!\r\n");
333376af099aSliuyi 				else {
333476af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
333576af099aSliuyi 				}
333676af099aSliuyi 			}
333776af099aSliuyi 		}
3338081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PPT") == 0) {
33393dc7e3ceSliuyi 		if (argc == 2) {
33403dc7e3ceSliuyi 			bSuccess = print_gpt(dev);
3341081d237aSliuyi 			if (!bSuccess) {
3342081d237aSliuyi 				bSuccess = print_parameter(dev);
3343081d237aSliuyi 				if (!bSuccess)
3344081d237aSliuyi 					printf("Not found any partition table!\r\n");
3345081d237aSliuyi 			}
33463dc7e3ceSliuyi 		} else
3347081d237aSliuyi 			printf("Parameter of [PPT] command is invalid, please check help!\r\n");
334876af099aSliuyi 	} else {
33499bc231bdSAndreas Färber 		printf("command is invalid!\r\n");
33509bc231bdSAndreas Färber 		usage();
335176af099aSliuyi 	}
335276af099aSliuyi 	return bSuccess;
335376af099aSliuyi }
335476af099aSliuyi 
335576af099aSliuyi 
main(int argc,char * argv[])335676af099aSliuyi int main(int argc, char* argv[])
335776af099aSliuyi {
335876af099aSliuyi 	CRKScan *pScan = NULL;
335976af099aSliuyi 	int ret;
336076af099aSliuyi 	char szProgramProcPath[100];
336176af099aSliuyi 	char szProgramDir[256];
336276af099aSliuyi 	string strLogDir,strConfigFile;
336376af099aSliuyi 	struct stat statBuf;
336476af099aSliuyi 
336576af099aSliuyi 	g_ConfigItemVec.clear();
3366*054028e7Sshineseth-rk 
336721b25fd4SDave Murphy #ifndef __MINGW32__
33681831c99cSQuang Dang 	snprintf(szProgramProcPath, sizeof(szProgramProcPath), "/proc/%d/exe", getpid());
336976af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
337076af099aSliuyi 		strcpy(szProgramDir, ".");
337121b25fd4SDave Murphy 	else
337221b25fd4SDave Murphy #else
337321b25fd4SDave Murphy 	strcpy(szProgramDir, ".");
337421b25fd4SDave Murphy #endif
337521b25fd4SDave Murphy 	{
337676af099aSliuyi 		char *pSlash;
337776af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
337876af099aSliuyi 		if (pSlash)
337976af099aSliuyi 			*pSlash = '\0';
338076af099aSliuyi 	}
338121b25fd4SDave Murphy 
338276af099aSliuyi 	strLogDir = szProgramDir;
338376af099aSliuyi 	strLogDir +=  "/log/";
338476af099aSliuyi 	strConfigFile = szProgramDir;
338576af099aSliuyi 	strConfigFile += "/config.ini";
338676af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
338721b25fd4SDave Murphy #ifndef __MINGW32__
338876af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
338921b25fd4SDave Murphy #else
339021b25fd4SDave Murphy 		mkdir(strLogDir.c_str());
339121b25fd4SDave Murphy #endif
3392e5ee8cc0Sliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
339376af099aSliuyi 
339476af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
339576af099aSliuyi 		if (g_pLogObject) {
339676af099aSliuyi 			g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
339776af099aSliuyi 		}
339876af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
339976af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
340076af099aSliuyi 	}
340176af099aSliuyi 
340276af099aSliuyi 	ret = libusb_init(NULL);
340376af099aSliuyi 	if (ret < 0) {
340476af099aSliuyi 		if (g_pLogObject) {
340576af099aSliuyi 			g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
340676af099aSliuyi 			delete g_pLogObject;
340776af099aSliuyi 		}
340876af099aSliuyi 		return -1;
340976af099aSliuyi 	}
341076af099aSliuyi 
341176af099aSliuyi 	pScan = new CRKScan();
341276af099aSliuyi 	if (!pScan) {
341376af099aSliuyi 		if (g_pLogObject) {
341432268622SAndreas Färber 			g_pLogObject->Record("Error: failed to create object for searching device");
341576af099aSliuyi 			delete g_pLogObject;
341676af099aSliuyi 		}
341776af099aSliuyi 		libusb_exit(NULL);
341876af099aSliuyi 		return -2;
341976af099aSliuyi 	}
342076af099aSliuyi 	pScan->SetVidPid();
342176af099aSliuyi 
342276af099aSliuyi 	if (argc == 1)
342376af099aSliuyi 		usage();
342476af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
342576af099aSliuyi 			return -0xFF;
342676af099aSliuyi 	if (pScan)
342776af099aSliuyi 		delete pScan;
342876af099aSliuyi 	if (g_pLogObject)
342976af099aSliuyi 		delete g_pLogObject;
343076af099aSliuyi 	libusb_exit(NULL);
343176af099aSliuyi 	return 0;
343276af099aSliuyi }
3433