xref: /rkdeveloptool/main.cpp (revision e541b7bbffd008d113ab9732da7c176129670721)
176af099aSliuyi /*
276af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
376af099aSliuyi  * Seth Liu 2017.03.01
476af099aSliuyi  *
576af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
676af099aSliuyi  */
776af099aSliuyi 
876af099aSliuyi #include   <unistd.h>
976af099aSliuyi #include   <dirent.h>
10c30d921cSKever Yang #include "config.h"
1176af099aSliuyi #include "DefineHeader.h"
12c30d921cSKever Yang #include "gpt.h"
1376af099aSliuyi #include "RKLog.h"
1476af099aSliuyi #include "RKScan.h"
1576af099aSliuyi #include "RKComm.h"
1676af099aSliuyi #include "RKDevice.h"
1776af099aSliuyi #include "RKImage.h"
1876af099aSliuyi extern const char *szManufName[];
1976af099aSliuyi CRKLog *g_pLogObject=NULL;
2076af099aSliuyi CONFIG_ITEM_VECTOR g_ConfigItemVec;
2176af099aSliuyi #define DEFAULT_RW_LBA 128
2276af099aSliuyi #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n)
2376af099aSliuyi #define CURSOR_DEL_LINE printf("%c[2K", 0x1B)
2476af099aSliuyi #define CURSOR_MOVE_HOME printf("%c[H", 0x1B)
2576af099aSliuyi #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B)
2676af099aSliuyi #define ERROR_COLOR_ATTR  printf("%c[30;41m", 0x1B);
273601cc08SAndreas Färber #define NORMAL_COLOR_ATTR  printf("%c[0m", 0x1B);
28c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize);
29c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize);
30c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len);
31c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len);
32c30d921cSKever Yang /*
33c30d921cSKever Yang u8 test_gpt_head[] = {
34c30d921cSKever Yang 	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00,
35c30d921cSKever Yang 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36c30d921cSKever Yang 	0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37c30d921cSKever Yang 	0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B,
38c30d921cSKever Yang 	0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39c30d921cSKever Yang 	0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08};
40c30d921cSKever Yang */
41c30d921cSKever Yang 
4276af099aSliuyi void usage()
4376af099aSliuyi {
4476af099aSliuyi 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
45ae4252f0Sliuyi 	printf("Help:\t\t\t-h or --help\r\n");
46154ee062SEddie Cai 	printf("Version:\t\t-v or --version\r\n");
47081d237aSliuyi 	printf("ListDevice:\t\tld\r\n");
48154ee062SEddie Cai 	printf("DownloadBoot:\t\tdb <Loader>\r\n");
49154ee062SEddie Cai 	printf("UpgradeLoader:\t\tul <Loader>\r\n");
50154ee062SEddie Cai 	printf("ReadLBA:\t\trl  <BeginSec> <SectorLen> <File>\r\n");
51154ee062SEddie Cai 	printf("WriteLBA:\t\twl  <BeginSec> <File>\r\n");
526ae612beSliuyi 	printf("WriteLBA:\t\twlx  <PartitionName> <File>\r\n");
53154ee062SEddie Cai 	printf("WriteGPT:\t\tgpt <gpt partition table>\r\n");
54081d237aSliuyi 	printf("WriteParameter:\t\tprm <parameter>\r\n");
55081d237aSliuyi 	printf("PrintPartition:\t\tppt \r\n");
56154ee062SEddie Cai 	printf("EraseFlash:\t\tef \r\n");
57154ee062SEddie Cai 	printf("TestDevice:\t\ttd\r\n");
58154ee062SEddie Cai 	printf("ResetDevice:\t\trd [subcode]\r\n");
59154ee062SEddie Cai 	printf("ReadFlashID:\t\trid\r\n");
60154ee062SEddie Cai 	printf("ReadFlashInfo:\t\trfi\r\n");
61154ee062SEddie Cai 	printf("ReadChipInfo:\t\trci\r\n");
62081d237aSliuyi 	printf("ReadCapability:\t\trcb\r\n");
6378884ef4SEddie Cai 	printf("PackBootLoader:\t\tpack\r\n");
6478884ef4SEddie Cai 	printf("UnpackBootLoader:\tunpack <boot loader>\r\n");
65d71e8c20SEddie Cai 	printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n");
6676af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
6776af099aSliuyi }
6876af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6976af099aSliuyi {
7076af099aSliuyi 	string strInfoText="";
7176af099aSliuyi 	char szText[256];
7276af099aSliuyi 	switch (promptID) {
7376af099aSliuyi 	case TESTDEVICE_PROGRESS:
7432268622SAndreas Färber 		sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue);
7576af099aSliuyi 		strInfoText = szText;
7676af099aSliuyi 		break;
7776af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7832268622SAndreas Färber 		sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue);
7976af099aSliuyi 		strInfoText = szText;
8076af099aSliuyi 		break;
8176af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
8232268622SAndreas Färber 		sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8376af099aSliuyi 		strInfoText = szText;
8476af099aSliuyi 		break;
8576af099aSliuyi 	case CHECKIMAGE_PROGRESS:
8632268622SAndreas Färber 		sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024);
8776af099aSliuyi 		strInfoText = szText;
8876af099aSliuyi 		break;
8976af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
9032268622SAndreas Färber 		sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue);
9176af099aSliuyi 		strInfoText = szText;
9276af099aSliuyi 		break;
9376af099aSliuyi 	case TESTBLOCK_PROGRESS:
9432268622SAndreas Färber 		sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue);
9576af099aSliuyi 		strInfoText = szText;
9676af099aSliuyi 		break;
9776af099aSliuyi 	case ERASEFLASH_PROGRESS:
9832268622SAndreas Färber 		sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue);
9976af099aSliuyi 		strInfoText = szText;
10076af099aSliuyi 		break;
10176af099aSliuyi 	case ERASESYSTEM_PROGRESS:
10232268622SAndreas Färber 		sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue);
10376af099aSliuyi 		strInfoText = szText;
10476af099aSliuyi 		break;
10576af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
10632268622SAndreas Färber 		sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue);
10776af099aSliuyi 		strInfoText = szText;
10876af099aSliuyi 		break;
10976af099aSliuyi 	}
11076af099aSliuyi 	if (strInfoText.size() > 0){
11176af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
11276af099aSliuyi 		CURSOR_DEL_LINE;
11376af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
11476af099aSliuyi 	}
11576af099aSliuyi 	if (emCall == CALL_LAST)
11676af099aSliuyi 		deviceLayer = 0;
11776af099aSliuyi }
11876af099aSliuyi 
11976af099aSliuyi char *strupr(char *szSrc)
12076af099aSliuyi {
12176af099aSliuyi 	char *p = szSrc;
12276af099aSliuyi 	while(*p){
12376af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
12476af099aSliuyi 			*p = *p - 'a' + 'A';
12576af099aSliuyi 		p++;
12676af099aSliuyi 	}
12776af099aSliuyi 	return szSrc;
12876af099aSliuyi }
12976af099aSliuyi void PrintData(PBYTE pData, int nSize)
13076af099aSliuyi {
13176af099aSliuyi 	char szPrint[17] = "\0";
13276af099aSliuyi 	int i;
13376af099aSliuyi 	for( i = 0; i < nSize; i++){
13476af099aSliuyi 		if(i % 16 == 0){
13576af099aSliuyi 			if(i / 16 > 0)
13676af099aSliuyi 				printf("     %s\r\n", szPrint);
13776af099aSliuyi 			printf("%08d ", i / 16);
13876af099aSliuyi 		}
13976af099aSliuyi 		printf("%02X ", pData[i]);
14076af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
14176af099aSliuyi 	}
14276af099aSliuyi 	if(i / 16 > 0)
14376af099aSliuyi 		printf("     %s\r\n", szPrint);
14476af099aSliuyi }
14576af099aSliuyi 
1460dcb0a4cSliuyi //	bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
1470dcb0a4cSliuyi //	{
1480dcb0a4cSliuyi //		if (!pszSrc)
1490dcb0a4cSliuyi //			return false;
1500dcb0a4cSliuyi //		int nSrcLen = strlen(pszSrc);
1510dcb0a4cSliuyi //		int nDestLen = nSrcLen * 2;
1520dcb0a4cSliuyi //
1530dcb0a4cSliuyi //		pszDest = NULL;
1540dcb0a4cSliuyi //		pszDest = new wchar_t[nDestLen];
1550dcb0a4cSliuyi //		if (!pszDest)
1560dcb0a4cSliuyi //			return false;
1570dcb0a4cSliuyi //		nDestLen = nDestLen * sizeof(wchar_t);
1580dcb0a4cSliuyi //		memset(pszDest, 0, nDestLen);
1590dcb0a4cSliuyi //		int iRet;
1600dcb0a4cSliuyi //		iconv_t cd;
1610dcb0a4cSliuyi //		cd = iconv_open("UTF-32", "UTF-8");
1620dcb0a4cSliuyi //		if((iconv_t)-1 == cd) {
1630dcb0a4cSliuyi //			delete []pszDest;
1640dcb0a4cSliuyi //			pszDest = NULL;
1650dcb0a4cSliuyi //		      return false;
1660dcb0a4cSliuyi //		 }
1670dcb0a4cSliuyi //		char *pIn, *pOut;
1680dcb0a4cSliuyi //		pIn = (char *)pszSrc;
1690dcb0a4cSliuyi //		pOut = (char *)pszDest;
1700dcb0a4cSliuyi //
1710dcb0a4cSliuyi //		iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
1720dcb0a4cSliuyi //
1730dcb0a4cSliuyi //		if(iRet == -1) {
1740dcb0a4cSliuyi //			delete []pszDest;
1750dcb0a4cSliuyi //			pszDest = NULL;
1760dcb0a4cSliuyi //			iconv_close(cd);
1770dcb0a4cSliuyi //			return false;
1780dcb0a4cSliuyi //		 }
1790dcb0a4cSliuyi //
1800dcb0a4cSliuyi //		 iconv_close(cd);
1810dcb0a4cSliuyi //
1820dcb0a4cSliuyi //		 return true;
1830dcb0a4cSliuyi //	}
1840dcb0a4cSliuyi //	bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
1850dcb0a4cSliuyi //	{
1860dcb0a4cSliuyi //		if (!pszSrc)
1870dcb0a4cSliuyi //			return false;
1880dcb0a4cSliuyi //		int nSrcLen = wcslen(pszSrc);
1890dcb0a4cSliuyi //		int nDestLen = nSrcLen * 2;
1900dcb0a4cSliuyi //		nSrcLen = nSrcLen * sizeof(wchar_t);
1910dcb0a4cSliuyi //		pszDest = NULL;
1920dcb0a4cSliuyi //		pszDest = new char[nDestLen];
1930dcb0a4cSliuyi //		if (!pszDest)
1940dcb0a4cSliuyi //			return false;
1950dcb0a4cSliuyi //		memset(pszDest, 0, nDestLen);
1960dcb0a4cSliuyi //		int iRet;
1970dcb0a4cSliuyi //		iconv_t cd;
1980dcb0a4cSliuyi //		cd = iconv_open("UTF-8", "UTF-32");
1990dcb0a4cSliuyi //
2000dcb0a4cSliuyi //		if((iconv_t)-1 == cd) {
2010dcb0a4cSliuyi //			delete []pszDest;
2020dcb0a4cSliuyi //			pszDest = NULL;
2030dcb0a4cSliuyi //		      return false;
2040dcb0a4cSliuyi //		 }
2050dcb0a4cSliuyi //		char *pIn, *pOut;
2060dcb0a4cSliuyi //		pIn = (char *)pszSrc;
2070dcb0a4cSliuyi //		pOut = (char *)pszDest;
2080dcb0a4cSliuyi //		iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
2090dcb0a4cSliuyi //
2100dcb0a4cSliuyi //		if(iRet == -1) {
2110dcb0a4cSliuyi //			delete []pszDest;
2120dcb0a4cSliuyi //			pszDest = NULL;
2130dcb0a4cSliuyi //			iconv_close(cd);
2140dcb0a4cSliuyi //			return false;
2150dcb0a4cSliuyi //		 }
2160dcb0a4cSliuyi //
2170dcb0a4cSliuyi //		 iconv_close(cd);
2180dcb0a4cSliuyi //
2190dcb0a4cSliuyi //		 return true;
2200dcb0a4cSliuyi //	}
221c29e5f0fSliuyi int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName)
22276af099aSliuyi {
22376af099aSliuyi 	unsigned int i;
224c29e5f0fSliuyi 	for(i = 0; i < vecItems.size(); i++){
225c29e5f0fSliuyi 		if (strcasecmp(pszName, vecItems[i].szItemName) == 0){
22676af099aSliuyi 			return i;
22776af099aSliuyi 		}
22876af099aSliuyi 	}
22976af099aSliuyi 	return -1;
23076af099aSliuyi }
231c29e5f0fSliuyi void string_to_uuid(string strUUid, char *uuid)
232c29e5f0fSliuyi {
233c29e5f0fSliuyi 	unsigned int i;
234c29e5f0fSliuyi 	char value;
235c29e5f0fSliuyi 	memset(uuid, 0, 16);
236c29e5f0fSliuyi 	for (i =0; i < strUUid.size(); i++) {
237c29e5f0fSliuyi 		value = 0;
238c29e5f0fSliuyi 		if ((strUUid[i] >= '0')&&(strUUid[i] <= '9'))
239c29e5f0fSliuyi 			value = strUUid[i] - '0';
240c29e5f0fSliuyi 		if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f'))
241c29e5f0fSliuyi 			value = strUUid[i] - 'a' + 10;
242c29e5f0fSliuyi 		if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F'))
243c29e5f0fSliuyi 			value = strUUid[i] - 'A' + 10;
244c29e5f0fSliuyi 		if ((i % 2) == 0)
245c29e5f0fSliuyi 			uuid[i / 2] += (value << 4);
246c29e5f0fSliuyi 		else
247c29e5f0fSliuyi 			uuid[i / 2] += value;
248c29e5f0fSliuyi 	}
249c29e5f0fSliuyi 	unsigned int *p32;
250c29e5f0fSliuyi 	unsigned short *p16;
251c29e5f0fSliuyi 	p32 = (unsigned int*)uuid;
252c29e5f0fSliuyi 	*p32 = cpu_to_be32(*p32);
253c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 4);
254c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
255c29e5f0fSliuyi 	p16 = (unsigned short *)(uuid + 6);
256c29e5f0fSliuyi 	*p16 = cpu_to_be16(*p16);
257c29e5f0fSliuyi }
25876af099aSliuyi 
25976af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
26076af099aSliuyi {
26176af099aSliuyi 
26276af099aSliuyi 	stringstream configStream(pConfig);
26376af099aSliuyi 	string strLine, strItemName, strItemValue;
26476af099aSliuyi 	string::size_type line_size,pos;
26576af099aSliuyi 	STRUCT_CONFIG_ITEM item;
26676af099aSliuyi 	vecItem.clear();
26776af099aSliuyi 	while (!configStream.eof()){
26876af099aSliuyi 		getline(configStream, strLine);
26976af099aSliuyi 		line_size = strLine.size();
27076af099aSliuyi 		if (line_size == 0)
27176af099aSliuyi 			continue;
27276af099aSliuyi 		if (strLine[line_size-1] == '\r'){
27376af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
27476af099aSliuyi 		}
275c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
276c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
277c30d921cSKever Yang 		if (strLine.size()==0 )
278c30d921cSKever Yang 			continue;
279c30d921cSKever Yang 		if (strLine[0] == '#')
280c30d921cSKever Yang 			continue;
28176af099aSliuyi 		pos = strLine.find("=");
28276af099aSliuyi 		if (pos == string::npos){
28376af099aSliuyi 			continue;
28476af099aSliuyi 		}
28576af099aSliuyi 		strItemName = strLine.substr(0, pos);
28676af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
28776af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
28876af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
28976af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
29076af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
29176af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
29276af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
29376af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
29476af099aSliuyi 			vecItem.push_back(item);
29576af099aSliuyi 		}
29676af099aSliuyi 	}
29776af099aSliuyi 	return true;
29876af099aSliuyi 
29976af099aSliuyi }
30076af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
30176af099aSliuyi {
30276af099aSliuyi 	FILE *file = NULL;
30376af099aSliuyi 	file = fopen(pConfigFile, "rb");
30476af099aSliuyi 	if( !file ){
30576af099aSliuyi 		if (g_pLogObject)
30632268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile);
30776af099aSliuyi 		return false;
30876af099aSliuyi 	}
30976af099aSliuyi 	int iFileSize;
31076af099aSliuyi 	fseek(file, 0, SEEK_END);
31176af099aSliuyi 	iFileSize = ftell(file);
31276af099aSliuyi 	fseek(file, 0, SEEK_SET);
31376af099aSliuyi 	char *pConfigBuf = NULL;
31476af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
31576af099aSliuyi 	if (!pConfigBuf){
31676af099aSliuyi 		fclose(file);
31776af099aSliuyi 		return false;
31876af099aSliuyi 	}
31976af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
32076af099aSliuyi 	int iRead;
32176af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
32276af099aSliuyi 	if (iRead != iFileSize){
32376af099aSliuyi 		if (g_pLogObject)
32432268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize);
32576af099aSliuyi 		fclose(file);
32676af099aSliuyi 		delete []pConfigBuf;
32776af099aSliuyi 		return false;
32876af099aSliuyi 	}
32976af099aSliuyi 	fclose(file);
33076af099aSliuyi 	bool bRet;
33176af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
33276af099aSliuyi 	delete []pConfigBuf;
33376af099aSliuyi 	return bRet;
33476af099aSliuyi }
335c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
336c30d921cSKever Yang {
337c30d921cSKever Yang 	string::size_type pos,prevPos;
338c30d921cSKever Yang 	string strOffset,strLen;
339c30d921cSKever Yang 	int iCount;
340c30d921cSKever Yang 	prevPos = pos = 0;
341c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
342c30d921cSKever Yang 		return false;
343c30d921cSKever Yang 	}
344c30d921cSKever Yang 	pos = strPartInfo.find('@');
345c30d921cSKever Yang 	if (pos == string::npos) {
346c30d921cSKever Yang 		return false;
347c30d921cSKever Yang 	}
348c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
349c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
350c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
351c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
352c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
353c30d921cSKever Yang 	} else {
354c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
355c30d921cSKever Yang 		if (iCount != 1) {
356c30d921cSKever Yang 			return false;
357c30d921cSKever Yang 		}
358c30d921cSKever Yang 	}
359c30d921cSKever Yang 
360c30d921cSKever Yang 	prevPos = pos + 1;
361c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
362c30d921cSKever Yang 	if (pos == string::npos) {
363c30d921cSKever Yang 		return false;
364c30d921cSKever Yang 	}
365c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
366c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
367c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
368c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
369c30d921cSKever Yang 	if (iCount != 1) {
370c30d921cSKever Yang 		return false;
371c30d921cSKever Yang 	}
372c30d921cSKever Yang 	prevPos = pos + 1;
373c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
374c30d921cSKever Yang 	if (pos == string::npos) {
375c30d921cSKever Yang 		return false;
376c30d921cSKever Yang 	}
377c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
378c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
379c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
380c30d921cSKever Yang 
381c30d921cSKever Yang 	return true;
382c30d921cSKever Yang }
383c29e5f0fSliuyi bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid)
384c29e5f0fSliuyi {
385c29e5f0fSliuyi 	string::size_type pos(0);
386c30d921cSKever Yang 
387c29e5f0fSliuyi 	if (strUuidInfo.size() <= 0) {
388c29e5f0fSliuyi 		return false;
389c29e5f0fSliuyi 	}
390c29e5f0fSliuyi 	pos = strUuidInfo.find('=');
391c29e5f0fSliuyi 	if (pos == string::npos) {
392c29e5f0fSliuyi 		return false;
393c29e5f0fSliuyi 	}
394c29e5f0fSliuyi 	strName = strUuidInfo.substr(0, pos);
395c29e5f0fSliuyi 	strName.erase(0, strName.find_first_not_of(" "));
396c29e5f0fSliuyi 	strName.erase(strName.find_last_not_of(" ") + 1);
397c29e5f0fSliuyi 
398c29e5f0fSliuyi 	strUUid = strUuidInfo.substr(pos+1);
399c29e5f0fSliuyi 	strUUid.erase(0, strUUid.find_first_not_of(" "));
400c29e5f0fSliuyi 	strUUid.erase(strUUid.find_last_not_of(" ") + 1);
401c29e5f0fSliuyi 
402c29e5f0fSliuyi 	while(true) {
403c29e5f0fSliuyi 		pos = 0;
404c29e5f0fSliuyi 		if( (pos = strUUid.find("-")) != string::npos)
405c29e5f0fSliuyi 			strUUid.replace(pos,1,"");
406c29e5f0fSliuyi 		else
407c29e5f0fSliuyi 			break;
408c29e5f0fSliuyi 	}
409c29e5f0fSliuyi 	if (strUUid.size() != 32)
410c29e5f0fSliuyi 		return false;
411c29e5f0fSliuyi 	return true;
412c29e5f0fSliuyi }
413c29e5f0fSliuyi 
414c29e5f0fSliuyi 
415c29e5f0fSliuyi bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
416c30d921cSKever Yang {
417c30d921cSKever Yang 	stringstream paramStream(pParameter);
418c30d921cSKever Yang 	bool bRet,bFind = false;
419c29e5f0fSliuyi 	string strLine, strPartition, strPartInfo, strPartName, strUUid;
420c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
421c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
422c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
423c29e5f0fSliuyi 	STRUCT_CONFIG_ITEM uuid_item;
424c30d921cSKever Yang 	vecItem.clear();
425c29e5f0fSliuyi 	vecUuidItem.clear();
426c30d921cSKever Yang 	while (!paramStream.eof()) {
427c30d921cSKever Yang 		getline(paramStream,strLine);
428c30d921cSKever Yang 		line_size = strLine.size();
429c30d921cSKever Yang 		if (line_size == 0)
430c30d921cSKever Yang 			continue;
431c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
432c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
433c30d921cSKever Yang 		}
434c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
435c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
436c30d921cSKever Yang 		if (strLine.size()==0 )
437c30d921cSKever Yang 			continue;
438c30d921cSKever Yang 		if (strLine[0] == '#')
439c30d921cSKever Yang 			continue;
440c29e5f0fSliuyi 		pos = strLine.find("uuid:");
441c29e5f0fSliuyi 		if (pos != string::npos) {
442c29e5f0fSliuyi 			strPartInfo = strLine.substr(pos+5);
443c29e5f0fSliuyi 			bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid);
444c29e5f0fSliuyi 			if (bRet) {
445c29e5f0fSliuyi 				strcpy(uuid_item.szItemName, strPartName.c_str());
446c29e5f0fSliuyi 				string_to_uuid(strUUid,uuid_item.szItemValue);
447c29e5f0fSliuyi 				vecUuidItem.push_back(uuid_item);
448c29e5f0fSliuyi 			}
449c29e5f0fSliuyi 			continue;
450c29e5f0fSliuyi 		}
451c29e5f0fSliuyi 
452c30d921cSKever Yang 		pos = strLine.find("mtdparts");
453c30d921cSKever Yang 		if (pos == string::npos) {
454c30d921cSKever Yang 			continue;
455c30d921cSKever Yang 		}
456c30d921cSKever Yang 		bFind = true;
457c30d921cSKever Yang 		posColon = strLine.find(':', pos);
458c30d921cSKever Yang 		if (posColon == string::npos) {
459c30d921cSKever Yang 			continue;
460c30d921cSKever Yang 		}
461c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
462c30d921cSKever Yang 		pos = 0;
463c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
464c30d921cSKever Yang 		while (posComma != string::npos) {
465c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
466c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
467c30d921cSKever Yang 			if (bRet) {
468c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
469c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
470c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
471c30d921cSKever Yang 				vecItem.push_back(item);
472c30d921cSKever Yang 			}
473c30d921cSKever Yang 			pos = posComma + 1;
474c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
475c30d921cSKever Yang 		}
476c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
477c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
478c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
479c30d921cSKever Yang 			if (bRet) {
480c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
481c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
482c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
483c30d921cSKever Yang 				vecItem.push_back(item);
484c30d921cSKever Yang 			}
485c30d921cSKever Yang 		}
486c30d921cSKever Yang 	}
487c30d921cSKever Yang 	return bFind;
488c30d921cSKever Yang 
489c30d921cSKever Yang }
490c29e5f0fSliuyi bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem)
491c30d921cSKever Yang {
492c30d921cSKever Yang 	FILE *file = NULL;
493c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
494c30d921cSKever Yang 	if( !file ) {
495c30d921cSKever Yang 		if (g_pLogObject)
49632268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
497c30d921cSKever Yang 		return false;
498c30d921cSKever Yang 	}
499c30d921cSKever Yang 	int iFileSize;
500c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
501c30d921cSKever Yang 	iFileSize = ftell(file);
502c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
503c30d921cSKever Yang 	char *pParamBuf = NULL;
504c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
505c30d921cSKever Yang 	if (!pParamBuf) {
506c30d921cSKever Yang 		fclose(file);
507c30d921cSKever Yang 		return false;
508c30d921cSKever Yang 	}
509c30d921cSKever Yang 	int iRead;
510c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
511c30d921cSKever Yang 	if (iRead != iFileSize) {
512c30d921cSKever Yang 		if (g_pLogObject)
51332268622SAndreas Färber 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize);
514c30d921cSKever Yang 		fclose(file);
515c30d921cSKever Yang 		delete []pParamBuf;
516c30d921cSKever Yang 		return false;
517c30d921cSKever Yang 	}
518c30d921cSKever Yang 	fclose(file);
519c30d921cSKever Yang 	bool bRet;
520c29e5f0fSliuyi 	bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem);
521c30d921cSKever Yang 	delete []pParamBuf;
522c30d921cSKever Yang 	return bRet;
523c30d921cSKever Yang }
5246ae612beSliuyi bool is_sparse_image(char *szImage)
5256ae612beSliuyi {
5266ae612beSliuyi 	FILE *file = NULL;
5276ae612beSliuyi 	sparse_header head;
5286ae612beSliuyi 	u32 uiRead;
5296ae612beSliuyi 	file = fopen(szImage, "rb");
5306ae612beSliuyi 	if( !file ) {
5316ae612beSliuyi 		if (g_pLogObject)
5326ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
5336ae612beSliuyi 		return false;
5346ae612beSliuyi 	}
5356ae612beSliuyi 	uiRead = fread(&head, 1, sizeof(head), file);
5366ae612beSliuyi 	if (uiRead != sizeof(head)) {
5376ae612beSliuyi 		if (g_pLogObject)
5386ae612beSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head));
5396ae612beSliuyi 		fclose(file);
5406ae612beSliuyi 		return false;
5416ae612beSliuyi 	}
5426ae612beSliuyi 	fclose(file);
5436ae612beSliuyi 	if (head.magic!=SPARSE_HEADER_MAGIC)
5446ae612beSliuyi 	{
5456ae612beSliuyi 		return false;
5466ae612beSliuyi 	}
5476ae612beSliuyi 	return true;
5486ae612beSliuyi 
5496ae612beSliuyi }
5500dcb0a4cSliuyi bool is_ubifs_image(char *szImage)
5510dcb0a4cSliuyi {
5520dcb0a4cSliuyi 	FILE *file = NULL;
5530dcb0a4cSliuyi 	u32 magic;
5540dcb0a4cSliuyi 	u32 uiRead;
5550dcb0a4cSliuyi 	file = fopen(szImage, "rb");
5560dcb0a4cSliuyi 	if( !file ) {
5570dcb0a4cSliuyi 		if (g_pLogObject)
5580dcb0a4cSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage);
5590dcb0a4cSliuyi 		return false;
5600dcb0a4cSliuyi 	}
5610dcb0a4cSliuyi 	uiRead = fread(&magic, 1, sizeof(magic), file);
5620dcb0a4cSliuyi 	if (uiRead != sizeof(magic)) {
5630dcb0a4cSliuyi 		if (g_pLogObject)
5640dcb0a4cSliuyi 			g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(magic));
5650dcb0a4cSliuyi 		fclose(file);
5660dcb0a4cSliuyi 		return false;
5670dcb0a4cSliuyi 	}
5680dcb0a4cSliuyi 	fclose(file);
5690dcb0a4cSliuyi 	if (magic!=UBI_HEADER_MAGIC)
5700dcb0a4cSliuyi 	{
5710dcb0a4cSliuyi 		return false;
5720dcb0a4cSliuyi 	}
5730dcb0a4cSliuyi 	return true;
5740dcb0a4cSliuyi }
575c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
576c30d921cSKever Yang {
577c30d921cSKever Yang 	efi_guid_t id;
578c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
579c30d921cSKever Yang 	unsigned int i;
580c30d921cSKever Yang 
581c30d921cSKever Yang 	/* Set all fields randomly */
582c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
583c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
584c30d921cSKever Yang 
585c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
586c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
587c30d921cSKever Yang 
588c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
589c30d921cSKever Yang }
590c30d921cSKever Yang 
591c29e5f0fSliuyi void prepare_gpt_backup(u8 *master, u8 *backup)
592c29e5f0fSliuyi {
593c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
594c29e5f0fSliuyi 	gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
595c29e5f0fSliuyi 	u32 calc_crc32;
596c29e5f0fSliuyi 	u64 val;
597c29e5f0fSliuyi 
598c29e5f0fSliuyi 	/* recalculate the values for the Backup GPT Header */
599c29e5f0fSliuyi 	val = le64_to_cpu(gptMasterHead->my_lba);
600c29e5f0fSliuyi 	gptBackupHead->my_lba = gptMasterHead->alternate_lba;
601c29e5f0fSliuyi 	gptBackupHead->alternate_lba = cpu_to_le64(val);
602c29e5f0fSliuyi 	gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1);
603c29e5f0fSliuyi 	gptBackupHead->header_crc32 = 0;
604c29e5f0fSliuyi 
605c29e5f0fSliuyi 	calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
606c29e5f0fSliuyi 	gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
607c29e5f0fSliuyi }
6086ae612beSliuyi bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end)
6096ae612beSliuyi {
6106ae612beSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
6116ae612beSliuyi 	gpt_entry  *gptEntry  = NULL;
6126ae612beSliuyi 	u32 i,j;
6136ae612beSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
6146ae612beSliuyi 	bool bFound = false;
6156ae612beSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
6166ae612beSliuyi 
6176ae612beSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
6186ae612beSliuyi 		gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
6196ae612beSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
6206ae612beSliuyi 			break;
6216ae612beSliuyi 		for (j = 0; j < strlen(pszName); j++)
6226ae612beSliuyi 			if (gptEntry->partition_name[j] != pszName[j])
6236ae612beSliuyi 				break;
6246ae612beSliuyi 		if (gptEntry->partition_name[j] != 0)
6256ae612beSliuyi 			continue;
6266ae612beSliuyi 		if (j == strlen(pszName)) {
6276ae612beSliuyi 			bFound = true;
6286ae612beSliuyi 			break;
6296ae612beSliuyi 		}
6306ae612beSliuyi 	}
6316ae612beSliuyi 	if (bFound) {
6326ae612beSliuyi 		*lba = le64_to_cpu(gptEntry->starting_lba);
633*e541b7bbSliuyi 		if (gptMasterHead->last_usable_lba == gptEntry->ending_lba)
634*e541b7bbSliuyi 			*lba_end = 0xFFFFFFFF;
635*e541b7bbSliuyi 		else
6366ae612beSliuyi 			*lba_end =  le64_to_cpu(gptEntry->ending_lba);
6376ae612beSliuyi 		return true;
6386ae612beSliuyi 	}
6396ae612beSliuyi 	return false;
6406ae612beSliuyi }
641081d237aSliuyi bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size)
642081d237aSliuyi {
643081d237aSliuyi 	u32 i;
644081d237aSliuyi 	bool bFound = false, bRet;
645081d237aSliuyi 	PARAM_ITEM_VECTOR vecItem;
646081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
647081d237aSliuyi 
648081d237aSliuyi 	bRet = parse_parameter((char *)param, vecItem, vecUuid);
649081d237aSliuyi 	if (!bRet)
650081d237aSliuyi 		return false;
651081d237aSliuyi 
652081d237aSliuyi 	for (i = 0; i < vecItem.size(); i++) {
653081d237aSliuyi 		if (strcasecmp(pszName, vecItem[i].szItemName)==0) {
654081d237aSliuyi 			bFound = true;
655081d237aSliuyi 			break;
656081d237aSliuyi 		}
657081d237aSliuyi 	}
658081d237aSliuyi 	if (bFound) {
659081d237aSliuyi 		*part_offset = vecItem[i].uiItemOffset;
660081d237aSliuyi 		*part_size =  vecItem[i].uiItemSize;
661081d237aSliuyi 		return true;
662081d237aSliuyi 	}
663081d237aSliuyi 	return false;
664081d237aSliuyi }
665081d237aSliuyi 
666c29e5f0fSliuyi void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector)
667c29e5f0fSliuyi {
668c29e5f0fSliuyi 	gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE);
669c29e5f0fSliuyi 	gpt_entry  *gptLastPartEntry  = NULL;
670c29e5f0fSliuyi 	u32 i;
671c29e5f0fSliuyi 	u64 old_disksize;
672c29e5f0fSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
673c29e5f0fSliuyi 
674c29e5f0fSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
675c29e5f0fSliuyi 	old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1;
676c29e5f0fSliuyi 	for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) {
677c29e5f0fSliuyi 		gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
678c29e5f0fSliuyi 		if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0)
679c29e5f0fSliuyi 			break;
680c29e5f0fSliuyi 	}
681c29e5f0fSliuyi 	i--;
682c29e5f0fSliuyi 	gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry));
683c29e5f0fSliuyi 
684c29e5f0fSliuyi 	gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1);
685c29e5f0fSliuyi 	gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34);
686c29e5f0fSliuyi 
687c29e5f0fSliuyi 	if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition
688c29e5f0fSliuyi 		gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34);
689c29e5f0fSliuyi 		gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
690c29e5f0fSliuyi 	}
691c29e5f0fSliuyi 	gptMasterHead->header_crc32 = 0;
692c29e5f0fSliuyi 	gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header)));
693c29e5f0fSliuyi 	memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS);
694c29e5f0fSliuyi 	memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE);
695c29e5f0fSliuyi 	prepare_gpt_backup(master, backup);
696c29e5f0fSliuyi 
697c29e5f0fSliuyi }
698c29e5f0fSliuyi bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup)
699c29e5f0fSliuyi {
700c29e5f0fSliuyi 	FILE *file = NULL;
701c29e5f0fSliuyi 	file = fopen(pParamFile, "rb");
702c29e5f0fSliuyi 	if( !file ) {
703c29e5f0fSliuyi 		if (g_pLogObject)
704c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile);
705c29e5f0fSliuyi 		return false;
706c29e5f0fSliuyi 	}
707c29e5f0fSliuyi 	int iFileSize;
708c29e5f0fSliuyi 	fseek(file, 0, SEEK_END);
709c29e5f0fSliuyi 	iFileSize = ftell(file);
710c29e5f0fSliuyi 	fseek(file, 0, SEEK_SET);
711c29e5f0fSliuyi 	if (iFileSize != 67 * SECTOR_SIZE) {
712c29e5f0fSliuyi 		if (g_pLogObject)
713c29e5f0fSliuyi 			g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile);
714c29e5f0fSliuyi 		fclose(file);
715c29e5f0fSliuyi 		return false;
716c29e5f0fSliuyi 	}
717c29e5f0fSliuyi 
718c29e5f0fSliuyi 	int iRead;
719c29e5f0fSliuyi 	iRead = fread(master, 1, 34 * SECTOR_SIZE, file);
720c29e5f0fSliuyi 	if (iRead != 34 * SECTOR_SIZE) {
721c29e5f0fSliuyi 		if (g_pLogObject)
722c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE);
723c29e5f0fSliuyi 		fclose(file);
724c29e5f0fSliuyi 		return false;
725c29e5f0fSliuyi 	}
726c29e5f0fSliuyi 	iRead = fread(backup, 1, 33 * SECTOR_SIZE, file);
727c29e5f0fSliuyi 	if (iRead != 33 * SECTOR_SIZE) {
728c29e5f0fSliuyi 		if (g_pLogObject)
729c29e5f0fSliuyi 			g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE);
730c29e5f0fSliuyi 		fclose(file);
731c29e5f0fSliuyi 		return false;
732c29e5f0fSliuyi 	}
733c29e5f0fSliuyi 	fclose(file);
734c29e5f0fSliuyi 	return true;
735c29e5f0fSliuyi }
736c29e5f0fSliuyi void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
737c30d921cSKever Yang {
738c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
739c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
740c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
741c30d921cSKever Yang 	u32 i,j;
742c29e5f0fSliuyi 	int pos;
743c30d921cSKever Yang 	string strPartName;
744c30d921cSKever Yang 	string::size_type colonPos;
745c30d921cSKever Yang 	/*1.protective mbr*/
746c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
747c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
748c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
749c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
750c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
751c30d921cSKever Yang 	/*2.gpt header*/
752c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
753c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
754c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
755c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
756c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
757c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
758c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
759c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
760c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
761c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
762c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
763c30d921cSKever Yang 	gptHead->header_crc32 = 0;
764c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
765c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
766c30d921cSKever Yang 
767c30d921cSKever Yang 	/*3.gpt partition entry*/
768c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
769c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
770c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
771c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
772c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
773c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
774c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
775c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
776c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
777c30d921cSKever Yang 		if (colonPos != string::npos) {
778c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
779c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
780c29e5f0fSliuyi 			if (strPartName.find("grow") != string::npos)
781c29e5f0fSliuyi 				gptEntry->ending_lba = cpu_to_le64(diskSectors - 34);
782c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
783c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
784c30d921cSKever Yang 		}
785c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
786c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
787c29e5f0fSliuyi 		if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1)
788c29e5f0fSliuyi 			memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
789c30d921cSKever Yang 		gptEntry++;
790c30d921cSKever Yang 	}
791c30d921cSKever Yang 
792c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
793c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
794c30d921cSKever Yang 
795c30d921cSKever Yang }
796b38fe5fcSliuyi bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag)
797c30d921cSKever Yang {
798c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
799c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
800c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
801c30d921cSKever Yang 
802c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
803b38fe5fcSliuyi 	pSec0->uiRc4Flag = rc4Flag;
804c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
805c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
806c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
807c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
808c30d921cSKever Yang 	return true;
809c30d921cSKever Yang }
810c30d921cSKever Yang 
811c30d921cSKever Yang 
812c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
813c30d921cSKever Yang {
814c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
815c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
816c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
817c30d921cSKever Yang 
818c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
819c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
820c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
821c30d921cSKever Yang 	return true;
822c30d921cSKever Yang }
823c30d921cSKever Yang 
824c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
825c30d921cSKever Yang {
826c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
827c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
828c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
829c30d921cSKever Yang 
830c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
831c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
832c30d921cSKever Yang 	return true;
833c30d921cSKever Yang }
834c30d921cSKever Yang 
835c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
836c30d921cSKever Yang {
837c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
838c30d921cSKever Yang 	return true;
839c30d921cSKever Yang }
840c30d921cSKever Yang 
841b38fe5fcSliuyi int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag)
842c30d921cSKever Yang {
843c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
844c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
845c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
846c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
847c30d921cSKever Yang 	UINT i;
848b38fe5fcSliuyi 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec, rc4Flag);
849c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
850c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
851c30d921cSKever Yang 		return -6;
852c30d921cSKever Yang 	}
853c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
854c30d921cSKever Yang 		return -7;
855c30d921cSKever Yang 	}
856c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
857c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
858c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
859c30d921cSKever Yang 
860c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
861c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
862c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
863b38fe5fcSliuyi 
864b38fe5fcSliuyi 	if (rc4Flag) {
865b38fe5fcSliuyi 		for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++)
866b38fe5fcSliuyi 			P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE);
867b38fe5fcSliuyi 		for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++)
868b38fe5fcSliuyi 			P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE);
869b38fe5fcSliuyi 	}
870b38fe5fcSliuyi 
871c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
872c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
873c30d921cSKever Yang 
874c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
875c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
876c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
877c30d921cSKever Yang 		if(i == 1) {
878c30d921cSKever Yang 			continue;
879c30d921cSKever Yang 		} else {
880c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
881c30d921cSKever Yang 		}
882c30d921cSKever Yang 	}
883c30d921cSKever Yang 	return 0;
884c30d921cSKever Yang }
885c30d921cSKever Yang 
886c30d921cSKever Yang 
88776af099aSliuyi 
88876af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
88976af099aSliuyi {
89006ea143eSKlaus Goger 	if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType)
89176af099aSliuyi 		return true;
89276af099aSliuyi 	else
89376af099aSliuyi 	{
89476af099aSliuyi 		ERROR_COLOR_ATTR;
89532268622SAndreas Färber 		printf("The device does not support this operation!");
89676af099aSliuyi 		NORMAL_COLOR_ATTR;
89776af099aSliuyi 		printf("\r\n");
89876af099aSliuyi 		return false;
89976af099aSliuyi 	}
90076af099aSliuyi }
901081d237aSliuyi bool MakeParamBuffer(char *pParamFile, char* &pParamData)
902081d237aSliuyi {
903081d237aSliuyi 	FILE *file=NULL;
904081d237aSliuyi 	file = fopen(pParamFile, "rb");
905081d237aSliuyi 	if( !file )
906081d237aSliuyi 	{
907081d237aSliuyi 		if (g_pLogObject)
908081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile);
909081d237aSliuyi 		return false;
910081d237aSliuyi 	}
911081d237aSliuyi 	int iFileSize;
912081d237aSliuyi 	fseek(file,0,SEEK_END);
913081d237aSliuyi 	iFileSize = ftell(file);
914081d237aSliuyi 	fseek(file,0,SEEK_SET);
915081d237aSliuyi 	char *pParamBuf=NULL;
916081d237aSliuyi 	pParamBuf = new char[iFileSize + 12];
917081d237aSliuyi 	if (!pParamBuf)
918081d237aSliuyi 	{
919081d237aSliuyi 		fclose(file);
920081d237aSliuyi 		return false;
921081d237aSliuyi 	}
922081d237aSliuyi 	memset(pParamBuf,0,iFileSize+12);
923081d237aSliuyi 	*(UINT *)(pParamBuf) = 0x4D524150;
924081d237aSliuyi 
925081d237aSliuyi 	int iRead;
926081d237aSliuyi 	iRead = fread(pParamBuf+8,1,iFileSize,file);
927081d237aSliuyi 	if (iRead!=iFileSize)
928081d237aSliuyi 	{
929081d237aSliuyi 		if (g_pLogObject)
930081d237aSliuyi 			g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize);
931081d237aSliuyi 		fclose(file);
932081d237aSliuyi 		delete []pParamBuf;
933081d237aSliuyi 		return false;
934081d237aSliuyi 	}
935081d237aSliuyi 	fclose(file);
936081d237aSliuyi 
937081d237aSliuyi 	*(UINT *)(pParamBuf+4) = iFileSize;
938081d237aSliuyi 	*(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize);
939081d237aSliuyi 	pParamData = pParamBuf;
940081d237aSliuyi 	return true;
941081d237aSliuyi }
942081d237aSliuyi 
943081d237aSliuyi bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
944081d237aSliuyi {
945081d237aSliuyi 	CRKComm *pComm = NULL;
946081d237aSliuyi 	char *pParamBuf = NULL, writeBuf[512*1024];
947081d237aSliuyi 	int iRet, nParamSec, nParamSize;
948081d237aSliuyi 	bool bRet, bSuccess = false;
949081d237aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER))
950081d237aSliuyi 		return false;
951081d237aSliuyi 
952081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
953081d237aSliuyi 	if (!bRet) {
954081d237aSliuyi 		ERROR_COLOR_ATTR;
955081d237aSliuyi 		printf("Creating Comm Object failed!");
956081d237aSliuyi 		NORMAL_COLOR_ATTR;
957081d237aSliuyi 		printf("\r\n");
958081d237aSliuyi 		return bSuccess;
959081d237aSliuyi 	}
960081d237aSliuyi 	if (!MakeParamBuffer(szParameter, pParamBuf)) {
961081d237aSliuyi 		ERROR_COLOR_ATTR;
962081d237aSliuyi 		printf("Generating parameter failed!");
963081d237aSliuyi 		NORMAL_COLOR_ATTR;
964081d237aSliuyi 		printf("\r\n");
965081d237aSliuyi 		return bSuccess;
966081d237aSliuyi 	}
967081d237aSliuyi 	printf("Writing parameter...\r\n");
968081d237aSliuyi 	nParamSize = *(UINT *)(pParamBuf+4) + 12;
969081d237aSliuyi 	nParamSec = BYTE2SECTOR(nParamSize);
970081d237aSliuyi 	if (nParamSec > 1024) {
971081d237aSliuyi 		ERROR_COLOR_ATTR;
972081d237aSliuyi 		printf("parameter is too large!");
973081d237aSliuyi 		NORMAL_COLOR_ATTR;
974081d237aSliuyi 		printf("\r\n");
975081d237aSliuyi 		return bSuccess;
976081d237aSliuyi 	}
977081d237aSliuyi 	memset(writeBuf, 0, nParamSec*512);
978081d237aSliuyi 	memcpy(writeBuf, pParamBuf, nParamSize);
979081d237aSliuyi 	iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf);
980081d237aSliuyi 	if (iRet != ERR_SUCCESS) {
981081d237aSliuyi 		ERROR_COLOR_ATTR;
982081d237aSliuyi 		printf("Writing parameter failed!");
983081d237aSliuyi 		NORMAL_COLOR_ATTR;
984081d237aSliuyi 		printf("\r\n");
985081d237aSliuyi 		return bSuccess;
986081d237aSliuyi 	}
987081d237aSliuyi 
988081d237aSliuyi 	bSuccess = true;
989081d237aSliuyi 	CURSOR_MOVEUP_LINE(1);
990081d237aSliuyi 	CURSOR_DEL_LINE;
991081d237aSliuyi 	printf("Writing parameter succeeded.\r\n");
992081d237aSliuyi 	return bSuccess;
993081d237aSliuyi }
994081d237aSliuyi 
995c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
996c30d921cSKever Yang {
997c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
998c30d921cSKever Yang 	u32 total_size_sector;
999c30d921cSKever Yang 	CRKComm *pComm = NULL;
1000c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
1001c29e5f0fSliuyi 	CONFIG_ITEM_VECTOR vecUuid;
1002c30d921cSKever Yang 	int iRet;
1003c30d921cSKever Yang 	bool bRet, bSuccess = false;
1004c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1005c30d921cSKever Yang 		return false;
1006c30d921cSKever Yang 
1007c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1008c30d921cSKever Yang 	if (!bRet) {
1009c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1010c30d921cSKever Yang 		printf("Creating Comm Object failed!");
1011c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1012c30d921cSKever Yang 		printf("\r\n");
1013c30d921cSKever Yang 		return bSuccess;
1014c30d921cSKever Yang 	}
101532268622SAndreas Färber 	printf("Writing gpt...\r\n");
1016c30d921cSKever Yang 	//1.get flash info
1017c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
1018c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
1019c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1020c30d921cSKever Yang 		printf("Reading Flash Info failed!");
1021c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1022c30d921cSKever Yang 		printf("\r\n");
1023c30d921cSKever Yang 		return bSuccess;
1024c30d921cSKever Yang 	}
1025c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
1026c29e5f0fSliuyi 	if (strstr(szParameter, ".img")) {
1027c29e5f0fSliuyi 		if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) {
1028c29e5f0fSliuyi 			ERROR_COLOR_ATTR;
1029c29e5f0fSliuyi 			printf("Loading partition image failed!");
1030c29e5f0fSliuyi 			NORMAL_COLOR_ATTR;
1031c29e5f0fSliuyi 			printf("\r\n");
1032c29e5f0fSliuyi 			return bSuccess;
1033c29e5f0fSliuyi 		}
1034c29e5f0fSliuyi 		update_gpt_disksize(master_gpt, backup_gpt, total_size_sector);
1035c29e5f0fSliuyi 	} else {
1036c30d921cSKever Yang 		//2.get partition from parameter
1037c29e5f0fSliuyi 		bRet = parse_parameter_file(szParameter, vecItems, vecUuid);
1038c30d921cSKever Yang 		if (!bRet) {
1039c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1040c30d921cSKever Yang 			printf("Parsing parameter failed!");
1041c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1042c30d921cSKever Yang 			printf("\r\n");
1043c30d921cSKever Yang 			return bSuccess;
1044c30d921cSKever Yang 		}
1045*e541b7bbSliuyi 		if (vecItems[vecItems.size()-1].uiItemSize!=0xFFFFFFFF)
1046*e541b7bbSliuyi 			total_size_sector = vecItems[vecItems.size()-1].uiItemOffset + vecItems[vecItems.size()-1].uiItemSize + 33
1047*e541b7bbSliuyi 		//vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33;
1048c30d921cSKever Yang 		//3.generate gpt info
1049c29e5f0fSliuyi 		create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector);
1050c30d921cSKever Yang 		memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
1051c30d921cSKever Yang 		memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
1052c29e5f0fSliuyi 		prepare_gpt_backup(master_gpt, backup_gpt);
1053c29e5f0fSliuyi 	}
1054c29e5f0fSliuyi 
1055c30d921cSKever Yang 	//4. write gpt
1056c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
1057c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
1058c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1059c30d921cSKever Yang 		printf("Writing master gpt failed!");
1060c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1061c30d921cSKever Yang 		printf("\r\n");
1062c30d921cSKever Yang 		return bSuccess;
1063c30d921cSKever Yang 	}
1064c29e5f0fSliuyi 	iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt);
1065c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
1066c30d921cSKever Yang 		ERROR_COLOR_ATTR;
1067c30d921cSKever Yang 		printf("Writing backup gpt failed!");
1068c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1069c30d921cSKever Yang 		printf("\r\n");
1070c30d921cSKever Yang 		return bSuccess;
1071c30d921cSKever Yang 	}
1072c29e5f0fSliuyi 
1073c30d921cSKever Yang 	bSuccess = true;
1074c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
1075c30d921cSKever Yang 	CURSOR_DEL_LINE;
107632268622SAndreas Färber 	printf("Writing gpt succeeded.\r\n");
1077c30d921cSKever Yang 	return bSuccess;
1078c30d921cSKever Yang }
107976af099aSliuyi 
108078884ef4SEddie Cai #include "boot_merger.h"
108178884ef4SEddie Cai #define ENTRY_ALIGN  (2048)
108278884ef4SEddie Cai options gOpts;
108378884ef4SEddie Cai 
108478884ef4SEddie Cai 
108578884ef4SEddie Cai char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX;
108678884ef4SEddie Cai char* gConfigPath;
108778884ef4SEddie Cai uint8_t gBuf[MAX_MERGE_SIZE];
108878884ef4SEddie Cai 
108978884ef4SEddie Cai static inline void fixPath(char* path) {
109078884ef4SEddie Cai 	int i, len = strlen(path);
109178884ef4SEddie Cai 	for(i=0; i<len; i++) {
109278884ef4SEddie Cai 		if (path[i] == '\\')
109378884ef4SEddie Cai 			path[i] = '/';
109478884ef4SEddie Cai 		else if (path[i] == '\r' || path[i] == '\n')
109578884ef4SEddie Cai 			path[i] = '\0';
109678884ef4SEddie Cai 	}
109778884ef4SEddie Cai }
109878884ef4SEddie Cai 
109978884ef4SEddie Cai static bool parseChip(FILE* file) {
110078884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
110178884ef4SEddie Cai 		return false;
110278884ef4SEddie Cai 	}
110378884ef4SEddie Cai 	if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) {
110478884ef4SEddie Cai 		return false;
110578884ef4SEddie Cai 	}
110678884ef4SEddie Cai 	printf("chip: %s\n", gOpts.chip);
110778884ef4SEddie Cai 	return true;
110878884ef4SEddie Cai }
110978884ef4SEddie Cai 
111078884ef4SEddie Cai static bool parseVersion(FILE* file) {
111178884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
111278884ef4SEddie Cai 		return false;
111378884ef4SEddie Cai 	}
111478884ef4SEddie Cai 	if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1)
111578884ef4SEddie Cai 		return false;
111678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
111778884ef4SEddie Cai 		return false;
111878884ef4SEddie Cai 	}
111978884ef4SEddie Cai 	if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1)
112078884ef4SEddie Cai 		return false;
112178884ef4SEddie Cai 	printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor);
112278884ef4SEddie Cai 	return true;
112378884ef4SEddie Cai }
112478884ef4SEddie Cai 
112578884ef4SEddie Cai static bool parse471(FILE* file) {
112678884ef4SEddie Cai 	int i, index, pos;
112778884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
112878884ef4SEddie Cai 
112978884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
113078884ef4SEddie Cai 		return false;
113178884ef4SEddie Cai 	}
113278884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1)
113378884ef4SEddie Cai 		return false;
113478884ef4SEddie Cai 	printf("num: %d\n", gOpts.code471Num);
113578884ef4SEddie Cai 	if (!gOpts.code471Num)
113678884ef4SEddie Cai 		return true;
113778884ef4SEddie Cai 	if (gOpts.code471Num < 0)
113878884ef4SEddie Cai 		return false;
113978884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
114078884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
114178884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
114278884ef4SEddie Cai 			return false;
114378884ef4SEddie Cai 		}
114478884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
114578884ef4SEddie Cai 				!= 2)
114678884ef4SEddie Cai 			return false;
114778884ef4SEddie Cai 		index--;
114878884ef4SEddie Cai 		fixPath(buf);
114978884ef4SEddie Cai 		strcpy((char*)gOpts.code471Path[index], buf);
115078884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code471Path[index]);
115178884ef4SEddie Cai 	}
115278884ef4SEddie Cai 	pos = ftell(file);
115378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
115478884ef4SEddie Cai 		return false;
115578884ef4SEddie Cai 	}
115678884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1)
115778884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
115878884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code471Sleep);
115978884ef4SEddie Cai 	return true;
116078884ef4SEddie Cai }
116178884ef4SEddie Cai 
116278884ef4SEddie Cai static bool parse472(FILE* file) {
116378884ef4SEddie Cai 	int i, index, pos;
116478884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
116578884ef4SEddie Cai 
116678884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
116778884ef4SEddie Cai 		return false;
116878884ef4SEddie Cai 	}
116978884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1)
117078884ef4SEddie Cai 		return false;
117178884ef4SEddie Cai 	printf("num: %d\n", gOpts.code472Num);
117278884ef4SEddie Cai 	if (!gOpts.code472Num)
117378884ef4SEddie Cai 		return true;
117478884ef4SEddie Cai 	if (gOpts.code472Num < 0)
117578884ef4SEddie Cai 		return false;
117678884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
117778884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
117878884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
117978884ef4SEddie Cai 			return false;
118078884ef4SEddie Cai 		}
118178884ef4SEddie Cai 		if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf)
118278884ef4SEddie Cai 				!= 2)
118378884ef4SEddie Cai 			return false;
118478884ef4SEddie Cai 		fixPath(buf);
118578884ef4SEddie Cai 		index--;
118678884ef4SEddie Cai 		strcpy((char*)gOpts.code472Path[index], buf);
118778884ef4SEddie Cai 		printf("path%i: %s\n", index, gOpts.code472Path[index]);
118878884ef4SEddie Cai 	}
118978884ef4SEddie Cai 	pos = ftell(file);
119078884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
119178884ef4SEddie Cai 		return false;
119278884ef4SEddie Cai 	}
119378884ef4SEddie Cai 	if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1)
119478884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
119578884ef4SEddie Cai 	printf("sleep: %d\n", gOpts.code472Sleep);
119678884ef4SEddie Cai 	return true;
119778884ef4SEddie Cai }
119878884ef4SEddie Cai 
119978884ef4SEddie Cai static bool parseLoader(FILE* file) {
120078884ef4SEddie Cai 	int i, j, index, pos;
120178884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
120278884ef4SEddie Cai 	char buf2[MAX_LINE_LEN];
120378884ef4SEddie Cai 
120478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
120578884ef4SEddie Cai 		return false;
120678884ef4SEddie Cai 	}
120778884ef4SEddie Cai 	pos = ftell(file);
120878884ef4SEddie Cai 	if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) {
120978884ef4SEddie Cai 		fseek(file, pos, SEEK_SET);
121078884ef4SEddie Cai 		if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) {
121178884ef4SEddie Cai 			return false;
121278884ef4SEddie Cai 		}
121378884ef4SEddie Cai 	}
121478884ef4SEddie Cai 	printf("num: %d\n", gOpts.loaderNum);
121578884ef4SEddie Cai 	if (!gOpts.loaderNum)
121678884ef4SEddie Cai 		return false;
121778884ef4SEddie Cai 	if (gOpts.loaderNum < 0)
121878884ef4SEddie Cai 		return false;
121978884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
122078884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
122178884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
122278884ef4SEddie Cai 			return false;
122378884ef4SEddie Cai 		}
122478884ef4SEddie Cai 		if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf)
122578884ef4SEddie Cai 				!= 2)
122678884ef4SEddie Cai 			return false;
122778884ef4SEddie Cai 		strcpy(gOpts.loader[index].name, buf);
122878884ef4SEddie Cai 		printf("name%d: %s\n", index, gOpts.loader[index].name);
1229544ec1d4SKlaus Goger 		index++;
123078884ef4SEddie Cai 	}
123178884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
123278884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
123378884ef4SEddie Cai 			return false;
123478884ef4SEddie Cai 		}
123578884ef4SEddie Cai 		if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2)
123678884ef4SEddie Cai 				!= 2)
123778884ef4SEddie Cai 			return false;
123878884ef4SEddie Cai 		for (j=0; j<gOpts.loaderNum; j++) {
123978884ef4SEddie Cai 			if (!strcmp(gOpts.loader[j].name, buf)) {
124078884ef4SEddie Cai 				fixPath(buf2);
124178884ef4SEddie Cai 				strcpy(gOpts.loader[j].path, buf2);
124278884ef4SEddie Cai 				printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path);
124378884ef4SEddie Cai 				break;
124478884ef4SEddie Cai 			}
124578884ef4SEddie Cai 		}
124678884ef4SEddie Cai 		if (j >= gOpts.loaderNum) {
124778884ef4SEddie Cai 			return false;
124878884ef4SEddie Cai 		}
124978884ef4SEddie Cai 	}
125078884ef4SEddie Cai 	return true;
125178884ef4SEddie Cai }
125278884ef4SEddie Cai 
125378884ef4SEddie Cai static bool parseOut(FILE* file) {
125478884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
125578884ef4SEddie Cai 		return false;
125678884ef4SEddie Cai 	}
125778884ef4SEddie Cai 	if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1)
125878884ef4SEddie Cai 		return false;
125978884ef4SEddie Cai 	fixPath(gOpts.outPath);
126078884ef4SEddie Cai 	printf("out: %s\n", gOpts.outPath);
126178884ef4SEddie Cai 	return true;
126278884ef4SEddie Cai }
126378884ef4SEddie Cai 
126478884ef4SEddie Cai 
126578884ef4SEddie Cai void printOpts(FILE* out) {
126678884ef4SEddie Cai 	int i;
126778884ef4SEddie Cai 	fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip);
126878884ef4SEddie Cai 	fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR
126978884ef4SEddie Cai 			"=%d\n", gOpts.major, gOpts.minor);
127078884ef4SEddie Cai 
127178884ef4SEddie Cai 	fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num);
127278884ef4SEddie Cai 	for (i=0 ;i<gOpts.code471Num ;i++) {
127378884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]);
127478884ef4SEddie Cai 	}
127578884ef4SEddie Cai 	if (gOpts.code471Sleep > 0)
127678884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep);
127778884ef4SEddie Cai 
127878884ef4SEddie Cai 	fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num);
127978884ef4SEddie Cai 	for (i=0 ;i<gOpts.code472Num ;i++) {
128078884ef4SEddie Cai 		fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]);
128178884ef4SEddie Cai 	}
128278884ef4SEddie Cai 	if (gOpts.code472Sleep > 0)
128378884ef4SEddie Cai 		fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep);
128478884ef4SEddie Cai 
128578884ef4SEddie Cai 	fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum);
128678884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
128778884ef4SEddie Cai 		fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name);
128878884ef4SEddie Cai 	}
128978884ef4SEddie Cai 	for (i=0 ;i<gOpts.loaderNum ;i++) {
129078884ef4SEddie Cai 		fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path);
129178884ef4SEddie Cai 	}
129278884ef4SEddie Cai 
129378884ef4SEddie Cai 	fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath);
129478884ef4SEddie Cai }
129578884ef4SEddie Cai 
129678884ef4SEddie Cai static bool parseOpts(void) {
129778884ef4SEddie Cai 	bool ret = false;
129878884ef4SEddie Cai 	bool chipOk = false;
129978884ef4SEddie Cai 	bool versionOk = false;
130078884ef4SEddie Cai 	bool code471Ok = true;
130178884ef4SEddie Cai 	bool code472Ok = true;
130278884ef4SEddie Cai 	bool loaderOk = false;
130378884ef4SEddie Cai 	bool outOk = false;
130478884ef4SEddie Cai 	char buf[MAX_LINE_LEN];
130578884ef4SEddie Cai 
130678884ef4SEddie Cai 	char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath;
130778884ef4SEddie Cai 	FILE* file;
130878884ef4SEddie Cai 	file = fopen(configPath, "r");
130978884ef4SEddie Cai 	if (!file) {
131078884ef4SEddie Cai 		fprintf(stderr, "config (%s) not found!\n", configPath);
131108c0d218SKlaus Goger 		if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) {
131278884ef4SEddie Cai 			file = fopen(DEF_CONFIG_FILE, "w");
131378884ef4SEddie Cai 			if (file) {
131432268622SAndreas Färber 				fprintf(stderr, "creating defconfig\n");
131578884ef4SEddie Cai 				printOpts(file);
131678884ef4SEddie Cai 			}
131778884ef4SEddie Cai 		}
131878884ef4SEddie Cai 		goto end;
131978884ef4SEddie Cai 	}
132078884ef4SEddie Cai 
132132268622SAndreas Färber 	printf("Starting to parse...\n");
132278884ef4SEddie Cai 
132378884ef4SEddie Cai 	if (SCANF_EAT(file) != 0) {
132478884ef4SEddie Cai 		goto end;
132578884ef4SEddie Cai 	}
132678884ef4SEddie Cai 	while(fscanf(file, "%s", buf) == 1) {
132778884ef4SEddie Cai 		if (!strcmp(buf, SEC_CHIP)) {
132878884ef4SEddie Cai 			chipOk = parseChip(file);
132978884ef4SEddie Cai 			if (!chipOk) {
133078884ef4SEddie Cai 				printf("parseChip failed!\n");
133178884ef4SEddie Cai 				goto end;
133278884ef4SEddie Cai 			}
133378884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_VERSION)) {
133478884ef4SEddie Cai 			versionOk = parseVersion(file);
133578884ef4SEddie Cai 			if (!versionOk) {
133678884ef4SEddie Cai 				printf("parseVersion failed!\n");
133778884ef4SEddie Cai 				goto end;
133878884ef4SEddie Cai 			}
133978884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_471)) {
134078884ef4SEddie Cai 			code471Ok = parse471(file);
134178884ef4SEddie Cai 			if (!code471Ok) {
134278884ef4SEddie Cai 				printf("parse471 failed!\n");
134378884ef4SEddie Cai 				goto end;
134478884ef4SEddie Cai 			}
134578884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_472)) {
134678884ef4SEddie Cai 			code472Ok = parse472(file);
134778884ef4SEddie Cai 			if (!code472Ok) {
134878884ef4SEddie Cai 				printf("parse472 failed!\n");
134978884ef4SEddie Cai 				goto end;
135078884ef4SEddie Cai 			}
135178884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_LOADER)) {
135278884ef4SEddie Cai 			loaderOk = parseLoader(file);
135378884ef4SEddie Cai 			if (!loaderOk) {
135478884ef4SEddie Cai 				printf("parseLoader failed!\n");
135578884ef4SEddie Cai 				goto end;
135678884ef4SEddie Cai 			}
135778884ef4SEddie Cai 		} else if (!strcmp(buf, SEC_OUT)) {
135878884ef4SEddie Cai 			outOk = parseOut(file);
135978884ef4SEddie Cai 			if (!outOk) {
136078884ef4SEddie Cai 				printf("parseOut failed!\n");
136178884ef4SEddie Cai 				goto end;
136278884ef4SEddie Cai 			}
136378884ef4SEddie Cai 		} else if (buf[0] == '#') {
136478884ef4SEddie Cai 			continue;
136578884ef4SEddie Cai 		} else {
136678884ef4SEddie Cai 			printf("unknown sec: %s!\n", buf);
136778884ef4SEddie Cai 			goto end;
136878884ef4SEddie Cai 		}
136978884ef4SEddie Cai 		if (SCANF_EAT(file) != 0) {
137078884ef4SEddie Cai 			goto end;
137178884ef4SEddie Cai 		}
137278884ef4SEddie Cai 	}
137378884ef4SEddie Cai 
137478884ef4SEddie Cai 	if (chipOk && versionOk && code471Ok && code472Ok
137578884ef4SEddie Cai 			&& loaderOk && outOk)
137678884ef4SEddie Cai 		ret = true;
137778884ef4SEddie Cai end:
137878884ef4SEddie Cai 	if (file)
137978884ef4SEddie Cai 		fclose(file);
138078884ef4SEddie Cai 	return ret;
138178884ef4SEddie Cai }
138278884ef4SEddie Cai 
138378884ef4SEddie Cai bool initOpts(void) {
138478884ef4SEddie Cai 	//set default opts
138578884ef4SEddie Cai 	gOpts.major = DEF_MAJOR;
138678884ef4SEddie Cai 	gOpts.minor = DEF_MINOR;
138778884ef4SEddie Cai 	strcpy(gOpts.chip, DEF_CHIP);
138878884ef4SEddie Cai 	gOpts.code471Sleep = DEF_CODE471_SLEEP;
138978884ef4SEddie Cai 	gOpts.code472Sleep = DEF_CODE472_SLEEP;
139078884ef4SEddie Cai 	gOpts.code471Num = DEF_CODE471_NUM;
139178884ef4SEddie Cai 	gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num);
139278884ef4SEddie Cai 	strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH);
139378884ef4SEddie Cai 	gOpts.code472Num = DEF_CODE472_NUM;
139478884ef4SEddie Cai 	gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num);
139578884ef4SEddie Cai 	strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH);
139678884ef4SEddie Cai 	gOpts.loaderNum = DEF_LOADER_NUM;
139778884ef4SEddie Cai 	gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum);
139878884ef4SEddie Cai 	strcpy(gOpts.loader[0].name, DEF_LOADER0);
139978884ef4SEddie Cai 	strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH);
140078884ef4SEddie Cai 	strcpy(gOpts.loader[1].name, DEF_LOADER1);
140178884ef4SEddie Cai 	strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH);
140278884ef4SEddie Cai 	strcpy(gOpts.outPath, DEF_OUT_PATH);
140378884ef4SEddie Cai 
140478884ef4SEddie Cai 	return parseOpts();
140578884ef4SEddie Cai }
140678884ef4SEddie Cai 
140778884ef4SEddie Cai /************merge code****************/
140878884ef4SEddie Cai 
140978884ef4SEddie Cai static inline uint32_t getBCD(unsigned short value) {
141078884ef4SEddie Cai 	uint8_t tmp[2] = {0};
141178884ef4SEddie Cai 	int i;
141278884ef4SEddie Cai 	uint32_t ret;
141378884ef4SEddie Cai 	//if (value > 0xFFFF) {
141478884ef4SEddie Cai 	//	return 0;
141578884ef4SEddie Cai 	//}
141678884ef4SEddie Cai 	for(i=0; i < 2; i++) {
141778884ef4SEddie Cai 		tmp[i] = (((value/10)%10)<<4) | (value%10);
141878884ef4SEddie Cai 		value /= 100;
141978884ef4SEddie Cai 	}
142078884ef4SEddie Cai 	ret = ((uint16_t)(tmp[1] << 8)) | tmp[0];
142178884ef4SEddie Cai 
142278884ef4SEddie Cai 	printf("ret: %x\n",ret);
142378884ef4SEddie Cai 	return ret&0xFF;
142478884ef4SEddie Cai }
142578884ef4SEddie Cai 
142678884ef4SEddie Cai static inline void str2wide(const char* str, uint16_t* wide, int len)
142778884ef4SEddie Cai {
142878884ef4SEddie Cai 	int i;
142978884ef4SEddie Cai 	for (i = 0; i < len; i++) {
143078884ef4SEddie Cai 		wide[i] = (uint16_t) str[i];
143178884ef4SEddie Cai 	}
143278884ef4SEddie Cai 	wide[len] = 0;
143378884ef4SEddie Cai }
143478884ef4SEddie Cai 
143578884ef4SEddie Cai static inline void getName(char* path, uint16_t* dst) {
143678884ef4SEddie Cai 	char* end;
143778884ef4SEddie Cai 	char* start;
143878884ef4SEddie Cai 	int len;
143978884ef4SEddie Cai 	if (!path || !dst)
144078884ef4SEddie Cai 		return;
144178884ef4SEddie Cai 	start = strrchr(path, '/');
144278884ef4SEddie Cai 	if (!start)
144378884ef4SEddie Cai 		start = path;
144478884ef4SEddie Cai 	else
144578884ef4SEddie Cai 		start++;
144678884ef4SEddie Cai 	end = strrchr(path, '.');
1447641cfa16SEddie Cai 	if (!end || (end < start))
144878884ef4SEddie Cai 		end = path + strlen(path);
144978884ef4SEddie Cai 	len = end - start;
145078884ef4SEddie Cai 	if (len >= MAX_NAME_LEN)
145178884ef4SEddie Cai 		len = MAX_NAME_LEN -1;
145278884ef4SEddie Cai 	str2wide(start, dst, len);
145378884ef4SEddie Cai 
145478884ef4SEddie Cai 
145578884ef4SEddie Cai 		char name[MAX_NAME_LEN];
145678884ef4SEddie Cai 		memset(name, 0, sizeof(name));
145778884ef4SEddie Cai 		memcpy(name, start, len);
145878884ef4SEddie Cai 		printf("path: %s, name: %s\n", path, name);
145978884ef4SEddie Cai 
146078884ef4SEddie Cai }
146178884ef4SEddie Cai 
146278884ef4SEddie Cai static inline bool getFileSize(const char *path, uint32_t* size) {
146378884ef4SEddie Cai 	struct stat st;
146478884ef4SEddie Cai 	if(stat(path, &st) < 0)
146578884ef4SEddie Cai 		return false;
146678884ef4SEddie Cai 	*size = st.st_size;
146778884ef4SEddie Cai 	printf("path: %s, size: %d\n", path, *size);
146878884ef4SEddie Cai 	return true;
146978884ef4SEddie Cai }
147078884ef4SEddie Cai 
147178884ef4SEddie Cai static inline rk_time getTime(void) {
147278884ef4SEddie Cai 	rk_time rkTime;
147378884ef4SEddie Cai 
147478884ef4SEddie Cai 	struct tm *tm;
147578884ef4SEddie Cai 	time_t tt = time(NULL);
147678884ef4SEddie Cai 	tm = localtime(&tt);
147778884ef4SEddie Cai 	rkTime.year = tm->tm_year + 1900;
147878884ef4SEddie Cai 	rkTime.month = tm->tm_mon + 1;
147978884ef4SEddie Cai 	rkTime.day = tm->tm_mday;
148078884ef4SEddie Cai 	rkTime.hour = tm->tm_hour;
148178884ef4SEddie Cai 	rkTime.minute = tm->tm_min;
148278884ef4SEddie Cai 	rkTime.second = tm->tm_sec;
148378884ef4SEddie Cai 	printf("%d-%d-%d %02d:%02d:%02d\n",
148478884ef4SEddie Cai 			rkTime.year, rkTime.month, rkTime.day,
148578884ef4SEddie Cai 			rkTime.hour, rkTime.minute, rkTime.second);
148678884ef4SEddie Cai 	return rkTime;
148778884ef4SEddie Cai }
148878884ef4SEddie Cai 
148978884ef4SEddie Cai static bool writeFile(FILE* outFile, const char* path, bool fix) {
149078884ef4SEddie Cai 	bool ret = false;
149178884ef4SEddie Cai 	uint32_t size = 0, fixSize = 0;
149278884ef4SEddie Cai 	uint8_t* buf;
149378884ef4SEddie Cai 
149478884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
149578884ef4SEddie Cai 	if (!inFile)
149678884ef4SEddie Cai 		goto end;
149778884ef4SEddie Cai 
149878884ef4SEddie Cai 	if (!getFileSize(path, &size))
149978884ef4SEddie Cai 		goto end;
150078884ef4SEddie Cai 	if (fix) {
150178884ef4SEddie Cai 		fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
150278884ef4SEddie Cai 		uint32_t tmp = fixSize % ENTRY_ALIGN;
150378884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
150478884ef4SEddie Cai 		fixSize +=tmp;
150578884ef4SEddie Cai 		memset(gBuf, 0, fixSize);
150678884ef4SEddie Cai 	} else {
150778884ef4SEddie Cai 		memset(gBuf, 0, size+ENTRY_ALIGN);
150878884ef4SEddie Cai 	}
150978884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
151078884ef4SEddie Cai 		goto end;
151178884ef4SEddie Cai 
151278884ef4SEddie Cai 	if (fix) {
151378884ef4SEddie Cai 
151478884ef4SEddie Cai 		buf = gBuf;
151578884ef4SEddie Cai 		size = fixSize;
151678884ef4SEddie Cai 		while(1) {
151778884ef4SEddie Cai 			P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET);
151878884ef4SEddie Cai 			buf += SMALL_PACKET;
151978884ef4SEddie Cai 			if (fixSize <= SMALL_PACKET)
152078884ef4SEddie Cai 				break;
152178884ef4SEddie Cai 			fixSize -= SMALL_PACKET;
152278884ef4SEddie Cai 		}
152378884ef4SEddie Cai 	} else {
152478884ef4SEddie Cai 		uint32_t tmp = size % ENTRY_ALIGN;
152578884ef4SEddie Cai 		tmp = tmp ? (ENTRY_ALIGN - tmp): 0;
152678884ef4SEddie Cai 		size +=tmp;
152778884ef4SEddie Cai 		P_RC4(gBuf, size);
152878884ef4SEddie Cai 	}
152978884ef4SEddie Cai 
153078884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
153178884ef4SEddie Cai 		goto end;
153278884ef4SEddie Cai 	ret = true;
153378884ef4SEddie Cai end:
153478884ef4SEddie Cai 	if (inFile)
153578884ef4SEddie Cai 		fclose(inFile);
153678884ef4SEddie Cai 	if (!ret)
153732268622SAndreas Färber 		printf("writing entry (%s) failed\n", path);
153878884ef4SEddie Cai 	return ret;
153978884ef4SEddie Cai }
154078884ef4SEddie Cai 
154178884ef4SEddie Cai static bool saveEntry(FILE* outFile, char* path, rk_entry_type type,
154278884ef4SEddie Cai 		uint16_t delay, uint32_t* offset, char* fixName, bool fix) {
154378884ef4SEddie Cai 	uint32_t size;
154478884ef4SEddie Cai 	rk_boot_entry entry;
154578884ef4SEddie Cai 
154632268622SAndreas Färber 	printf("writing: %s\n", path);
1547641cfa16SEddie Cai 	memset(&entry, 0, sizeof(rk_boot_entry));
154878884ef4SEddie Cai 	getName(fixName ? fixName: path, entry.name);
154978884ef4SEddie Cai 	entry.size = sizeof(rk_boot_entry);
155078884ef4SEddie Cai 	entry.type = type;
155178884ef4SEddie Cai 	entry.dataOffset = *offset;
155278884ef4SEddie Cai 	if (!getFileSize(path, &size)) {
155332268622SAndreas Färber 		printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path);
155478884ef4SEddie Cai 		return false;
155578884ef4SEddie Cai 	}
155678884ef4SEddie Cai 	if (fix)
155778884ef4SEddie Cai 		size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET;
155878884ef4SEddie Cai 	uint32_t tmp = size % ENTRY_ALIGN;
155978884ef4SEddie Cai 	size += tmp ? (ENTRY_ALIGN - tmp): 0;
156032268622SAndreas Färber 	printf("alignment size: %d\n", size);
156178884ef4SEddie Cai 	entry.dataSize = size;
156278884ef4SEddie Cai 	entry.dataDelay = delay;
156378884ef4SEddie Cai 	*offset += size;
156478884ef4SEddie Cai 	fwrite(&entry, sizeof(rk_boot_entry), 1, outFile);
156578884ef4SEddie Cai 	return true;
156678884ef4SEddie Cai }
156778884ef4SEddie Cai 
156878884ef4SEddie Cai static inline uint32_t convertChipType(const char* chip) {
156978884ef4SEddie Cai 	char buffer[5];
157078884ef4SEddie Cai 	memset(buffer, 0, sizeof(buffer));
157178884ef4SEddie Cai 	snprintf(buffer, sizeof(buffer), "%s", chip);
157278884ef4SEddie Cai 	return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
157378884ef4SEddie Cai }
157478884ef4SEddie Cai 
157578884ef4SEddie Cai static inline uint32_t getChipType(const char* chip) {
157678884ef4SEddie Cai 	printf("chip: %s\n", chip);
157778884ef4SEddie Cai 	int chipType = RKNONE_DEVICE;
157878884ef4SEddie Cai 	if(!chip) {
157978884ef4SEddie Cai 		goto end;
158078884ef4SEddie Cai 	}
158178884ef4SEddie Cai 	if (!strcmp(chip, CHIP_RK28)) {
158278884ef4SEddie Cai 		chipType = RK28_DEVICE;
158378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK28)) {
158478884ef4SEddie Cai 		chipType = RK28_DEVICE;
158578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK281X)) {
158678884ef4SEddie Cai 		chipType = RK281X_DEVICE;
158778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKPANDA)) {
158878884ef4SEddie Cai 		chipType = RKPANDA_DEVICE;
158978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK27)) {
159078884ef4SEddie Cai 		chipType = RK27_DEVICE;
159178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKNANO)) {
159278884ef4SEddie Cai 		chipType = RKNANO_DEVICE;
159378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKSMART)) {
159478884ef4SEddie Cai 		chipType = RKSMART_DEVICE;
159578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCROWN)) {
159678884ef4SEddie Cai 		chipType = RKCROWN_DEVICE;
159778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RKCAYMAN)) {
159878884ef4SEddie Cai 		chipType = RKCAYMAN_DEVICE;
159978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK29)) {
160078884ef4SEddie Cai 		chipType = RK29_DEVICE;
160178884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK292X)) {
160278884ef4SEddie Cai 		chipType = RK292X_DEVICE;
160378884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30)) {
160478884ef4SEddie Cai 		chipType = RK30_DEVICE;
160578884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK30B)) {
160678884ef4SEddie Cai 		chipType = RK30B_DEVICE;
160778884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK31)) {
160878884ef4SEddie Cai 		chipType = RK31_DEVICE;
160978884ef4SEddie Cai 	} else if (!strcmp(chip, CHIP_RK32)) {
161078884ef4SEddie Cai 		chipType = RK32_DEVICE;
161178884ef4SEddie Cai 	} else {
161278884ef4SEddie Cai 		chipType = convertChipType(chip + 2);
161378884ef4SEddie Cai 	}
161478884ef4SEddie Cai 
161578884ef4SEddie Cai end:
161678884ef4SEddie Cai 	printf("type: 0x%x\n", chipType);
161778884ef4SEddie Cai 	if (chipType == RKNONE_DEVICE) {
161832268622SAndreas Färber 		printf("chip type not supported!\n");
161978884ef4SEddie Cai 	}
162078884ef4SEddie Cai 	return chipType;
162178884ef4SEddie Cai }
162278884ef4SEddie Cai 
162378884ef4SEddie Cai static inline void getBoothdr(rk_boot_header* hdr) {
162478884ef4SEddie Cai 	memset(hdr, 0, sizeof(rk_boot_header));
162578884ef4SEddie Cai 	hdr->tag = TAG;
162678884ef4SEddie Cai 	hdr->size = sizeof(rk_boot_header);
162778884ef4SEddie Cai 	hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor);
162878884ef4SEddie Cai 	hdr->mergerVersion = MERGER_VERSION;
162978884ef4SEddie Cai 	hdr->releaseTime = getTime();
163078884ef4SEddie Cai 	hdr->chipType = getChipType(gOpts.chip);
163178884ef4SEddie Cai 
163278884ef4SEddie Cai 	hdr->code471Num = gOpts.code471Num;
163378884ef4SEddie Cai 	hdr->code471Offset = sizeof(rk_boot_header);
163478884ef4SEddie Cai 	hdr->code471Size = sizeof(rk_boot_entry);
163578884ef4SEddie Cai 
163678884ef4SEddie Cai 	hdr->code472Num = gOpts.code472Num;
163778884ef4SEddie Cai 	hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size;
163878884ef4SEddie Cai 	hdr->code472Size = sizeof(rk_boot_entry);
163978884ef4SEddie Cai 
164078884ef4SEddie Cai 	hdr->loaderNum = gOpts.loaderNum;
164178884ef4SEddie Cai 	hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size;
164278884ef4SEddie Cai 	hdr->loaderSize = sizeof(rk_boot_entry);
164378884ef4SEddie Cai #ifndef USE_P_RC4
164478884ef4SEddie Cai 	hdr->rc4Flag = 1;
164578884ef4SEddie Cai #endif
164678884ef4SEddie Cai }
164778884ef4SEddie Cai 
164878884ef4SEddie Cai static inline uint32_t getCrc(const char* path) {
164978884ef4SEddie Cai 	uint32_t size = 0;
165078884ef4SEddie Cai 	uint32_t crc = 0;
165178884ef4SEddie Cai 
165278884ef4SEddie Cai 	FILE* file = fopen(path, "rb");
165378884ef4SEddie Cai 	getFileSize(path, &size);
165478884ef4SEddie Cai 	if (!file)
165578884ef4SEddie Cai 		goto end;
165678884ef4SEddie Cai 	if (!fread(gBuf, size, 1, file))
165778884ef4SEddie Cai 		goto end;
165878884ef4SEddie Cai 	crc = CRC_32(gBuf, size);
165978884ef4SEddie Cai 	printf("crc: 0x%08x\n", crc);
166078884ef4SEddie Cai end:
166178884ef4SEddie Cai 	if (file)
166278884ef4SEddie Cai 		fclose(file);
166378884ef4SEddie Cai 	return crc;
166478884ef4SEddie Cai }
166578884ef4SEddie Cai 
166678884ef4SEddie Cai bool mergeBoot(void) {
166778884ef4SEddie Cai 	uint32_t dataOffset;
166878884ef4SEddie Cai 	bool ret = false;
166978884ef4SEddie Cai 	int i;
167078884ef4SEddie Cai 	FILE* outFile;
167178884ef4SEddie Cai 	uint32_t crc;
167278884ef4SEddie Cai 	rk_boot_header hdr;
167378884ef4SEddie Cai 
167478884ef4SEddie Cai 	if (!initOpts())
167578884ef4SEddie Cai 		return false;
167678884ef4SEddie Cai 	{
167778884ef4SEddie Cai 		char* subfix = strstr(gOpts.outPath, OUT_SUBFIX);
167878884ef4SEddie Cai 		char version[MAX_LINE_LEN];
167978884ef4SEddie Cai 		snprintf(version, sizeof(version), "%s", gSubfix);
168078884ef4SEddie Cai 		if (subfix && !strcmp(subfix, OUT_SUBFIX)) {
168178884ef4SEddie Cai 			subfix[0] = '\0';
168278884ef4SEddie Cai 		}
168378884ef4SEddie Cai 		strcat(gOpts.outPath, version);
168478884ef4SEddie Cai 		printf("fix opt: %s\n", gOpts.outPath);
168578884ef4SEddie Cai 	}
168678884ef4SEddie Cai 
168778884ef4SEddie Cai 	printf("---------------\nUSING CONFIG:\n");
168878884ef4SEddie Cai 	printOpts(stdout);
168978884ef4SEddie Cai 	printf("---------------\n\n");
169078884ef4SEddie Cai 
169178884ef4SEddie Cai 
169278884ef4SEddie Cai 	outFile = fopen(gOpts.outPath, "wb+");
169378884ef4SEddie Cai 	if (!outFile) {
169432268622SAndreas Färber 		printf("Opening output file (%s) failed\n", gOpts.outPath);
169578884ef4SEddie Cai 		goto end;
169678884ef4SEddie Cai 	}
169778884ef4SEddie Cai 
169878884ef4SEddie Cai 	getBoothdr(&hdr);
169932268622SAndreas Färber 	printf("Writing header...\n");
170078884ef4SEddie Cai 	fwrite(&hdr, 1, sizeof(rk_boot_header), outFile);
170178884ef4SEddie Cai 
170278884ef4SEddie Cai 	dataOffset = sizeof(rk_boot_header) +
170378884ef4SEddie Cai 		(gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) *
170478884ef4SEddie Cai 		sizeof(rk_boot_entry);
170578884ef4SEddie Cai 
170632268622SAndreas Färber 	printf("Writing code 471 entry...\n");
170778884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
170878884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep,
170978884ef4SEddie Cai 					&dataOffset, NULL, false))
171078884ef4SEddie Cai 			goto end;
171178884ef4SEddie Cai 	}
171232268622SAndreas Färber 	printf("Writing code 472 entry...\n");
171378884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
171478884ef4SEddie Cai 		if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep,
171578884ef4SEddie Cai 					&dataOffset, NULL, false))
171678884ef4SEddie Cai 			goto end;
171778884ef4SEddie Cai 	}
171832268622SAndreas Färber 	printf("Writing loader entry...\n");
171978884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
172078884ef4SEddie Cai 		if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0,
172178884ef4SEddie Cai 					&dataOffset, gOpts.loader[i].name, true))
172278884ef4SEddie Cai 			goto end;
172378884ef4SEddie Cai 	}
172478884ef4SEddie Cai 
172532268622SAndreas Färber 	printf("Writing code 471...\n");
172678884ef4SEddie Cai 	for (i=0; i<gOpts.code471Num; i++) {
172778884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code471Path[i], false))
172878884ef4SEddie Cai 			goto end;
172978884ef4SEddie Cai 	}
173032268622SAndreas Färber 	printf("Writing code 472...\n");
173178884ef4SEddie Cai 	for (i=0; i<gOpts.code472Num; i++) {
173278884ef4SEddie Cai 		if (!writeFile(outFile, (char*)gOpts.code472Path[i], false))
173378884ef4SEddie Cai 			goto end;
173478884ef4SEddie Cai 	}
173532268622SAndreas Färber 	printf("Writing loader...\n");
173678884ef4SEddie Cai 	for (i=0; i<gOpts.loaderNum; i++) {
173778884ef4SEddie Cai 		if (!writeFile(outFile, gOpts.loader[i].path, true))
173878884ef4SEddie Cai 			goto end;
173978884ef4SEddie Cai 	}
174078884ef4SEddie Cai 	fflush(outFile);
174178884ef4SEddie Cai 
174232268622SAndreas Färber 	printf("Writing crc...\n");
174378884ef4SEddie Cai 	crc = getCrc(gOpts.outPath);
174478884ef4SEddie Cai 	if (!fwrite(&crc, sizeof(crc), 1, outFile))
174578884ef4SEddie Cai 		goto end;
174632268622SAndreas Färber 	printf("Done.\n");
174778884ef4SEddie Cai 	ret = true;
174878884ef4SEddie Cai end:
174978884ef4SEddie Cai 	if (outFile)
175078884ef4SEddie Cai 		fclose(outFile);
175178884ef4SEddie Cai 	return ret;
175278884ef4SEddie Cai }
175378884ef4SEddie Cai 
175478884ef4SEddie Cai /************merge code end************/
175578884ef4SEddie Cai /************unpack code***************/
175678884ef4SEddie Cai 
175778884ef4SEddie Cai static inline void wide2str(const uint16_t* wide, char* str, int len)
175878884ef4SEddie Cai {
175978884ef4SEddie Cai 	int i;
176078884ef4SEddie Cai 	for (i = 0; i < len; i++) {
176178884ef4SEddie Cai 		str[i] = (char) (wide[i] & 0xFF);
176278884ef4SEddie Cai 	}
176378884ef4SEddie Cai }
176478884ef4SEddie Cai 
176578884ef4SEddie Cai static bool unpackEntry(rk_boot_entry* entry, const char* name,
176678884ef4SEddie Cai 		FILE* inFile) {
176778884ef4SEddie Cai 	bool ret = false;
176878884ef4SEddie Cai 	int size, i;
176978884ef4SEddie Cai 	FILE* outFile = fopen(name, "wb+");
177078884ef4SEddie Cai 	if (!outFile)
177178884ef4SEddie Cai 		goto end;
177232268622SAndreas Färber 	printf("unpacking entry (%s)\n", name);
177378884ef4SEddie Cai 	fseek(inFile, entry->dataOffset, SEEK_SET);
177478884ef4SEddie Cai 	size = entry->dataSize;
177578884ef4SEddie Cai 	if (!fread(gBuf, size, 1, inFile))
177678884ef4SEddie Cai 		goto end;
177778884ef4SEddie Cai 	if (entry->type == ENTRY_LOADER) {
177878884ef4SEddie Cai 		for(i=0; i<size/SMALL_PACKET; i++)
177978884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET);
178078884ef4SEddie Cai 		if (size % SMALL_PACKET)
178178884ef4SEddie Cai 		{
178278884ef4SEddie Cai 			P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512);
178378884ef4SEddie Cai 		}
178478884ef4SEddie Cai 	} else {
178578884ef4SEddie Cai 		P_RC4(gBuf, size);
178678884ef4SEddie Cai 	}
178778884ef4SEddie Cai 	if (!fwrite(gBuf, size, 1, outFile))
178878884ef4SEddie Cai 		goto end;
178978884ef4SEddie Cai 	ret = true;
179078884ef4SEddie Cai end:
179178884ef4SEddie Cai 	if (outFile)
179278884ef4SEddie Cai 		fclose(outFile);
179378884ef4SEddie Cai 	return ret;
179478884ef4SEddie Cai }
179578884ef4SEddie Cai 
179678884ef4SEddie Cai bool unpackBoot(char* path) {
179778884ef4SEddie Cai 	bool ret = false;
179878884ef4SEddie Cai 	FILE* inFile = fopen(path, "rb");
179978884ef4SEddie Cai 	int entryNum, i;
180078884ef4SEddie Cai 	char name[MAX_NAME_LEN];
180178884ef4SEddie Cai 	rk_boot_entry* entrys;
180278884ef4SEddie Cai 	if (!inFile) {
180378884ef4SEddie Cai 		fprintf(stderr, "loader (%s) not found\n", path);
180478884ef4SEddie Cai 		goto end;
180578884ef4SEddie Cai 	}
180678884ef4SEddie Cai 
180778884ef4SEddie Cai 	rk_boot_header hdr;
180878884ef4SEddie Cai 	if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) {
180932268622SAndreas Färber 		fprintf(stderr, "reading header failed\n");
181078884ef4SEddie Cai 		goto end;
181178884ef4SEddie Cai 	}
181278884ef4SEddie Cai 	printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum);
181378884ef4SEddie Cai 	entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum;
181478884ef4SEddie Cai 	entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum);
181578884ef4SEddie Cai 	if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) {
181632268622SAndreas Färber 		fprintf(stderr, "reading data failed\n");
181778884ef4SEddie Cai 		goto end;
181878884ef4SEddie Cai 	}
181978884ef4SEddie Cai 
182078884ef4SEddie Cai 	printf("entry num: %d\n", entryNum);
182178884ef4SEddie Cai 	for (i=0; i<entryNum; i++) {
182278884ef4SEddie Cai 		wide2str(entrys[i].name, name, MAX_NAME_LEN);
182378884ef4SEddie Cai 
182478884ef4SEddie Cai 		printf("entry: t=%d, name=%s, off=%d, size=%d\n",
182578884ef4SEddie Cai 				entrys[i].type, name, entrys[i].dataOffset,
182678884ef4SEddie Cai 				entrys[i].dataSize);
182778884ef4SEddie Cai 		if (!unpackEntry(entrys + i, name, inFile)) {
182832268622SAndreas Färber 			fprintf(stderr, "unpacking entry (%s) failed\n", name);
182978884ef4SEddie Cai 			goto end;
183078884ef4SEddie Cai 		}
183178884ef4SEddie Cai 	}
183278884ef4SEddie Cai 	printf("done\n");
183378884ef4SEddie Cai 	ret = true;
183478884ef4SEddie Cai end:
183578884ef4SEddie Cai 	if (inFile)
183678884ef4SEddie Cai 		fclose(inFile);
183778884ef4SEddie Cai 	return ret;
183878884ef4SEddie Cai }
183978884ef4SEddie Cai 
184076af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
184176af099aSliuyi {
184276af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
184376af099aSliuyi 		return false;
184476af099aSliuyi 	CRKImage *pImage = NULL;
184576af099aSliuyi 	CRKBoot *pBoot = NULL;
184676af099aSliuyi 	bool bRet, bSuccess = false;
184776af099aSliuyi 	int iRet;
184876af099aSliuyi 
184976af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
185076af099aSliuyi 	if (!bRet){
185176af099aSliuyi 		ERROR_COLOR_ATTR;
185232268622SAndreas Färber 		printf("Opening loader failed, exiting download boot!");
185376af099aSliuyi 		NORMAL_COLOR_ATTR;
185476af099aSliuyi 		printf("\r\n");
185576af099aSliuyi 		return bSuccess;
185676af099aSliuyi 	} else {
185776af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
185876af099aSliuyi 		CRKComm *pComm = NULL;
185976af099aSliuyi 		CRKDevice *pDevice = NULL;
186076af099aSliuyi 
186176af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
186276af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
186376af099aSliuyi 		if (!bRet) {
186476af099aSliuyi 			if (pImage)
186576af099aSliuyi 				delete pImage;
186676af099aSliuyi 			ERROR_COLOR_ATTR;
186776af099aSliuyi 			printf("Creating Comm Object failed!");
186876af099aSliuyi 			NORMAL_COLOR_ATTR;
186976af099aSliuyi 			printf("\r\n");
187076af099aSliuyi 			return bSuccess;
187176af099aSliuyi 		}
187276af099aSliuyi 
187376af099aSliuyi 		pDevice = new CRKDevice(dev);
187476af099aSliuyi 		if (!pDevice) {
187576af099aSliuyi 			if (pImage)
187676af099aSliuyi 				delete pImage;
187776af099aSliuyi 			if (pComm)
187876af099aSliuyi 				delete pComm;
187976af099aSliuyi 			ERROR_COLOR_ATTR;
188076af099aSliuyi 			printf("Creating device object failed!");
188176af099aSliuyi 			NORMAL_COLOR_ATTR;
188276af099aSliuyi 			printf("\r\n");
188376af099aSliuyi 			return bSuccess;
188476af099aSliuyi 		}
188576af099aSliuyi 
188676af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
188732268622SAndreas Färber 		printf("Downloading bootloader...\r\n");
188876af099aSliuyi 		iRet = pDevice->DownloadBoot();
188976af099aSliuyi 
189076af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
189176af099aSliuyi 		CURSOR_DEL_LINE;
189276af099aSliuyi 		if (iRet == 0) {
189376af099aSliuyi 			bSuccess = true;
189432268622SAndreas Färber 			printf("Downloading bootloader succeeded.\r\n");
189576af099aSliuyi 		}
189676af099aSliuyi 		else
189732268622SAndreas Färber 			printf("Downloading bootloader failed!\r\n");
189876af099aSliuyi 
189976af099aSliuyi 		if (pImage)
190076af099aSliuyi 			delete pImage;
190176af099aSliuyi 		if(pDevice)
190276af099aSliuyi 			delete pDevice;
190376af099aSliuyi 	}
190476af099aSliuyi 	return bSuccess;
190576af099aSliuyi }
1906c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
1907c30d921cSKever Yang {
1908c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
1909c30d921cSKever Yang 		return false;
1910c30d921cSKever Yang 	CRKImage *pImage = NULL;
1911c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
1912c30d921cSKever Yang 	CRKComm *pComm = NULL;
1913c30d921cSKever Yang 	bool bRet, bSuccess = false;
1914c30d921cSKever Yang 	int iRet;
1915aca206f7SPeter Robinson 	signed char index;
1916c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
1917c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
1918c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
1919c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
1920c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
1921c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
1922c30d921cSKever Yang 	PBYTE pIDBData = NULL;
1923c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
1924c30d921cSKever Yang 	if (!bRet){
1925c30d921cSKever Yang 		ERROR_COLOR_ATTR;
192632268622SAndreas Färber 		printf("Opening loader failed, exiting upgrade loader!");
1927c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
1928c30d921cSKever Yang 		printf("\r\n");
1929c30d921cSKever Yang 		goto Exit_UpgradeLoader;
1930c30d921cSKever Yang 	} else {
1931c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
1932c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
1933c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
1934c30d921cSKever Yang 		if (!bRet) {
1935c30d921cSKever Yang 			ERROR_COLOR_ATTR;
1936c30d921cSKever Yang 			printf("Creating Comm Object failed!");
1937c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
1938c30d921cSKever Yang 			printf("\r\n");
1939c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1940c30d921cSKever Yang 		}
1941c30d921cSKever Yang 
194232268622SAndreas Färber 		printf("Upgrading loader...\r\n");
1943c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
1944c30d921cSKever Yang 		if (index == -1) {
1945c30d921cSKever Yang 			if (g_pLogObject) {
194632268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__);
1947c30d921cSKever Yang 			}
1948c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1949c30d921cSKever Yang 		}
1950c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
1951c30d921cSKever Yang 		if (!bRet) {
1952c30d921cSKever Yang 			if (g_pLogObject) {
195332268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__);
1954c30d921cSKever Yang 			}
1955c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1956c30d921cSKever Yang 		}
1957c30d921cSKever Yang 
1958c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
1959c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
1960c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
1961c30d921cSKever Yang 			if (g_pLogObject) {
196232268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__);
1963c30d921cSKever Yang 			}
1964c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1965c30d921cSKever Yang 		}
1966c30d921cSKever Yang 
1967c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
1968c30d921cSKever Yang 		if (index == -1) {
1969c30d921cSKever Yang 			if (g_pLogObject) {
197032268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__);
1971c30d921cSKever Yang 			}
1972c30d921cSKever Yang 			delete []loaderCodeBuffer;
1973c30d921cSKever Yang 			return -4;
1974c30d921cSKever Yang 		}
1975c30d921cSKever Yang 
1976c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
1977c30d921cSKever Yang 		if (!bRet) {
1978c30d921cSKever Yang 			if (g_pLogObject) {
197932268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__);
1980c30d921cSKever Yang 			}
1981c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1982c30d921cSKever Yang 		}
1983c30d921cSKever Yang 
1984c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
1985c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
1986c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
1987c30d921cSKever Yang 			if (g_pLogObject) {
198832268622SAndreas Färber 				g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__);
1989c30d921cSKever Yang 			}
1990c30d921cSKever Yang 			goto Exit_UpgradeLoader;
1991c30d921cSKever Yang 		}
1992c30d921cSKever Yang 
1993c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
1994c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
1995c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
1996c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
1997c30d921cSKever Yang 		if (!pIDBData) {
1998c30d921cSKever Yang 			ERROR_COLOR_ATTR;
199932268622SAndreas Färber 			printf("Allocating memory failed!");
2000c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
2001c30d921cSKever Yang 			printf("\r\n");
2002c30d921cSKever Yang 			goto Exit_UpgradeLoader;
2003c30d921cSKever Yang 		}
2004c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
2005b38fe5fcSliuyi 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag);
2006c30d921cSKever Yang 		if (iRet != 0) {
2007c30d921cSKever Yang 			ERROR_COLOR_ATTR;
200832268622SAndreas Färber 			printf("Making idblock failed!");
2009c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
2010c30d921cSKever Yang 			printf("\r\n");
2011c30d921cSKever Yang 			goto Exit_UpgradeLoader;
2012c30d921cSKever Yang 		}
2013c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
2014c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
2015c30d921cSKever Yang 		CURSOR_DEL_LINE;
2016c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
2017b38fe5fcSliuyi 			//pComm->Reset_Usb_Device();
2018c30d921cSKever Yang 			bSuccess = true;
201932268622SAndreas Färber 			printf("Upgrading loader succeeded.\r\n");
2020c30d921cSKever Yang 		} else {
202132268622SAndreas Färber 			printf("Upgrading loader failed!\r\n");
2022c30d921cSKever Yang 			goto Exit_UpgradeLoader;
2023c30d921cSKever Yang 		}
2024c30d921cSKever Yang 	}
2025c30d921cSKever Yang Exit_UpgradeLoader:
2026c30d921cSKever Yang 	if (pImage)
2027c30d921cSKever Yang 		delete pImage;
2028c30d921cSKever Yang 	if (pComm)
2029c30d921cSKever Yang 		delete pComm;
2030c30d921cSKever Yang 	if (loaderCodeBuffer)
2031c30d921cSKever Yang 		delete []loaderCodeBuffer;
2032c30d921cSKever Yang 	if (loaderDataBuffer)
2033c30d921cSKever Yang 		delete []loaderDataBuffer;
2034c30d921cSKever Yang 	if (pIDBData)
2035c30d921cSKever Yang 		delete []pIDBData;
2036c30d921cSKever Yang 	return bSuccess;
2037c30d921cSKever Yang }
20383dc7e3ceSliuyi bool print_gpt(STRUCT_RKDEVICE_DESC &dev)
20393dc7e3ceSliuyi {
20403dc7e3ceSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
20413dc7e3ceSliuyi 		return false;
20423dc7e3ceSliuyi 	u8 master_gpt[34 * SECTOR_SIZE];
20433dc7e3ceSliuyi 	gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE);
20443dc7e3ceSliuyi 	bool bRet, bSuccess = false;
20453dc7e3ceSliuyi 	int iRet;
20463dc7e3ceSliuyi 	gpt_entry  *gptEntry  = NULL;
20473dc7e3ceSliuyi 	u32 i,j;
20483dc7e3ceSliuyi 	u8 zerobuf[GPT_ENTRY_SIZE];
20493dc7e3ceSliuyi 	memset(zerobuf,0,GPT_ENTRY_SIZE);
20503dc7e3ceSliuyi 	CRKComm *pComm = NULL;
20513dc7e3ceSliuyi 	char partName[36];
20523dc7e3ceSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
20533dc7e3ceSliuyi 	if (!bRet) {
20543dc7e3ceSliuyi 		ERROR_COLOR_ATTR;
20553dc7e3ceSliuyi 		printf("Creating Comm Object failed!");
20563dc7e3ceSliuyi 		NORMAL_COLOR_ATTR;
20573dc7e3ceSliuyi 		printf("\r\n");
20583dc7e3ceSliuyi 		return bSuccess;
20593dc7e3ceSliuyi 	}
20603dc7e3ceSliuyi 	iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt);
20613dc7e3ceSliuyi 	if(ERR_SUCCESS == iRet) {
20623dc7e3ceSliuyi 		if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
20633dc7e3ceSliuyi 			goto Exit_PrintGpt;
20643dc7e3ceSliuyi 		}
20653dc7e3ceSliuyi 
20663dc7e3ceSliuyi 	} else {
20673dc7e3ceSliuyi 		if (g_pLogObject)
20683dc7e3ceSliuyi 				g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
20693dc7e3ceSliuyi 		printf("Read GPT failed!\r\n");
20703dc7e3ceSliuyi 		goto Exit_PrintGpt;
20713dc7e3ceSliuyi 	}
20723dc7e3ceSliuyi 
2073081d237aSliuyi 	printf("**********Partition Info(GPT)**********\r\n");
20743dc7e3ceSliuyi 	printf("NO  LBA       Name                \r\n");
20753dc7e3ceSliuyi 	for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) {
20763dc7e3ceSliuyi 		gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE);
20773dc7e3ceSliuyi 		if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0)
20783dc7e3ceSliuyi 			break;
20793dc7e3ceSliuyi 		memset(partName, 0 , 36);
20803dc7e3ceSliuyi 		j = 0;
20813dc7e3ceSliuyi 		while (gptEntry->partition_name[j]) {
20823dc7e3ceSliuyi 			partName[j] = (char)gptEntry->partition_name[j];
20833dc7e3ceSliuyi 			j++;
20843dc7e3ceSliuyi 		}
20853dc7e3ceSliuyi 		printf("%02d  %08X  %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName);
20863dc7e3ceSliuyi 	}
20873dc7e3ceSliuyi 	bSuccess = true;
20883dc7e3ceSliuyi Exit_PrintGpt:
20893dc7e3ceSliuyi 	if (pComm)
20903dc7e3ceSliuyi 		delete pComm;
20913dc7e3ceSliuyi 	return bSuccess;
20923dc7e3ceSliuyi }
2093081d237aSliuyi bool print_parameter(STRUCT_RKDEVICE_DESC &dev)
2094081d237aSliuyi {
2095081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2096081d237aSliuyi 		return false;
2097081d237aSliuyi 	u8 param_buf[512 * SECTOR_SIZE];
2098081d237aSliuyi 	bool bRet, bSuccess = false;
2099081d237aSliuyi 	int iRet;
2100081d237aSliuyi 	u32 i, nParamSize;
2101081d237aSliuyi 	CRKComm *pComm = NULL;
2102081d237aSliuyi 	PARAM_ITEM_VECTOR vecParamItem;
2103081d237aSliuyi 	CONFIG_ITEM_VECTOR vecUuidItem;
2104081d237aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
2105081d237aSliuyi 	if (!bRet) {
2106081d237aSliuyi 		ERROR_COLOR_ATTR;
2107081d237aSliuyi 		printf("Creating Comm Object failed!");
2108081d237aSliuyi 		NORMAL_COLOR_ATTR;
2109081d237aSliuyi 		printf("\r\n");
2110081d237aSliuyi 		return bSuccess;
2111081d237aSliuyi 	}
2112081d237aSliuyi 	iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf);
2113081d237aSliuyi 	if(ERR_SUCCESS == iRet) {
2114081d237aSliuyi 		if (*(u32 *)param_buf != 0x4D524150) {
2115081d237aSliuyi 			goto Exit_PrintParam;
2116081d237aSliuyi 		}
2117081d237aSliuyi 
2118081d237aSliuyi 	} else {
2119081d237aSliuyi 		if (g_pLogObject)
2120081d237aSliuyi 				g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2121081d237aSliuyi 		printf("Read parameter failed!\r\n");
2122081d237aSliuyi 		goto Exit_PrintParam;
2123081d237aSliuyi 	}
2124081d237aSliuyi 	nParamSize = *(u32 *)(param_buf + 4);
2125081d237aSliuyi 	memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8);
2126081d237aSliuyi 
2127081d237aSliuyi 	bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem);
2128081d237aSliuyi 	if (!bRet) {
2129081d237aSliuyi 		if (g_pLogObject)
2130081d237aSliuyi 				g_pLogObject->Record("Error: parse parameter failed");
2131081d237aSliuyi 		printf("Parse parameter failed!\r\n");
2132081d237aSliuyi 		goto Exit_PrintParam;
2133081d237aSliuyi 	}
2134081d237aSliuyi 	printf("**********Partition Info(parameter)**********\r\n");
2135081d237aSliuyi 	printf("NO  LBA       Name                \r\n");
2136081d237aSliuyi 	for (i = 0; i < vecParamItem.size(); i++) {
2137081d237aSliuyi 		printf("%02d  %08X  %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName);
2138081d237aSliuyi 	}
2139081d237aSliuyi 	bSuccess = true;
2140081d237aSliuyi Exit_PrintParam:
2141081d237aSliuyi 	if (pComm)
2142081d237aSliuyi 		delete pComm;
2143081d237aSliuyi 	return bSuccess;
2144081d237aSliuyi }
2145c30d921cSKever Yang 
214676af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
214776af099aSliuyi {
214876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
214976af099aSliuyi 		return false;
215076af099aSliuyi 	CRKImage *pImage = NULL;
215176af099aSliuyi 	bool bRet, bSuccess = false;
215276af099aSliuyi 	int iRet;
215376af099aSliuyi 	CRKScan *pScan = NULL;
215476af099aSliuyi 	pScan = new CRKScan();
215576af099aSliuyi 	pScan->SetVidPid();
215676af099aSliuyi 
215776af099aSliuyi 	CRKComm *pComm = NULL;
215876af099aSliuyi 	CRKDevice *pDevice = NULL;
215976af099aSliuyi 
216076af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
216176af099aSliuyi 	if (!bRet) {
216276af099aSliuyi 		if (pScan)
216376af099aSliuyi 			delete pScan;
216476af099aSliuyi 		ERROR_COLOR_ATTR;
216576af099aSliuyi 		printf("Creating Comm Object failed!");
216676af099aSliuyi 		NORMAL_COLOR_ATTR;
216776af099aSliuyi 		printf("\r\n");
216876af099aSliuyi 		return bSuccess;
216976af099aSliuyi 	}
217076af099aSliuyi 
217176af099aSliuyi 	pDevice = new CRKDevice(dev);
217276af099aSliuyi 	if (!pDevice) {
217376af099aSliuyi 		if (pComm)
217476af099aSliuyi 			delete pComm;
217576af099aSliuyi 		if (pScan)
217676af099aSliuyi 			delete pScan;
217776af099aSliuyi 		ERROR_COLOR_ATTR;
217876af099aSliuyi 		printf("Creating device object failed!");
217976af099aSliuyi 		NORMAL_COLOR_ATTR;
218076af099aSliuyi 		printf("\r\n");
218176af099aSliuyi 		return bSuccess;
218276af099aSliuyi 	}
218376af099aSliuyi 
218476af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
218576af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
218676af099aSliuyi 
218732268622SAndreas Färber 	printf("Starting to erase flash...\r\n");
21886502326dSliuyi 	bRet = pDevice->GetFlashInfo();
21896502326dSliuyi 	if (!bRet) {
21906502326dSliuyi 		if (pDevice)
21916502326dSliuyi 			delete pDevice;
21926502326dSliuyi 		if (pScan)
21936502326dSliuyi 			delete pScan;
21946502326dSliuyi 		ERROR_COLOR_ATTR;
21956502326dSliuyi 		printf("Getting flash info from device failed!");
21966502326dSliuyi 		NORMAL_COLOR_ATTR;
21976502326dSliuyi 		printf("\r\n");
21986502326dSliuyi 		return bSuccess;
21996502326dSliuyi 	}
220076af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
220176af099aSliuyi 	if (pDevice)
220276af099aSliuyi 		delete pDevice;
220376af099aSliuyi 
220476af099aSliuyi 	if (iRet == 0) {
220576af099aSliuyi 		if (pScan) {
220676af099aSliuyi 			pScan->SetVidPid();
220776af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
220876af099aSliuyi 			delete pScan;
220976af099aSliuyi 		}
221076af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
221176af099aSliuyi 		CURSOR_DEL_LINE;
221276af099aSliuyi 		bSuccess = true;
221332268622SAndreas Färber 		printf("Erasing flash complete.\r\n");
221476af099aSliuyi 	}
221576af099aSliuyi 
221676af099aSliuyi 	return bSuccess;
221776af099aSliuyi }
221876af099aSliuyi 
221976af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
222076af099aSliuyi {
222176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
222276af099aSliuyi 		return false;
222376af099aSliuyi 	CRKUsbComm *pComm = NULL;
222476af099aSliuyi 	bool bRet, bSuccess = false;
222576af099aSliuyi 	int iRet;
222676af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
222776af099aSliuyi 	if (bRet) {
222876af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
222976af099aSliuyi 		if (iRet != ERR_SUCCESS) {
223076af099aSliuyi 			if (g_pLogObject)
223176af099aSliuyi 				g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet);
223232268622SAndreas Färber 			printf("Test Device failed!\r\n");
223376af099aSliuyi 		} else {
223476af099aSliuyi 			bSuccess = true;
223576af099aSliuyi 			printf("Test Device OK.\r\n");
223676af099aSliuyi 		}
223776af099aSliuyi 	} else {
223832268622SAndreas Färber 		printf("Test Device quit, creating comm object failed!\r\n");
223976af099aSliuyi 	}
224076af099aSliuyi 	if (pComm) {
224176af099aSliuyi 		delete pComm;
224276af099aSliuyi 		pComm = NULL;
224376af099aSliuyi 	}
224476af099aSliuyi 	return bSuccess;
224576af099aSliuyi }
224676af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
224776af099aSliuyi {
224876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
224976af099aSliuyi 		return false;
225076af099aSliuyi 	CRKUsbComm *pComm = NULL;
225176af099aSliuyi 	bool bRet, bSuccess = false;
225276af099aSliuyi 	int iRet;
225376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
225476af099aSliuyi 	if (bRet) {
225576af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
225676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
225776af099aSliuyi 			if (g_pLogObject)
225876af099aSliuyi 				g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet);
225932268622SAndreas Färber 			printf("Reset Device failed!\r\n");
226076af099aSliuyi 		} else {
226176af099aSliuyi 			bSuccess = true;
226276af099aSliuyi 			printf("Reset Device OK.\r\n");
226376af099aSliuyi 		}
226476af099aSliuyi 	} else {
226532268622SAndreas Färber 		printf("Reset Device quit, creating comm object failed!\r\n");
226676af099aSliuyi 	}
226776af099aSliuyi 	if (pComm) {
226876af099aSliuyi 		delete pComm;
226976af099aSliuyi 		pComm = NULL;
227076af099aSliuyi 	}
227176af099aSliuyi 	return bSuccess;
227276af099aSliuyi }
227376af099aSliuyi 
227476af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
227576af099aSliuyi {
227676af099aSliuyi 	CRKUsbComm *pComm = NULL;
227776af099aSliuyi 	bool bRet, bSuccess = false;
227876af099aSliuyi 	int iRet;
227976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
228076af099aSliuyi 		return bSuccess;
228176af099aSliuyi 
228276af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
228376af099aSliuyi 	if (bRet) {
228476af099aSliuyi 		BYTE flashID[5];
228576af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
228676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
228776af099aSliuyi 			if (g_pLogObject)
228876af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet);
228932268622SAndreas Färber 			printf("Reading flash ID failed!\r\n");
229076af099aSliuyi 		} else {
229176af099aSliuyi 			printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
229276af099aSliuyi 			bSuccess = true;
229376af099aSliuyi 		}
229476af099aSliuyi 	} else {
229532268622SAndreas Färber 		printf("Read Flash ID quit, creating comm object failed!\r\n");
229676af099aSliuyi 	}
229776af099aSliuyi 	if (pComm) {
229876af099aSliuyi 		delete pComm;
229976af099aSliuyi 		pComm = NULL;
230076af099aSliuyi 	}
230176af099aSliuyi 	return bSuccess;
230276af099aSliuyi }
230376af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
230476af099aSliuyi {
230576af099aSliuyi 	CRKUsbComm *pComm = NULL;
230676af099aSliuyi 	bool bRet, bSuccess = false;
230776af099aSliuyi 	int iRet;
230876af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
230976af099aSliuyi 		return bSuccess;
231076af099aSliuyi 
231176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
231276af099aSliuyi 	if (bRet) {
231376af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
231476af099aSliuyi 		UINT uiRead;
231576af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
231676af099aSliuyi 		if (iRet != ERR_SUCCESS) {
231776af099aSliuyi 			if (g_pLogObject)
231876af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet);
231932268622SAndreas Färber 			printf("Read Flash Info failed!\r\n");
232076af099aSliuyi 		} else {
232176af099aSliuyi 			printf("Flash Info:\r\n");
232276af099aSliuyi 			if (info.bManufCode <= 7) {
232376af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
232476af099aSliuyi 			}
232576af099aSliuyi 			else
232676af099aSliuyi 				printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode);
232776af099aSliuyi 
232876af099aSliuyi 			printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024);
23290dcb0a4cSliuyi 			printf("\tFlash Size: %d Sectors\r\n", info.uiFlashSize);
233076af099aSliuyi 			printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2);
233176af099aSliuyi 			printf("\tPage Size: %d KB\r\n", info.bPageSize / 2);
233276af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
233376af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
233476af099aSliuyi 			printf("\tFlash CS: ");
233576af099aSliuyi 			for(int i = 0; i < 8; i++) {
233676af099aSliuyi 				if( info.bFlashCS & (1 << i) )
233776af099aSliuyi 					printf("Flash<%d> ", i);
233876af099aSliuyi 			}
233976af099aSliuyi 			printf("\r\n");
234076af099aSliuyi 			bSuccess = true;
234176af099aSliuyi 		}
234276af099aSliuyi 	}else {
234332268622SAndreas Färber 		printf("Read Flash Info quit, creating comm object failed!\r\n");
234476af099aSliuyi 	}
234576af099aSliuyi 	if (pComm) {
234676af099aSliuyi 		delete pComm;
234776af099aSliuyi 		pComm = NULL;
234876af099aSliuyi 	}
234976af099aSliuyi 	return bSuccess;
235076af099aSliuyi }
235176af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
235276af099aSliuyi {
235376af099aSliuyi 	CRKUsbComm *pComm = NULL;
235476af099aSliuyi 	bool bRet, bSuccess = false;
235576af099aSliuyi 	int iRet;
235676af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
235776af099aSliuyi 		return bSuccess;
235876af099aSliuyi 
235976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
236076af099aSliuyi 	if (bRet) {
236176af099aSliuyi 		BYTE chipInfo[16];
236276af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
236376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
236476af099aSliuyi 			if (g_pLogObject)
236576af099aSliuyi 				g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet);
236632268622SAndreas Färber 			printf("Read Chip Info failed!\r\n");
236776af099aSliuyi 		} else {
236876af099aSliuyi 			string strChipInfo;
236976af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
237076af099aSliuyi 			printf("Chip Info: %s\r\n", strChipInfo.c_str());
237176af099aSliuyi 			bSuccess = true;
237276af099aSliuyi 		}
237376af099aSliuyi 	} else {
237432268622SAndreas Färber 		printf("Read Chip Info quit, creating comm object failed!\r\n");
237576af099aSliuyi 	}
237676af099aSliuyi 	if (pComm) {
237776af099aSliuyi 		delete pComm;
237876af099aSliuyi 		pComm = NULL;
237976af099aSliuyi 	}
238076af099aSliuyi 	return bSuccess;
238176af099aSliuyi }
2382081d237aSliuyi bool read_capability(STRUCT_RKDEVICE_DESC &dev)
2383081d237aSliuyi {
2384081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2385081d237aSliuyi 	bool bRet, bSuccess = false;
2386081d237aSliuyi 	int iRet;
2387081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2388081d237aSliuyi 		return bSuccess;
2389081d237aSliuyi 
2390081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2391081d237aSliuyi 	if (bRet) {
2392081d237aSliuyi 
2393081d237aSliuyi 		BYTE capability[8];
2394081d237aSliuyi 		iRet = pComm->RKU_ReadCapability(capability);
2395081d237aSliuyi 		if (iRet != ERR_SUCCESS)
2396081d237aSliuyi 		{
2397081d237aSliuyi 			if (g_pLogObject)
2398081d237aSliuyi 				g_pLogObject->Record("Error:read_capability failed,err=%d", iRet);
2399081d237aSliuyi 			printf("Read capability Fail!\r\n");
2400081d237aSliuyi 		} else {
2401081d237aSliuyi 			printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n",
2402081d237aSliuyi 			capability[0], capability[1], capability[2], capability[3],
2403081d237aSliuyi 			capability[4], capability[5], capability[6], capability[7]);
2404081d237aSliuyi 			if (capability[0] & 1)
2405081d237aSliuyi 			{
2406081d237aSliuyi 				printf("Direct LBA:\tenabled\r\n");
2407081d237aSliuyi 			}
2408081d237aSliuyi 
2409081d237aSliuyi 			if (capability[0] & 2)
2410081d237aSliuyi 			{
2411081d237aSliuyi 				printf("Vendor Storage:\tenabled\r\n");
2412081d237aSliuyi 			}
2413081d237aSliuyi 
2414081d237aSliuyi 			if (capability[0] & 4)
2415081d237aSliuyi 			{
2416081d237aSliuyi 				printf("First 4m Access:\tenabled\r\n");
2417081d237aSliuyi 			}
2418081d237aSliuyi 			bSuccess = true;
2419081d237aSliuyi 		}
2420081d237aSliuyi 	} else {
2421081d237aSliuyi 		printf("Read capability quit, creating comm object failed!\r\n");
2422081d237aSliuyi 	}
2423081d237aSliuyi 	if (pComm) {
2424081d237aSliuyi 		delete pComm;
2425081d237aSliuyi 		pComm = NULL;
2426081d237aSliuyi 	}
2427081d237aSliuyi 	return bSuccess;
2428081d237aSliuyi }
2429081d237aSliuyi bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam)
2430081d237aSliuyi {
2431081d237aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
2432081d237aSliuyi 		return false;
2433081d237aSliuyi 	CRKUsbComm *pComm = NULL;
2434081d237aSliuyi 	bool bRet, bSuccess = false;
2435081d237aSliuyi 	int iRet;
2436081d237aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
2437081d237aSliuyi 	if (bRet) {
2438081d237aSliuyi 		iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam);
2439081d237aSliuyi 		if(ERR_SUCCESS == iRet) {
2440081d237aSliuyi 			if (*(u32 *)pParam != 0x4D524150) {
2441081d237aSliuyi 				goto Exit_ReadParam;
2442081d237aSliuyi 			}
2443081d237aSliuyi 		} else {
2444081d237aSliuyi 			if (g_pLogObject)
2445081d237aSliuyi 					g_pLogObject->Record("Error: read parameter failed, err=%d", iRet);
2446081d237aSliuyi 			printf("Read parameter failed!\r\n");
2447081d237aSliuyi 			goto Exit_ReadParam;
2448081d237aSliuyi 		}
2449081d237aSliuyi 		bSuccess = true;
2450081d237aSliuyi 	}
2451081d237aSliuyi Exit_ReadParam:
2452081d237aSliuyi 	if (pComm) {
2453081d237aSliuyi 		delete pComm;
2454081d237aSliuyi 		pComm = NULL;
2455081d237aSliuyi 	}
2456081d237aSliuyi 	return bSuccess;
2457081d237aSliuyi }
2458081d237aSliuyi 
2459081d237aSliuyi 
24606ae612beSliuyi bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt)
24616ae612beSliuyi {
24626ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
24636ae612beSliuyi 		return false;
24646ae612beSliuyi 	gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE);
24656ae612beSliuyi 	CRKUsbComm *pComm = NULL;
24666ae612beSliuyi 	bool bRet, bSuccess = false;
24676ae612beSliuyi 	int iRet;
24686ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
24696ae612beSliuyi 	if (bRet) {
24706ae612beSliuyi 		iRet = pComm->RKU_ReadLBA( 0, 34, pGpt);
24716ae612beSliuyi 		if(ERR_SUCCESS == iRet) {
24726ae612beSliuyi 			if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) {
24736ae612beSliuyi 				goto Exit_ReadGPT;
24746ae612beSliuyi 			}
24756ae612beSliuyi 		} else {
24766ae612beSliuyi 			if (g_pLogObject)
24776ae612beSliuyi 					g_pLogObject->Record("Error: read gpt failed, err=%d", iRet);
24786ae612beSliuyi 			printf("Read GPT failed!\r\n");
24796ae612beSliuyi 			goto Exit_ReadGPT;
24806ae612beSliuyi 		}
24816ae612beSliuyi 		bSuccess = true;
24826ae612beSliuyi 	}
24836ae612beSliuyi Exit_ReadGPT:
24846ae612beSliuyi 	if (pComm) {
24856ae612beSliuyi 		delete pComm;
24866ae612beSliuyi 		pComm = NULL;
24876ae612beSliuyi 	}
24886ae612beSliuyi 	return bSuccess;
24896ae612beSliuyi }
249076af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
249176af099aSliuyi {
249276af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
249376af099aSliuyi 		return false;
249476af099aSliuyi 	CRKUsbComm *pComm = NULL;
249576af099aSliuyi 	FILE *file = NULL;
249676af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
249776af099aSliuyi 	int iRet;
249876af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
249976af099aSliuyi 	int nSectorSize = 512;
250076af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
250176af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
250276af099aSliuyi 	if (bRet) {
250376af099aSliuyi 		if(szFile) {
250476af099aSliuyi 			file = fopen(szFile, "wb+");
250576af099aSliuyi 			if( !file ) {
250676af099aSliuyi 				printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
250776af099aSliuyi 				goto Exit_ReadLBA;
250876af099aSliuyi 			}
250976af099aSliuyi 		}
251076af099aSliuyi 
251176af099aSliuyi 		while(uiLen > 0) {
251276af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
251376af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
251476af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
251576af099aSliuyi 			if(ERR_SUCCESS == iRet) {
251676af099aSliuyi 				uiLen -= iRead;
251776af099aSliuyi 				iTotalRead += iRead;
251876af099aSliuyi 
251976af099aSliuyi 				if(szFile) {
252076af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
252176af099aSliuyi 					if (bFirst){
252276af099aSliuyi 						if (iTotalRead >= 1024)
252332268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
252476af099aSliuyi 						else
252532268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
252676af099aSliuyi 						bFirst = false;
252776af099aSliuyi 					} else {
252876af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
252976af099aSliuyi 						CURSOR_DEL_LINE;
253076af099aSliuyi 						if (iTotalRead >= 1024)
253132268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
253276af099aSliuyi 						else
253332268622SAndreas Färber 							printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
253476af099aSliuyi 					}
253576af099aSliuyi 				}
253676af099aSliuyi 				else
253776af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
253876af099aSliuyi 			} else {
253976af099aSliuyi 				if (g_pLogObject)
254076af099aSliuyi 					g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet);
254176af099aSliuyi 
254276af099aSliuyi 				printf("Read LBA failed!\r\n");
254376af099aSliuyi 				goto Exit_ReadLBA;
254476af099aSliuyi 			}
254576af099aSliuyi 		}
254676af099aSliuyi 		bSuccess = true;
254776af099aSliuyi 	} else {
254832268622SAndreas Färber 		printf("Read LBA quit, creating comm object failed!\r\n");
254976af099aSliuyi 	}
255076af099aSliuyi Exit_ReadLBA:
255176af099aSliuyi 	if (pComm) {
255276af099aSliuyi 		delete pComm;
255376af099aSliuyi 		pComm = NULL;
255476af099aSliuyi 	}
255576af099aSliuyi 	if (file)
255676af099aSliuyi 		fclose(file);
255776af099aSliuyi 	return bSuccess;
255876af099aSliuyi }
25590dcb0a4cSliuyi bool erase_ubi_block(STRUCT_RKDEVICE_DESC &dev, u32 uiOffset, u32 uiPartSize)
25600dcb0a4cSliuyi {
25610dcb0a4cSliuyi 	STRUCT_FLASHINFO_CMD info;
25620dcb0a4cSliuyi 	CRKComm *pComm = NULL;
25630dcb0a4cSliuyi 	BYTE flashID[5];
25640dcb0a4cSliuyi 	bool bRet,bSuccess=false;
25650dcb0a4cSliuyi 	UINT uiReadCount,uiStartBlock,uiEraseBlock,uiBlockCount,uiErasePos;
25660dcb0a4cSliuyi 	int iRet;
25670dcb0a4cSliuyi 	DWORD *pID=NULL;
25681e890c4fSliuyi 
2569*e541b7bbSliuyi 	printf("Erase ubi in, offset=0x%08x,size=0x%08x!\r\n",uiOffset,uiPartSize);
25700dcb0a4cSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
25710dcb0a4cSliuyi 		return false;
25720dcb0a4cSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
25730dcb0a4cSliuyi 	if (!bRet)
25740dcb0a4cSliuyi 	{
25750dcb0a4cSliuyi 		printf("Erase ubi quit, creating comm object failed!\r\n");
25760dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
25770dcb0a4cSliuyi 	}
25780dcb0a4cSliuyi 	iRet = pComm->RKU_ReadFlashID(flashID);
25790dcb0a4cSliuyi 	if(iRet!=ERR_SUCCESS)
25800dcb0a4cSliuyi 	{
25810dcb0a4cSliuyi 		if (g_pLogObject)
25820dcb0a4cSliuyi 		{
25830dcb0a4cSliuyi 			g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashID failed,RetCode(%d)",iRet);
25840dcb0a4cSliuyi 		}
25850dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
25860dcb0a4cSliuyi 	}
25870dcb0a4cSliuyi 	pID = (DWORD *)flashID;
25881e890c4fSliuyi 
25890dcb0a4cSliuyi 	if (*pID==0x434d4d45)//emmc
25900dcb0a4cSliuyi 	{
25910dcb0a4cSliuyi 		bSuccess = true;
25920dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
25930dcb0a4cSliuyi 	}
25940dcb0a4cSliuyi 
25950dcb0a4cSliuyi 	iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info,&uiReadCount);
25960dcb0a4cSliuyi 	if (iRet!=ERR_SUCCESS)
25970dcb0a4cSliuyi 	{
25980dcb0a4cSliuyi 		if (g_pLogObject)
25990dcb0a4cSliuyi 			g_pLogObject->Record("Error:EraseUBIBlock-->RKU_ReadFlashInfo err=%d", iRet);
26000dcb0a4cSliuyi 		goto EXIT_UBI_ERASE;
26010dcb0a4cSliuyi 	}
26020dcb0a4cSliuyi 	if (uiPartSize==0xFFFFFFFF)
26030dcb0a4cSliuyi 		uiPartSize = info.uiFlashSize - uiOffset - (info.usBlockSize * 4);
26040dcb0a4cSliuyi 
26050dcb0a4cSliuyi 	uiStartBlock = uiOffset / info.usBlockSize;
26060dcb0a4cSliuyi 	if ((uiPartSize % info.usBlockSize) == 0)
26070dcb0a4cSliuyi 		uiEraseBlock = uiPartSize / info.usBlockSize;
26080dcb0a4cSliuyi 	else
26090dcb0a4cSliuyi 		uiEraseBlock = uiPartSize / info.usBlockSize + 1;
26100dcb0a4cSliuyi 
2611*e541b7bbSliuyi 	printf("Erase block start, offset=0x%08x,count=0x%08x!\r\n",uiStartBlock,uiEraseBlock);
26120dcb0a4cSliuyi 	uiErasePos=uiStartBlock;
26130dcb0a4cSliuyi 	while (uiEraseBlock>0)
26140dcb0a4cSliuyi 	{
26150dcb0a4cSliuyi 		uiBlockCount = (uiEraseBlock<MAX_ERASE_BLOCKS)?uiEraseBlock:MAX_ERASE_BLOCKS;
26160dcb0a4cSliuyi 
26170dcb0a4cSliuyi 		iRet = pComm->RKU_EraseBlock(0,uiErasePos,uiBlockCount,ERASE_FORCE);
26180dcb0a4cSliuyi 		if ((iRet!=ERR_SUCCESS)&&(iRet!=ERR_FOUND_BAD_BLOCK))
26190dcb0a4cSliuyi 		{
26200dcb0a4cSliuyi 			if (g_pLogObject)
26210dcb0a4cSliuyi 			{
26220dcb0a4cSliuyi 				g_pLogObject->Record("Error:EraseUBIBlock-->RKU_EraseBlock failed,RetCode(%d)",iRet);
26230dcb0a4cSliuyi 			}
26240dcb0a4cSliuyi 			goto EXIT_UBI_ERASE;
26250dcb0a4cSliuyi 		}
26260dcb0a4cSliuyi 
26270dcb0a4cSliuyi 		uiErasePos += uiBlockCount;
26280dcb0a4cSliuyi 		uiEraseBlock -= uiBlockCount;
26290dcb0a4cSliuyi 	}
26300dcb0a4cSliuyi 	bSuccess = true;
26310dcb0a4cSliuyi EXIT_UBI_ERASE:
26320dcb0a4cSliuyi 	if (pComm)
26330dcb0a4cSliuyi 		delete pComm;
26340dcb0a4cSliuyi 	return bSuccess;
26350dcb0a4cSliuyi }
26366ae612beSliuyi bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize)
26376ae612beSliuyi {
2638ae4252f0Sliuyi 	UINT uiErase=1024*32;
26396ae612beSliuyi 	bool bSuccess = true;
26406ae612beSliuyi 	int iRet;
26416ae612beSliuyi 	while (uiSize)
26426ae612beSliuyi 	{
26436ae612beSliuyi 		if (uiSize>=uiErase)
26446ae612beSliuyi 		{
26456ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiErase);
26466ae612beSliuyi 			uiSize -= uiErase;
26476ae612beSliuyi 			uiOffset += uiErase;
26486ae612beSliuyi 		}
26496ae612beSliuyi 		else
26506ae612beSliuyi 		{
26516ae612beSliuyi 			iRet = pComm->RKU_EraseLBA(uiOffset,uiSize);
26526ae612beSliuyi 			uiSize = 0;
26536ae612beSliuyi 			uiOffset += uiSize;
26546ae612beSliuyi 		}
26556ae612beSliuyi 		if (iRet!=ERR_SUCCESS)
26566ae612beSliuyi 		{
26576ae612beSliuyi 			if (g_pLogObject)
26586ae612beSliuyi 			{
26596ae612beSliuyi 				g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet);
26606ae612beSliuyi 			}
26616ae612beSliuyi 			bSuccess = false;
26626ae612beSliuyi 			break;
26636ae612beSliuyi 		}
26646ae612beSliuyi 	}
26656ae612beSliuyi 	return bSuccess;
26666ae612beSliuyi 
26676ae612beSliuyi }
26686ae612beSliuyi bool EatSparseChunk(FILE *file, chunk_header &chunk)
26696ae612beSliuyi {
26706ae612beSliuyi 	UINT uiRead;
26716ae612beSliuyi 	uiRead = fread(&chunk, 1, sizeof(chunk_header), file);
26726ae612beSliuyi 	if (uiRead != sizeof(chunk_header)) {
26736ae612beSliuyi 		if (g_pLogObject)
26746ae612beSliuyi 		{
26756ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno);
26766ae612beSliuyi 		}
26776ae612beSliuyi 		return false;
26786ae612beSliuyi 	}
26796ae612beSliuyi 	return true;
26806ae612beSliuyi }
26816ae612beSliuyi bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize)
26826ae612beSliuyi {
26836ae612beSliuyi 	UINT uiRead;
26846ae612beSliuyi 	uiRead = fread(pBuf, 1, dwSize, file);
26856ae612beSliuyi 	if (uiRead!=dwSize)
26866ae612beSliuyi 	{
26876ae612beSliuyi 		if (g_pLogObject)
26886ae612beSliuyi 		{
26896ae612beSliuyi 			g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno);
26906ae612beSliuyi 		}
26916ae612beSliuyi 		return false;
26926ae612beSliuyi 	}
26936ae612beSliuyi 	return true;
26946ae612beSliuyi }
26956ae612beSliuyi 
26966ae612beSliuyi bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile)
26976ae612beSliuyi {
26986ae612beSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
26996ae612beSliuyi 		return false;
27006ae612beSliuyi 	CRKUsbComm *pComm = NULL;
27016ae612beSliuyi 	FILE *file = NULL;
27026ae612beSliuyi 	bool bRet, bSuccess = false, bFirst = true;
27036ae612beSliuyi 	int iRet;
2704*e541b7bbSliuyi 	u64 iTotalWrite = 0, iFileSize = 0,dwChunkDataSize;
27056ae612beSliuyi 	UINT iRead = 0, uiTransferSec, curChunk, i;
2706*e541b7bbSliuyi 	UINT dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc;
27076ae612beSliuyi 	BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA];
27086ae612beSliuyi 	sparse_header header;
27096ae612beSliuyi 	chunk_header  chunk;
27106ae612beSliuyi 	dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE;
27116ae612beSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
27126ae612beSliuyi 	if (bRet) {
2713ae4252f0Sliuyi 
27146ae612beSliuyi 		file = fopen(szFile, "rb");
27156ae612beSliuyi 		if( !file ) {
27166ae612beSliuyi 			printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile);
27176ae612beSliuyi 			goto Exit_WriteSparseLBA;
27186ae612beSliuyi 		}
27196ae612beSliuyi 		fseeko(file, 0, SEEK_SET);
27206ae612beSliuyi 		iRead = fread(&header, 1, sizeof(header), file);
27216ae612beSliuyi 		if (iRead != sizeof(sparse_header))
27226ae612beSliuyi 		{
27236ae612beSliuyi 			if (g_pLogObject)
27246ae612beSliuyi 			{
27256ae612beSliuyi 				g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno);
27266ae612beSliuyi 			}
27276ae612beSliuyi 			goto Exit_WriteSparseLBA;
27286ae612beSliuyi 		}
27296ae612beSliuyi 		iFileSize = header.blk_sz * (u64)header.total_blks;
27306ae612beSliuyi 		iTotalWrite = 0;
27316ae612beSliuyi 		curChunk = 0;
2732ae4252f0Sliuyi 		if (uiSize==(u32)-1)
2733ae4252f0Sliuyi 			uiSize = ALIGN(iFileSize, SECTOR_SIZE);
2734ae4252f0Sliuyi 		bRet = erase_partition(pComm, uiBegin, uiSize);
2735ae4252f0Sliuyi 		if (!bRet) {
2736ae4252f0Sliuyi 			printf("%s failed, erase partition error\r\n", __func__);
2737ae4252f0Sliuyi 			goto Exit_WriteSparseLBA;
2738ae4252f0Sliuyi 		}
27396ae612beSliuyi 		while(curChunk < header.total_chunks)
27406ae612beSliuyi 		{
27416ae612beSliuyi 			if (!EatSparseChunk(file, chunk)) {
27426ae612beSliuyi 				goto Exit_WriteSparseLBA;
27436ae612beSliuyi 			}
27446ae612beSliuyi 			curChunk++;
27456ae612beSliuyi 			switch (chunk.chunk_type) {
27466ae612beSliuyi 			case CHUNK_TYPE_RAW:
27476ae612beSliuyi 				dwChunkDataSize = chunk.total_sz - sizeof(chunk_header);
27486ae612beSliuyi 				while (dwChunkDataSize) {
27496ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
27506ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
27516ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
27526ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
27536ae612beSliuyi 					} else {
27546ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
27556ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
27566ae612beSliuyi 					}
27576ae612beSliuyi 					if (!EatSparseData(file, pBuf, dwTransferBytes)) {
27586ae612beSliuyi 						goto Exit_WriteSparseLBA;
27596ae612beSliuyi 					}
27606ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
27616ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
27626ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
27636ae612beSliuyi 						iTotalWrite += dwTransferBytes;
27646ae612beSliuyi 						uiBegin += uiTransferSec;
27656ae612beSliuyi 					} else {
27666ae612beSliuyi 						if (g_pLogObject) {
27676ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)",  __func__, iTotalWrite, iRet);
27686ae612beSliuyi 						}
27696ae612beSliuyi 						goto Exit_WriteSparseLBA;
27706ae612beSliuyi 					}
27716ae612beSliuyi 					if (bFirst) {
27726ae612beSliuyi 						if (iTotalWrite >= 1024)
27736ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27746ae612beSliuyi 						else
27756ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
27766ae612beSliuyi 						bFirst = false;
27776ae612beSliuyi 					} else {
27786ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
27796ae612beSliuyi 						CURSOR_DEL_LINE;
27806ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
27816ae612beSliuyi 					}
27826ae612beSliuyi 				}
27836ae612beSliuyi 				break;
27846ae612beSliuyi 			case CHUNK_TYPE_FILL:
2785*e541b7bbSliuyi 				dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz;
27866ae612beSliuyi 				if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) {
27876ae612beSliuyi 					goto Exit_WriteSparseLBA;
27886ae612beSliuyi 				}
27896ae612beSliuyi 				while (dwChunkDataSize) {
27906ae612beSliuyi 					memset(pBuf, 0, dwMaxReadWriteBytes);
27916ae612beSliuyi 					if (dwChunkDataSize >= dwMaxReadWriteBytes) {
27926ae612beSliuyi 						dwTransferBytes = dwMaxReadWriteBytes;
27936ae612beSliuyi 						uiTransferSec = DEFAULT_RW_LBA;
27946ae612beSliuyi 					} else {
27956ae612beSliuyi 						dwTransferBytes = dwChunkDataSize;
27966ae612beSliuyi 						uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1));
27976ae612beSliuyi 					}
27986ae612beSliuyi 					for (i = 0; i < dwTransferBytes / 4; i++) {
27996ae612beSliuyi 						*(DWORD *)(pBuf + i * 4) = dwFillByte;
28006ae612beSliuyi 					}
28016ae612beSliuyi 					iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf);
28026ae612beSliuyi 					if( ERR_SUCCESS == iRet ) {
28036ae612beSliuyi 						dwChunkDataSize -= dwTransferBytes;
28046ae612beSliuyi 						iTotalWrite += dwTransferBytes;
28056ae612beSliuyi 						uiBegin += uiTransferSec;
28066ae612beSliuyi 					} else {
28076ae612beSliuyi 						if (g_pLogObject) {
28086ae612beSliuyi 							g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet);
28096ae612beSliuyi 						}
28106ae612beSliuyi 						goto Exit_WriteSparseLBA;
28116ae612beSliuyi 					}
28126ae612beSliuyi 					if (bFirst) {
28136ae612beSliuyi 						if (iTotalWrite >= 1024)
28146ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28156ae612beSliuyi 						else
28166ae612beSliuyi 							printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
28176ae612beSliuyi 						bFirst = false;
28186ae612beSliuyi 					} else {
28196ae612beSliuyi 						CURSOR_MOVEUP_LINE(1);
28206ae612beSliuyi 						CURSOR_DEL_LINE;
28216ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28226ae612beSliuyi 					}
28236ae612beSliuyi 				}
28246ae612beSliuyi 				break;
28256ae612beSliuyi 			case CHUNK_TYPE_DONT_CARE:
2826*e541b7bbSliuyi 				dwChunkDataSize = (u64)chunk.chunk_sz * header.blk_sz;
28276ae612beSliuyi 				iTotalWrite += dwChunkDataSize;
28286ae612beSliuyi 				uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1));
28296ae612beSliuyi 				uiBegin += uiTransferSec;
28306ae612beSliuyi 				if (bFirst) {
28316ae612beSliuyi 					if (iTotalWrite >= 1024)
28326ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28336ae612beSliuyi 					else
28346ae612beSliuyi 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
28356ae612beSliuyi 					bFirst = false;
28366ae612beSliuyi 				} else {
28376ae612beSliuyi 					CURSOR_MOVEUP_LINE(1);
28386ae612beSliuyi 					CURSOR_DEL_LINE;
28396ae612beSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
28406ae612beSliuyi 				}
28416ae612beSliuyi 				break;
28426ae612beSliuyi 			case CHUNK_TYPE_CRC32:
28436ae612beSliuyi 				EatSparseData(file,(PBYTE)&dwCrc,4);
28446ae612beSliuyi 				break;
28456ae612beSliuyi 			}
28466ae612beSliuyi 		}
28476ae612beSliuyi 		bSuccess = true;
28486ae612beSliuyi 	} else {
28496ae612beSliuyi 		printf("Write LBA quit, creating comm object failed!\r\n");
28506ae612beSliuyi 	}
28516ae612beSliuyi Exit_WriteSparseLBA:
28526ae612beSliuyi 	if (pComm) {
28536ae612beSliuyi 		delete pComm;
28546ae612beSliuyi 		pComm = NULL;
28556ae612beSliuyi 	}
28566ae612beSliuyi 	if (file)
28576ae612beSliuyi 		fclose(file);
28586ae612beSliuyi 	return bSuccess;
28596ae612beSliuyi 
28606ae612beSliuyi }
28616ae612beSliuyi 
286276af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
286376af099aSliuyi {
286476af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
286576af099aSliuyi 		return false;
286676af099aSliuyi 	CRKUsbComm *pComm = NULL;
286776af099aSliuyi 	FILE *file = NULL;
286876af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
286976af099aSliuyi 	int iRet;
287076af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
287176af099aSliuyi 	UINT iWrite = 0, iRead = 0;
287276af099aSliuyi 	UINT uiLen;
287376af099aSliuyi 	int nSectorSize = 512;
287476af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
287576af099aSliuyi 
28760dcb0a4cSliuyi 
287776af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
287876af099aSliuyi 	if (bRet) {
287976af099aSliuyi 		file = fopen(szFile, "rb");
288076af099aSliuyi 		if( !file ) {
288176af099aSliuyi 			printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile);
288276af099aSliuyi 			goto Exit_WriteLBA;
288376af099aSliuyi 		}
288476af099aSliuyi 
288576af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
288676af099aSliuyi 		iFileSize = ftello(file);
288776af099aSliuyi 		fseeko(file, 0, SEEK_SET);
288876af099aSliuyi 		while(iTotalWrite < iFileSize) {
288976af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
289076af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
289176af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
289276af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
289376af099aSliuyi 			if(ERR_SUCCESS == iRet) {
289476af099aSliuyi 				uiBegin += uiLen;
289576af099aSliuyi 				iTotalWrite += iWrite;
289676af099aSliuyi 				if (bFirst) {
289776af099aSliuyi 					if (iTotalWrite >= 1024)
289876af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
289976af099aSliuyi 					else
290032268622SAndreas Färber 						printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize);
290176af099aSliuyi 					bFirst = false;
290276af099aSliuyi 				} else {
290376af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
290476af099aSliuyi 					CURSOR_DEL_LINE;
290576af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
290676af099aSliuyi 				}
290776af099aSliuyi 			} else {
290876af099aSliuyi 				if (g_pLogObject)
290976af099aSliuyi 					g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet);
291076af099aSliuyi 
291176af099aSliuyi 				printf("Write LBA failed!\r\n");
291276af099aSliuyi 				goto Exit_WriteLBA;
291376af099aSliuyi 			}
291476af099aSliuyi 		}
291576af099aSliuyi 		bSuccess = true;
291676af099aSliuyi 	} else {
291732268622SAndreas Färber 		printf("Write LBA quit, creating comm object failed!\r\n");
291876af099aSliuyi 	}
291976af099aSliuyi Exit_WriteLBA:
292076af099aSliuyi 	if (pComm) {
292176af099aSliuyi 		delete pComm;
292276af099aSliuyi 		pComm = NULL;
292376af099aSliuyi 	}
292476af099aSliuyi 	if (file)
292576af099aSliuyi 		fclose(file);
292676af099aSliuyi 	return bSuccess;
292776af099aSliuyi }
292876af099aSliuyi 
292976af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
293076af099aSliuyi {
293176af099aSliuyi 	string strItem;
293276af099aSliuyi 	char szItem[100];
293376af099aSliuyi 	char *pos = NULL, *pStart;
293476af099aSliuyi 	pStart = pszItems;
293576af099aSliuyi 	pos = strchr(pStart, ',');
293676af099aSliuyi 	while(pos != NULL) {
293702bc7763SChristoph Muellner 		memset(szItem, 0, sizeof(szItem));
293876af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
293976af099aSliuyi 		strItem = szItem;
294076af099aSliuyi 		vecItems.push_back(strItem);
294176af099aSliuyi 		pStart = pos + 1;
294276af099aSliuyi 		if (*pStart == 0)
294376af099aSliuyi 			break;
294476af099aSliuyi 		pos = strchr(pStart, ',');
294576af099aSliuyi 	}
294676af099aSliuyi 	if (strlen(pStart) > 0) {
294702bc7763SChristoph Muellner 		memset(szItem, 0, sizeof(szItem));
294802bc7763SChristoph Muellner 		strncpy(szItem, pStart, sizeof(szItem)-1);
294976af099aSliuyi 		strItem = szItem;
295076af099aSliuyi 		vecItems.push_back(strItem);
295176af099aSliuyi 	}
295276af099aSliuyi }
2953c30d921cSKever Yang 
2954d71e8c20SEddie Cai void tag_spl(char *tag, char *spl)
2955d71e8c20SEddie Cai {
2956d71e8c20SEddie Cai 	FILE *file = NULL;
2957d71e8c20SEddie Cai 	int len;
2958d71e8c20SEddie Cai 
2959d71e8c20SEddie Cai 	if(!tag || !spl)
2960d71e8c20SEddie Cai 		return;
2961d71e8c20SEddie Cai 	len = strlen(tag);
2962d71e8c20SEddie Cai 	printf("tag len=%d\n",len);
2963d71e8c20SEddie Cai 	file = fopen(spl, "rb");
2964d71e8c20SEddie Cai 	if( !file ){
2965d71e8c20SEddie Cai 		return;
2966d71e8c20SEddie Cai 	}
2967d71e8c20SEddie Cai 	int iFileSize;
2968d71e8c20SEddie Cai 	fseek(file, 0, SEEK_END);
2969d71e8c20SEddie Cai 	iFileSize = ftell(file);
2970d71e8c20SEddie Cai 	fseek(file, 0, SEEK_SET);
2971d71e8c20SEddie Cai 	char *Buf = NULL;
2972d71e8c20SEddie Cai 	Buf = new char[iFileSize + len + 1];
2973d71e8c20SEddie Cai 	if (!Buf){
2974d71e8c20SEddie Cai 		fclose(file);
2975d71e8c20SEddie Cai 		return;
2976d71e8c20SEddie Cai 	}
2977d71e8c20SEddie Cai 	memset(Buf, 0, iFileSize + 1);
2978d71e8c20SEddie Cai 	memcpy(Buf, tag, len);
2979d71e8c20SEddie Cai 	int iRead;
2980d71e8c20SEddie Cai 	iRead = fread(Buf+len, 1, iFileSize, file);
2981d71e8c20SEddie Cai 	if (iRead != iFileSize){
2982d71e8c20SEddie Cai 		fclose(file);
2983d71e8c20SEddie Cai 		delete []Buf;
2984d71e8c20SEddie Cai 		return;
2985d71e8c20SEddie Cai 	}
2986d71e8c20SEddie Cai 	fclose(file);
2987d71e8c20SEddie Cai 
2988d71e8c20SEddie Cai 	len = strlen(spl);
298932268622SAndreas Färber 	char *taggedspl = new char[len + 5];
299032268622SAndreas Färber 	strcpy(taggedspl, spl);
299132268622SAndreas Färber 	strcpy(taggedspl + len, ".tag");
299232268622SAndreas Färber 	taggedspl[len+4] = 0;
299332268622SAndreas Färber 	printf("Writing tagged spl to %s\n", taggedspl);
2994d71e8c20SEddie Cai 
299532268622SAndreas Färber 	file = fopen(taggedspl, "wb");
2996d71e8c20SEddie Cai 	if( !file ){
299732268622SAndreas Färber 		delete []taggedspl;
2998d71e8c20SEddie Cai 		delete []Buf;
2999d71e8c20SEddie Cai 		return;
3000d71e8c20SEddie Cai 	}
3001d71e8c20SEddie Cai 	fwrite(Buf, 1, iFileSize+len, file);
3002d71e8c20SEddie Cai 	fclose(file);
300332268622SAndreas Färber 	delete []taggedspl;
3004d71e8c20SEddie Cai 	delete []Buf;
3005d71e8c20SEddie Cai 	printf("done\n");
3006d71e8c20SEddie Cai 	return;
3007d71e8c20SEddie Cai }
3008081d237aSliuyi void list_device(CRKScan *pScan)
3009081d237aSliuyi {
3010081d237aSliuyi 	STRUCT_RKDEVICE_DESC desc;
3011081d237aSliuyi 	string strDevType;
3012081d237aSliuyi 	int i,cnt;
3013081d237aSliuyi 	cnt = pScan->DEVICE_COUNTS;
3014081d237aSliuyi 	if (cnt == 0) {
3015081d237aSliuyi 		printf("not found any devices!\r\n");
3016081d237aSliuyi 		return;
3017081d237aSliuyi 	}
3018081d237aSliuyi 	for (i=0;i<cnt;i++)
3019081d237aSliuyi 	{
3020081d237aSliuyi 		pScan->GetDevice(desc, i);
3021081d237aSliuyi 		if (desc.emUsbType==RKUSB_MASKROM)
3022081d237aSliuyi 			strDevType = "Maskrom";
3023081d237aSliuyi 		else if (desc.emUsbType==RKUSB_LOADER)
3024081d237aSliuyi 			strDevType = "Loader";
3025081d237aSliuyi 		else
3026081d237aSliuyi 			strDevType = "Unknown";
3027081d237aSliuyi 		printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid,
3028081d237aSliuyi 		       desc.usPid,desc.uiLocationID,strDevType.c_str());
3029081d237aSliuyi 	}
3030081d237aSliuyi 
3031081d237aSliuyi }
3032081d237aSliuyi 
3033d71e8c20SEddie Cai 
303476af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
303576af099aSliuyi {
303676af099aSliuyi 	string strCmd;
303776af099aSliuyi 	strCmd = argv[1];
303876af099aSliuyi 	ssize_t cnt;
303976af099aSliuyi 	bool bRet,bSuccess = false;
30408df2d64aSEddie Cai 	char *s;
30418df2d64aSEddie Cai 	int i, ret;
304276af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
3043081d237aSliuyi 	u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE];
30446ae612beSliuyi 	u64 lba, lba_end;
3045081d237aSliuyi 	u32 part_size, part_offset;
304676af099aSliuyi 
304776af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
30488df2d64aSEddie Cai 	s = (char*)strCmd.c_str();
30498df2d64aSEddie Cai 	for(i = 0; i < (int)strlen(s); i++)
30508df2d64aSEddie Cai 	        s[i] = toupper(s[i]);
305178884ef4SEddie Cai 
30528df2d64aSEddie Cai 	if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){
305376af099aSliuyi 		usage();
305476af099aSliuyi 		return true;
30558df2d64aSEddie Cai 	} else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) {
3056c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
305776af099aSliuyi 		return true;
305878884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader
305978884ef4SEddie Cai 		mergeBoot();
306078884ef4SEddie Cai 		return true;
306178884ef4SEddie Cai 	} else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader
306278884ef4SEddie Cai 		string strLoader = argv[2];
306378884ef4SEddie Cai 		unpackBoot((char*)strLoader.c_str());
306478884ef4SEddie Cai 		return true;
3065d71e8c20SEddie Cai 	} else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl
3066d71e8c20SEddie Cai 		if (argc == 4) {
3067d71e8c20SEddie Cai 			string tag = argv[2];
3068d71e8c20SEddie Cai 			string spl = argv[3];
3069d71e8c20SEddie Cai 			printf("tag %s to %s\n", tag.c_str(), spl.c_str());
3070d71e8c20SEddie Cai 			tag_spl((char*)tag.c_str(), (char*)spl.c_str());
3071d71e8c20SEddie Cai 			return true;
3072d71e8c20SEddie Cai 		}
3073d71e8c20SEddie Cai 		printf("tagspl: parameter error\n");
3074d71e8c20SEddie Cai 		usage();
307576af099aSliuyi 	}
307676af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
3077081d237aSliuyi 	if(strcmp(strCmd.c_str(), "LD") == 0) {
3078081d237aSliuyi 		list_device(pScan);
30790dcb0a4cSliuyi 		return (cnt>0)?true:false;
3080081d237aSliuyi 	}
3081081d237aSliuyi 
308276af099aSliuyi 	if (cnt < 1) {
308376af099aSliuyi 		ERROR_COLOR_ATTR;
308432268622SAndreas Färber 		printf("Did not find any rockusb device, please plug device in!");
308576af099aSliuyi 		NORMAL_COLOR_ATTR;
308676af099aSliuyi 		printf("\r\n");
308776af099aSliuyi 		return bSuccess;
308876af099aSliuyi 	} else if (cnt > 1) {
308976af099aSliuyi 		ERROR_COLOR_ATTR;
309032268622SAndreas Färber 		printf("Found too many rockusb devices, please plug devices out!");
309176af099aSliuyi 		NORMAL_COLOR_ATTR;
309276af099aSliuyi 		printf("\r\n");
309376af099aSliuyi 		return bSuccess;
309476af099aSliuyi 	}
309576af099aSliuyi 
309676af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
309776af099aSliuyi 	if (!bRet) {
309876af099aSliuyi 		ERROR_COLOR_ATTR;
309932268622SAndreas Färber 		printf("Getting information about rockusb device failed!");
310076af099aSliuyi 		NORMAL_COLOR_ATTR;
310176af099aSliuyi 		printf("\r\n");
310276af099aSliuyi 		return bSuccess;
310376af099aSliuyi 	}
310476af099aSliuyi 
310576af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
310676af099aSliuyi 		if ((argc != 2) && (argc != 3))
310776af099aSliuyi 			printf("Parameter of [RD] command is invalid, please check help!\r\n");
310876af099aSliuyi 		else {
310976af099aSliuyi 			if (argc == 2)
311076af099aSliuyi 				bSuccess = reset_device(dev);
311176af099aSliuyi 			else {
311276af099aSliuyi 				UINT uiSubCode;
311376af099aSliuyi 				char *pszEnd;
311476af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
311576af099aSliuyi 				if (*pszEnd)
311676af099aSliuyi 					printf("Subcode is invalid, please check!\r\n");
311776af099aSliuyi 				else {
311876af099aSliuyi 					if (uiSubCode <= 5)
311976af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
312076af099aSliuyi 					else
312176af099aSliuyi 						printf("Subcode is invalid, please check!\r\n");
312276af099aSliuyi 				}
312376af099aSliuyi 			}
312476af099aSliuyi 		}
312576af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
312676af099aSliuyi 		bSuccess = test_device(dev);
312776af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
312876af099aSliuyi 		bSuccess = read_flash_id(dev);
312976af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
313076af099aSliuyi 		bSuccess = read_flash_info(dev);
313176af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
313276af099aSliuyi 		bSuccess = read_chip_info(dev);
3133081d237aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability
3134081d237aSliuyi 		bSuccess = read_capability(dev);
313576af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
313676af099aSliuyi 		if (argc > 2) {
313776af099aSliuyi 			string strLoader;
313876af099aSliuyi 			strLoader = argv[2];
313976af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
314076af099aSliuyi 		} else if (argc == 2) {
3141c29e5f0fSliuyi 			ret = find_config_item(g_ConfigItemVec, "loader");
314276af099aSliuyi 			if (ret == -1)
314332268622SAndreas Färber 				printf("Did not find loader item in config!\r\n");
314476af099aSliuyi 			else
314576af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
314676af099aSliuyi 		} else
314776af099aSliuyi 			printf("Parameter of [DB] command is invalid, please check help!\r\n");
3148c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
3149c30d921cSKever Yang 		if (argc > 2) {
3150c30d921cSKever Yang 			string strParameter;
3151c30d921cSKever Yang 			strParameter = argv[2];
3152c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
3153c30d921cSKever Yang 		} else
3154c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid, please check help!\r\n");
3155081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PRM") == 0) {
3156081d237aSliuyi 		if (argc > 2) {
3157081d237aSliuyi 			string strParameter;
3158081d237aSliuyi 			strParameter = argv[2];
3159081d237aSliuyi 			bSuccess = write_parameter(dev, (char *)strParameter.c_str());
3160081d237aSliuyi 		} else
3161081d237aSliuyi 			printf("Parameter of [PRM] command is invalid, please check help!\r\n");
3162c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
3163c30d921cSKever Yang 		if (argc > 2) {
3164c30d921cSKever Yang 			string strLoader;
3165c30d921cSKever Yang 			strLoader = argv[2];
3166c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
3167c30d921cSKever Yang 		} else
3168c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid, please check help!\r\n");
316976af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
317076af099aSliuyi 		if (argc == 2) {
317176af099aSliuyi 			bSuccess = erase_flash(dev);
317276af099aSliuyi 		} else
317376af099aSliuyi 			printf("Parameter of [EF] command is invalid, please check help!\r\n");
317476af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
317576af099aSliuyi 		if (argc == 4) {
317676af099aSliuyi 			UINT uiBegin;
317776af099aSliuyi 			char *pszEnd;
317876af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
317976af099aSliuyi 			if (*pszEnd)
318076af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
3181ae4252f0Sliuyi 			else {
3182ae4252f0Sliuyi 				if (is_sparse_image(argv[3]))
3183ae4252f0Sliuyi 						bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]);
31840dcb0a4cSliuyi 				else {
31850dcb0a4cSliuyi 					bSuccess = true;
31860dcb0a4cSliuyi 					if (is_ubifs_image(argv[3]))
31870dcb0a4cSliuyi 						bSuccess = erase_ubi_block(dev, (u32)uiBegin, (u32)-1);
31880dcb0a4cSliuyi 					if (bSuccess)
3189ae4252f0Sliuyi 						bSuccess = write_lba(dev, (u32)uiBegin, argv[3]);
31900dcb0a4cSliuyi 					else
31910dcb0a4cSliuyi 						printf("Failure of Erase for writing ubi image!\r\n");
31920dcb0a4cSliuyi 				}
3193ae4252f0Sliuyi 			}
319476af099aSliuyi 		} else
319576af099aSliuyi 			printf("Parameter of [WL] command is invalid, please check help!\r\n");
31966ae612beSliuyi 	} else if(strcmp(strCmd.c_str(), "WLX") == 0) {
31976ae612beSliuyi 		if (argc == 4) {
31986ae612beSliuyi 			bRet = read_gpt(dev, master_gpt);
31996ae612beSliuyi 			if (bRet) {
32006ae612beSliuyi 				bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end);
32016ae612beSliuyi 				if (bRet) {
32026ae612beSliuyi 					if (is_sparse_image(argv[3]))
32036ae612beSliuyi 						bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]);
32040dcb0a4cSliuyi 					else {
32050dcb0a4cSliuyi 						bSuccess = true;
32060dcb0a4cSliuyi 						if (is_ubifs_image(argv[3]))
32070dcb0a4cSliuyi 							bSuccess = erase_ubi_block(dev, (u32)lba, (u32)(lba_end - lba + 1));
32080dcb0a4cSliuyi 						if (bSuccess)
32096ae612beSliuyi 							bSuccess = write_lba(dev, (u32)lba, argv[3]);
32100dcb0a4cSliuyi 						else
32110dcb0a4cSliuyi 							printf("Failure of Erase for writing ubi image!\r\n");
32120dcb0a4cSliuyi 					}
32136ae612beSliuyi 				} else
32146ae612beSliuyi 					printf("No found %s partition\r\n", argv[2]);
3215081d237aSliuyi 			} else {
3216081d237aSliuyi 				bRet = read_param(dev, param_buffer);
3217081d237aSliuyi 				if (bRet) {
3218081d237aSliuyi 					bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size);
3219081d237aSliuyi 					if (bRet) {
3220081d237aSliuyi 						if (is_sparse_image(argv[3]))
3221081d237aSliuyi 							bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]);
32220dcb0a4cSliuyi 						else {
32231e890c4fSliuyi 
32240dcb0a4cSliuyi 							bSuccess = true;
32250dcb0a4cSliuyi 							if (is_ubifs_image(argv[3]))
32260dcb0a4cSliuyi 								bSuccess = erase_ubi_block(dev, part_offset, part_size);
32270dcb0a4cSliuyi 							if (bSuccess)
3228081d237aSliuyi 								bSuccess = write_lba(dev, part_offset, argv[3]);
32290dcb0a4cSliuyi 							else
32300dcb0a4cSliuyi 								printf("Failure of Erase for writing ubi image!\r\n");
32310dcb0a4cSliuyi 						}
3232081d237aSliuyi 					} else
3233081d237aSliuyi 						printf("No found %s partition\r\n", argv[2]);
32346ae612beSliuyi 				}
3235081d237aSliuyi 				else
3236081d237aSliuyi 					printf("Not found any partition table!\r\n");
3237081d237aSliuyi 			}
3238081d237aSliuyi 
32396ae612beSliuyi 		} else
32406ae612beSliuyi 			printf("Parameter of [WLX] command is invalid, please check help!\r\n");
324176af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
324276af099aSliuyi 		char *pszEnd;
324376af099aSliuyi 		UINT uiBegin, uiLen;
324476af099aSliuyi 		if (argc != 5)
324576af099aSliuyi 			printf("Parameter of [RL] command is invalid, please check help!\r\n");
324676af099aSliuyi 		else {
324776af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
324876af099aSliuyi 			if (*pszEnd)
324976af099aSliuyi 				printf("Begin is invalid, please check!\r\n");
325076af099aSliuyi 			else {
325176af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
325276af099aSliuyi 				if (*pszEnd)
325376af099aSliuyi 					printf("Len is invalid, please check!\r\n");
325476af099aSliuyi 				else {
325576af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
325676af099aSliuyi 				}
325776af099aSliuyi 			}
325876af099aSliuyi 		}
3259081d237aSliuyi 	} else if(strcmp(strCmd.c_str(), "PPT") == 0) {
32603dc7e3ceSliuyi 		if (argc == 2) {
32613dc7e3ceSliuyi 			bSuccess = print_gpt(dev);
3262081d237aSliuyi 			if (!bSuccess) {
3263081d237aSliuyi 				bSuccess = print_parameter(dev);
3264081d237aSliuyi 				if (!bSuccess)
3265081d237aSliuyi 					printf("Not found any partition table!\r\n");
3266081d237aSliuyi 			}
32673dc7e3ceSliuyi 		} else
3268081d237aSliuyi 			printf("Parameter of [PPT] command is invalid, please check help!\r\n");
326976af099aSliuyi 	} else {
32709bc231bdSAndreas Färber 		printf("command is invalid!\r\n");
32719bc231bdSAndreas Färber 		usage();
327276af099aSliuyi 	}
327376af099aSliuyi 	return bSuccess;
327476af099aSliuyi }
327576af099aSliuyi 
327676af099aSliuyi 
327776af099aSliuyi int main(int argc, char* argv[])
327876af099aSliuyi {
327976af099aSliuyi 	CRKScan *pScan = NULL;
328076af099aSliuyi 	int ret;
328176af099aSliuyi 	char szProgramProcPath[100];
328276af099aSliuyi 	char szProgramDir[256];
328376af099aSliuyi 	string strLogDir,strConfigFile;
328476af099aSliuyi 	struct stat statBuf;
328576af099aSliuyi 
328676af099aSliuyi 	g_ConfigItemVec.clear();
328776af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
328876af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
328976af099aSliuyi 		strcpy(szProgramDir, ".");
329076af099aSliuyi 	else {
329176af099aSliuyi 		char *pSlash;
329276af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
329376af099aSliuyi 		if (pSlash)
329476af099aSliuyi 			*pSlash = '\0';
329576af099aSliuyi 	}
329676af099aSliuyi 	strLogDir = szProgramDir;
329776af099aSliuyi 	strLogDir +=  "/log/";
329876af099aSliuyi 	strConfigFile = szProgramDir;
329976af099aSliuyi 	strConfigFile += "/config.ini";
330076af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
330176af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
3302e5ee8cc0Sliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true);
330376af099aSliuyi 
330476af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
330576af099aSliuyi 		if (g_pLogObject) {
330676af099aSliuyi 			g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno);
330776af099aSliuyi 		}
330876af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
330976af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
331076af099aSliuyi 	}
331176af099aSliuyi 
331276af099aSliuyi 	ret = libusb_init(NULL);
331376af099aSliuyi 	if (ret < 0) {
331476af099aSliuyi 		if (g_pLogObject) {
331576af099aSliuyi 			g_pLogObject->Record("Error: libusb_init failed, err=%d", ret);
331676af099aSliuyi 			delete g_pLogObject;
331776af099aSliuyi 		}
331876af099aSliuyi 		return -1;
331976af099aSliuyi 	}
332076af099aSliuyi 
332176af099aSliuyi 	pScan = new CRKScan();
332276af099aSliuyi 	if (!pScan) {
332376af099aSliuyi 		if (g_pLogObject) {
332432268622SAndreas Färber 			g_pLogObject->Record("Error: failed to create object for searching device");
332576af099aSliuyi 			delete g_pLogObject;
332676af099aSliuyi 		}
332776af099aSliuyi 		libusb_exit(NULL);
332876af099aSliuyi 		return -2;
332976af099aSliuyi 	}
333076af099aSliuyi 	pScan->SetVidPid();
333176af099aSliuyi 
333276af099aSliuyi 	if (argc == 1)
333376af099aSliuyi 		usage();
333476af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
333576af099aSliuyi 			return -0xFF;
333676af099aSliuyi 	if (pScan)
333776af099aSliuyi 		delete pScan;
333876af099aSliuyi 	if (g_pLogObject)
333976af099aSliuyi 		delete g_pLogObject;
334076af099aSliuyi 	libusb_exit(NULL);
334176af099aSliuyi 	return 0;
334276af099aSliuyi }
3343