xref: /rkdeveloptool/main.cpp (revision c30d921c26f1105311971e7cc3731cac267aae66)
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>
10*c30d921cSKever Yang #include "config.h"
1176af099aSliuyi #include "DefineHeader.h"
12*c30d921cSKever 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);
2776af099aSliuyi #define NORMAL_COLOR_ATTR  printf("%c[37;40m", 0x1B);
28*c30d921cSKever Yang extern UINT CRC_32(unsigned char* pData, UINT ulSize);
29*c30d921cSKever Yang extern unsigned short CRC_16(unsigned char* aData, UINT aSize);
30*c30d921cSKever Yang extern void P_RC4(unsigned char* buf, unsigned short len);
31*c30d921cSKever Yang extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len);
32*c30d921cSKever Yang /*
33*c30d921cSKever Yang u8 test_gpt_head[] = {
34*c30d921cSKever Yang 	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00,
35*c30d921cSKever Yang 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36*c30d921cSKever Yang 	0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37*c30d921cSKever Yang 	0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B,
38*c30d921cSKever Yang 	0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39*c30d921cSKever Yang 	0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08};
40*c30d921cSKever Yang */
41*c30d921cSKever Yang 
4276af099aSliuyi void usage()
4376af099aSliuyi {
4476af099aSliuyi 	printf("\r\n---------------------Tool Usage ---------------------\r\n");
4576af099aSliuyi 	printf("Help:             -H\r\n");
4676af099aSliuyi 	printf("Version:          -V\r\n");
4776af099aSliuyi 	printf("DownloadBoot:	DB <Loader>\r\n");
48*c30d921cSKever Yang 	printf("UpgradeLoader:	UL <Loader>\r\n");
4976af099aSliuyi 	printf("ReadLBA:		RL  <BeginSec> <SectorLen> <File>\r\n");
5076af099aSliuyi 	printf("WriteLBA:		WL  <BeginSec> <File>\r\n");
51*c30d921cSKever Yang 	printf("WriteGPT:       GPT <parameter>\r\n");
5276af099aSliuyi 	printf("EraseFlash:		EF \r\n");
5376af099aSliuyi 	printf("TestDevice:		TD\r\n");
5476af099aSliuyi 	printf("ResetDevice:	RD [subcode]\r\n");
5576af099aSliuyi 	printf("ReadFlashID:	RID\r\n");
5676af099aSliuyi 	printf("ReadFlashInfo:	RFI\r\n");
5776af099aSliuyi 	printf("ReadChipInfo:	RCI\r\n");
5876af099aSliuyi 	printf("-------------------------------------------------------\r\n\r\n");
5976af099aSliuyi }
6076af099aSliuyi void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall)
6176af099aSliuyi {
6276af099aSliuyi 	string strInfoText="";
6376af099aSliuyi 	char szText[256];
6476af099aSliuyi 	switch (promptID) {
6576af099aSliuyi 	case TESTDEVICE_PROGRESS:
6676af099aSliuyi 		sprintf(szText, "Test Device Total(%lld),Current(%lld)", totalValue, currentValue);
6776af099aSliuyi 		strInfoText = szText;
6876af099aSliuyi 		break;
6976af099aSliuyi 	case LOWERFORMAT_PROGRESS:
7076af099aSliuyi 		sprintf(szText, "Lowerformat Device Total(%lld),Current(%lld)", totalValue, currentValue);
7176af099aSliuyi 		strInfoText = szText;
7276af099aSliuyi 		break;
7376af099aSliuyi 	case DOWNLOADIMAGE_PROGRESS:
7476af099aSliuyi 		sprintf(szText, "Download Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
7576af099aSliuyi 		strInfoText = szText;
7676af099aSliuyi 		break;
7776af099aSliuyi 	case CHECKIMAGE_PROGRESS:
7876af099aSliuyi 		sprintf(szText, "Check Image Total(%lldK),Current(%lldK)", totalValue/1024, currentValue/1024);
7976af099aSliuyi 		strInfoText = szText;
8076af099aSliuyi 		break;
8176af099aSliuyi 	case TAGBADBLOCK_PROGRESS:
8276af099aSliuyi 		sprintf(szText, "Tag Bad Block Total(%lld),Current(%lld)", totalValue, currentValue);
8376af099aSliuyi 		strInfoText = szText;
8476af099aSliuyi 		break;
8576af099aSliuyi 	case TESTBLOCK_PROGRESS:
8676af099aSliuyi 		sprintf(szText, "Test Block Total(%lld),Current(%lld)", totalValue, currentValue);
8776af099aSliuyi 		strInfoText = szText;
8876af099aSliuyi 		break;
8976af099aSliuyi 	case ERASEFLASH_PROGRESS:
9076af099aSliuyi 		sprintf(szText, "Erase Flash Total(%lld),Current(%lld)", totalValue, currentValue);
9176af099aSliuyi 		strInfoText = szText;
9276af099aSliuyi 		break;
9376af099aSliuyi 	case ERASESYSTEM_PROGRESS:
9476af099aSliuyi 		sprintf(szText, "Erase System partition Total(%lld),Current(%lld)", totalValue, currentValue);
9576af099aSliuyi 		strInfoText = szText;
9676af099aSliuyi 		break;
9776af099aSliuyi 	case ERASEUSERDATA_PROGRESS:
9876af099aSliuyi 		sprintf(szText, "<LocationID=%x> Erase Userdata partition Total(%lld),Current(%lld)",deviceLayer,totalValue, currentValue);
9976af099aSliuyi 		strInfoText = szText;
10076af099aSliuyi 		break;
10176af099aSliuyi 	}
10276af099aSliuyi 	if (strInfoText.size() > 0){
10376af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
10476af099aSliuyi 		CURSOR_DEL_LINE;
10576af099aSliuyi 		printf("%s\r\n", strInfoText.c_str());
10676af099aSliuyi 	}
10776af099aSliuyi 	if (emCall == CALL_LAST)
10876af099aSliuyi 		deviceLayer = 0;
10976af099aSliuyi }
11076af099aSliuyi 
11176af099aSliuyi char *strupr(char *szSrc)
11276af099aSliuyi {
11376af099aSliuyi 	char *p = szSrc;
11476af099aSliuyi 	while(*p){
11576af099aSliuyi 		if ((*p >= 'a') && (*p <= 'z'))
11676af099aSliuyi 			*p = *p - 'a' + 'A';
11776af099aSliuyi 		p++;
11876af099aSliuyi 	}
11976af099aSliuyi 	return szSrc;
12076af099aSliuyi }
12176af099aSliuyi void PrintData(PBYTE pData, int nSize)
12276af099aSliuyi {
12376af099aSliuyi 	char szPrint[17] = "\0";
12476af099aSliuyi 	int i;
12576af099aSliuyi 	for( i = 0; i < nSize; i++){
12676af099aSliuyi 		if(i % 16 == 0){
12776af099aSliuyi 			if(i / 16 > 0)
12876af099aSliuyi 				printf("     %s\r\n", szPrint);
12976af099aSliuyi 			printf("%08d ", i / 16);
13076af099aSliuyi 		}
13176af099aSliuyi 		printf("%02X ", pData[i]);
13276af099aSliuyi 		szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.';
13376af099aSliuyi 	}
13476af099aSliuyi 	if(i / 16 > 0)
13576af099aSliuyi 		printf("     %s\r\n", szPrint);
13676af099aSliuyi }
13776af099aSliuyi 
13876af099aSliuyi bool StringToWideString(char *pszSrc, wchar_t *&pszDest)
13976af099aSliuyi {
14076af099aSliuyi 	if (!pszSrc)
14176af099aSliuyi 		return false;
14276af099aSliuyi 	int nSrcLen = strlen(pszSrc);
14376af099aSliuyi 	int nDestLen = nSrcLen * 2;
14476af099aSliuyi 
14576af099aSliuyi 	pszDest = NULL;
14676af099aSliuyi 	pszDest = new wchar_t[nDestLen];
14776af099aSliuyi 	if (!pszDest)
14876af099aSliuyi 		return false;
14976af099aSliuyi 	nDestLen = nDestLen * sizeof(wchar_t);
15076af099aSliuyi 	memset(pszDest, 0, nDestLen);
15176af099aSliuyi 	int iRet;
15276af099aSliuyi 	iconv_t cd;
15376af099aSliuyi 	cd = iconv_open("UTF-32", "UTF-8");
15476af099aSliuyi 	if((iconv_t)-1 == cd) {
15576af099aSliuyi 		delete []pszDest;
15676af099aSliuyi 		pszDest = NULL;
15776af099aSliuyi 	      return false;
15876af099aSliuyi 	 }
15976af099aSliuyi 	char *pIn, *pOut;
16076af099aSliuyi 	pIn = (char *)pszSrc;
16176af099aSliuyi 	pOut = (char *)pszDest;
16276af099aSliuyi 
16376af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
16476af099aSliuyi 
16576af099aSliuyi 	if(iRet == -1) {
16676af099aSliuyi 		delete []pszDest;
16776af099aSliuyi 		pszDest = NULL;
16876af099aSliuyi 		iconv_close(cd);
16976af099aSliuyi 		return false;
17076af099aSliuyi 	 }
17176af099aSliuyi 
17276af099aSliuyi 	 iconv_close(cd);
17376af099aSliuyi 
17476af099aSliuyi 	 return true;
17576af099aSliuyi }
17676af099aSliuyi bool WideStringToString(wchar_t *pszSrc, char *&pszDest)
17776af099aSliuyi {
17876af099aSliuyi 	if (!pszSrc)
17976af099aSliuyi 		return false;
18076af099aSliuyi 	int nSrcLen = wcslen(pszSrc);
18176af099aSliuyi 	int nDestLen = nSrcLen * 2;
18276af099aSliuyi 	nSrcLen = nSrcLen * sizeof(wchar_t);
18376af099aSliuyi 	pszDest = NULL;
18476af099aSliuyi 	pszDest = new char[nDestLen];
18576af099aSliuyi 	if (!pszDest)
18676af099aSliuyi 		return false;
18776af099aSliuyi 	memset(pszDest, 0, nDestLen);
18876af099aSliuyi 	int iRet;
18976af099aSliuyi 	iconv_t cd;
19076af099aSliuyi 	cd = iconv_open("UTF-8", "UTF-32");
19176af099aSliuyi 
19276af099aSliuyi 	if((iconv_t)-1 == cd) {
19376af099aSliuyi 		delete []pszDest;
19476af099aSliuyi 		pszDest = NULL;
19576af099aSliuyi 	      return false;
19676af099aSliuyi 	 }
19776af099aSliuyi 	char *pIn, *pOut;
19876af099aSliuyi 	pIn = (char *)pszSrc;
19976af099aSliuyi 	pOut = (char *)pszDest;
20076af099aSliuyi 	iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen);
20176af099aSliuyi 
20276af099aSliuyi 	if(iRet == -1) {
20376af099aSliuyi 		delete []pszDest;
20476af099aSliuyi 		pszDest = NULL;
20576af099aSliuyi 		iconv_close(cd);
20676af099aSliuyi 		return false;
20776af099aSliuyi 	 }
20876af099aSliuyi 
20976af099aSliuyi 	 iconv_close(cd);
21076af099aSliuyi 
21176af099aSliuyi 	 return true;
21276af099aSliuyi }
21376af099aSliuyi int find_config_item(const char *pszName)
21476af099aSliuyi {
21576af099aSliuyi 	unsigned int i;
21676af099aSliuyi 	for(i = 0; i < g_ConfigItemVec.size(); i++){
21776af099aSliuyi 		if (strcasecmp(pszName, g_ConfigItemVec[i].szItemName) == 0){
21876af099aSliuyi 			return i;
21976af099aSliuyi 		}
22076af099aSliuyi 	}
22176af099aSliuyi 	return -1;
22276af099aSliuyi }
22376af099aSliuyi 
22476af099aSliuyi bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem)
22576af099aSliuyi {
22676af099aSliuyi 
22776af099aSliuyi 	stringstream configStream(pConfig);
22876af099aSliuyi 	string strLine, strItemName, strItemValue;
22976af099aSliuyi 	string::size_type line_size,pos;
23076af099aSliuyi 	STRUCT_CONFIG_ITEM item;
23176af099aSliuyi 	vecItem.clear();
23276af099aSliuyi 	while (!configStream.eof()){
23376af099aSliuyi 		getline(configStream, strLine);
23476af099aSliuyi 		line_size = strLine.size();
23576af099aSliuyi 		if (line_size == 0)
23676af099aSliuyi 			continue;
23776af099aSliuyi 		if (strLine[line_size-1] == '\r'){
23876af099aSliuyi 			strLine = strLine.substr(0, line_size-1);
23976af099aSliuyi 		}
240*c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
241*c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
242*c30d921cSKever Yang 		if (strLine.size()==0 )
243*c30d921cSKever Yang 			continue;
244*c30d921cSKever Yang 		if (strLine[0] == '#')
245*c30d921cSKever Yang 			continue;
24676af099aSliuyi 		pos = strLine.find("=");
24776af099aSliuyi 		if (pos == string::npos){
24876af099aSliuyi 			continue;
24976af099aSliuyi 		}
25076af099aSliuyi 		strItemName = strLine.substr(0, pos);
25176af099aSliuyi 		strItemValue = strLine.substr(pos + 1);
25276af099aSliuyi 		strItemName.erase(0, strItemName.find_first_not_of(" "));
25376af099aSliuyi 		strItemName.erase(strItemName.find_last_not_of(" ") + 1);
25476af099aSliuyi 		strItemValue.erase(0, strItemValue.find_first_not_of(" "));
25576af099aSliuyi 		strItemValue.erase(strItemValue.find_last_not_of(" ") + 1);
25676af099aSliuyi 		if ((strItemName.size() > 0) && (strItemValue.size() > 0)){
25776af099aSliuyi 			strcpy(item.szItemName, strItemName.c_str());
25876af099aSliuyi 			strcpy(item.szItemValue, strItemValue.c_str());
25976af099aSliuyi 			vecItem.push_back(item);
26076af099aSliuyi 		}
26176af099aSliuyi 	}
26276af099aSliuyi 	return true;
26376af099aSliuyi 
26476af099aSliuyi }
26576af099aSliuyi bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem)
26676af099aSliuyi {
26776af099aSliuyi 	FILE *file = NULL;
26876af099aSliuyi 	file = fopen(pConfigFile, "rb");
26976af099aSliuyi 	if( !file ){
27076af099aSliuyi 		if (g_pLogObject)
27176af099aSliuyi 			g_pLogObject->Record("parse_config_file failed,err=%d,can't open file: %s\r\n", errno, pConfigFile);
27276af099aSliuyi 		return false;
27376af099aSliuyi 	}
27476af099aSliuyi 	int iFileSize;
27576af099aSliuyi 	fseek(file, 0, SEEK_END);
27676af099aSliuyi 	iFileSize = ftell(file);
27776af099aSliuyi 	fseek(file, 0, SEEK_SET);
27876af099aSliuyi 	char *pConfigBuf = NULL;
27976af099aSliuyi 	pConfigBuf = new char[iFileSize + 1];
28076af099aSliuyi 	if (!pConfigBuf){
28176af099aSliuyi 		fclose(file);
28276af099aSliuyi 		return false;
28376af099aSliuyi 	}
28476af099aSliuyi 	memset(pConfigBuf, 0, iFileSize + 1);
28576af099aSliuyi 	int iRead;
28676af099aSliuyi 	iRead = fread(pConfigBuf, 1, iFileSize, file);
28776af099aSliuyi 	if (iRead != iFileSize){
28876af099aSliuyi 		if (g_pLogObject)
28976af099aSliuyi 			g_pLogObject->Record("parse_config_file failed,err=%d, read=%d, total=%d\r\n", errno, iRead, iFileSize);
29076af099aSliuyi 		fclose(file);
29176af099aSliuyi 		delete []pConfigBuf;
29276af099aSliuyi 		return false;
29376af099aSliuyi 	}
29476af099aSliuyi 	fclose(file);
29576af099aSliuyi 	bool bRet;
29676af099aSliuyi 	bRet = parse_config(pConfigBuf, vecItem);
29776af099aSliuyi 	delete []pConfigBuf;
29876af099aSliuyi 	return bRet;
29976af099aSliuyi }
300*c30d921cSKever Yang bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
301*c30d921cSKever Yang {
302*c30d921cSKever Yang 	string::size_type pos,prevPos;
303*c30d921cSKever Yang 	string strOffset,strLen;
304*c30d921cSKever Yang 	int iCount;
305*c30d921cSKever Yang 	prevPos = pos = 0;
306*c30d921cSKever Yang 	if (strPartInfo.size() <= 0) {
307*c30d921cSKever Yang 		return false;
308*c30d921cSKever Yang 	}
309*c30d921cSKever Yang 	pos = strPartInfo.find('@');
310*c30d921cSKever Yang 	if (pos == string::npos) {
311*c30d921cSKever Yang 		return false;
312*c30d921cSKever Yang 	}
313*c30d921cSKever Yang 	strLen = strPartInfo.substr(prevPos, pos - prevPos);
314*c30d921cSKever Yang 	strLen.erase(0, strLen.find_first_not_of(" "));
315*c30d921cSKever Yang 	strLen.erase(strLen.find_last_not_of(" ") + 1);
316*c30d921cSKever Yang 	if (strchr(strLen.c_str(), '-')) {
317*c30d921cSKever Yang 		uiLen = 0xFFFFFFFF;
318*c30d921cSKever Yang 	} else {
319*c30d921cSKever Yang 		iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
320*c30d921cSKever Yang 		if (iCount != 1) {
321*c30d921cSKever Yang 			return false;
322*c30d921cSKever Yang 		}
323*c30d921cSKever Yang 	}
324*c30d921cSKever Yang 
325*c30d921cSKever Yang 	prevPos = pos + 1;
326*c30d921cSKever Yang 	pos = strPartInfo.find('(',prevPos);
327*c30d921cSKever Yang 	if (pos == string::npos) {
328*c30d921cSKever Yang 		return false;
329*c30d921cSKever Yang 	}
330*c30d921cSKever Yang 	strOffset = strPartInfo.substr(prevPos, pos - prevPos);
331*c30d921cSKever Yang 	strOffset.erase(0, strOffset.find_first_not_of(" "));
332*c30d921cSKever Yang 	strOffset.erase(strOffset.find_last_not_of(" ") + 1);
333*c30d921cSKever Yang 	iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
334*c30d921cSKever Yang 	if (iCount != 1) {
335*c30d921cSKever Yang 		return false;
336*c30d921cSKever Yang 	}
337*c30d921cSKever Yang 	prevPos = pos + 1;
338*c30d921cSKever Yang 	pos = strPartInfo.find(')', prevPos);
339*c30d921cSKever Yang 	if (pos == string::npos) {
340*c30d921cSKever Yang 		return false;
341*c30d921cSKever Yang 	}
342*c30d921cSKever Yang 	strName = strPartInfo.substr(prevPos, pos - prevPos);
343*c30d921cSKever Yang 	strName.erase(0, strName.find_first_not_of(" "));
344*c30d921cSKever Yang 	strName.erase(strName.find_last_not_of(" ") + 1);
345*c30d921cSKever Yang 
346*c30d921cSKever Yang 	return true;
347*c30d921cSKever Yang }
348*c30d921cSKever Yang 
349*c30d921cSKever Yang bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem)
350*c30d921cSKever Yang {
351*c30d921cSKever Yang 	stringstream paramStream(pParameter);
352*c30d921cSKever Yang 	bool bRet,bFind = false;
353*c30d921cSKever Yang 	string strLine, strPartition, strPartInfo, strPartName;
354*c30d921cSKever Yang 	string::size_type line_size, pos, posColon, posComma;
355*c30d921cSKever Yang 	UINT uiPartOffset, uiPartSize;
356*c30d921cSKever Yang 	STRUCT_PARAM_ITEM item;
357*c30d921cSKever Yang 	vecItem.clear();
358*c30d921cSKever Yang 	while (!paramStream.eof()) {
359*c30d921cSKever Yang 		getline(paramStream,strLine);
360*c30d921cSKever Yang 		line_size = strLine.size();
361*c30d921cSKever Yang 		if (line_size == 0)
362*c30d921cSKever Yang 			continue;
363*c30d921cSKever Yang 		if (strLine[line_size - 1] == '\r'){
364*c30d921cSKever Yang 			strLine = strLine.substr(0, line_size - 1);
365*c30d921cSKever Yang 		}
366*c30d921cSKever Yang 		strLine.erase(0, strLine.find_first_not_of(" "));
367*c30d921cSKever Yang 		strLine.erase(strLine.find_last_not_of(" ") + 1);
368*c30d921cSKever Yang 		if (strLine.size()==0 )
369*c30d921cSKever Yang 			continue;
370*c30d921cSKever Yang 		if (strLine[0] == '#')
371*c30d921cSKever Yang 			continue;
372*c30d921cSKever Yang 		pos = strLine.find("mtdparts");
373*c30d921cSKever Yang 		if (pos == string::npos) {
374*c30d921cSKever Yang 			continue;
375*c30d921cSKever Yang 		}
376*c30d921cSKever Yang 		bFind = true;
377*c30d921cSKever Yang 		posColon = strLine.find(':', pos);
378*c30d921cSKever Yang 		if (posColon == string::npos) {
379*c30d921cSKever Yang 			continue;
380*c30d921cSKever Yang 		}
381*c30d921cSKever Yang 		strPartition = strLine.substr(posColon + 1);
382*c30d921cSKever Yang 		pos = 0;
383*c30d921cSKever Yang 		posComma = strPartition.find(',', pos);
384*c30d921cSKever Yang 		while (posComma != string::npos) {
385*c30d921cSKever Yang 			strPartInfo = strPartition.substr(pos, posComma - pos);
386*c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
387*c30d921cSKever Yang 			if (bRet) {
388*c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
389*c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
390*c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
391*c30d921cSKever Yang 				vecItem.push_back(item);
392*c30d921cSKever Yang 			}
393*c30d921cSKever Yang 			pos = posComma + 1;
394*c30d921cSKever Yang 			posComma = strPartition.find(',', pos);
395*c30d921cSKever Yang 		}
396*c30d921cSKever Yang 		strPartInfo = strPartition.substr(pos);
397*c30d921cSKever Yang 		if (strPartInfo.size() > 0) {
398*c30d921cSKever Yang 			bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
399*c30d921cSKever Yang 			if (bRet) {
400*c30d921cSKever Yang 				strcpy(item.szItemName, strPartName.c_str());
401*c30d921cSKever Yang 				item.uiItemOffset = uiPartOffset;
402*c30d921cSKever Yang 				item.uiItemSize = uiPartSize;
403*c30d921cSKever Yang 				vecItem.push_back(item);
404*c30d921cSKever Yang 			}
405*c30d921cSKever Yang 		}
406*c30d921cSKever Yang 		break;
407*c30d921cSKever Yang 	}
408*c30d921cSKever Yang 	return bFind;
409*c30d921cSKever Yang 
410*c30d921cSKever Yang }
411*c30d921cSKever Yang bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem)
412*c30d921cSKever Yang {
413*c30d921cSKever Yang 	FILE *file = NULL;
414*c30d921cSKever Yang 	file = fopen(pParamFile, "rb");
415*c30d921cSKever Yang 	if( !file ) {
416*c30d921cSKever Yang 		if (g_pLogObject)
417*c30d921cSKever Yang 			g_pLogObject->Record("parse_parameter_file failed, err=%d, can't open file: %s\r\n", errno, pParamFile);
418*c30d921cSKever Yang 		return false;
419*c30d921cSKever Yang 	}
420*c30d921cSKever Yang 	int iFileSize;
421*c30d921cSKever Yang 	fseek(file, 0, SEEK_END);
422*c30d921cSKever Yang 	iFileSize = ftell(file);
423*c30d921cSKever Yang 	fseek(file, 0, SEEK_SET);
424*c30d921cSKever Yang 	char *pParamBuf = NULL;
425*c30d921cSKever Yang 	pParamBuf = new char[iFileSize];
426*c30d921cSKever Yang 	if (!pParamBuf) {
427*c30d921cSKever Yang 		fclose(file);
428*c30d921cSKever Yang 		return false;
429*c30d921cSKever Yang 	}
430*c30d921cSKever Yang 	int iRead;
431*c30d921cSKever Yang 	iRead = fread(pParamBuf, 1, iFileSize, file);
432*c30d921cSKever Yang 	if (iRead != iFileSize) {
433*c30d921cSKever Yang 		if (g_pLogObject)
434*c30d921cSKever Yang 			g_pLogObject->Record("parse_parameter_file failed, err=%d, read=%d, total=%d\r\n", errno,iRead,iFileSize);
435*c30d921cSKever Yang 		fclose(file);
436*c30d921cSKever Yang 		delete []pParamBuf;
437*c30d921cSKever Yang 		return false;
438*c30d921cSKever Yang 	}
439*c30d921cSKever Yang 	fclose(file);
440*c30d921cSKever Yang 	bool bRet;
441*c30d921cSKever Yang 	bRet = parse_parameter(pParamBuf, vecItem);
442*c30d921cSKever Yang 	delete []pParamBuf;
443*c30d921cSKever Yang 	return bRet;
444*c30d921cSKever Yang }
445*c30d921cSKever Yang void gen_rand_uuid(unsigned char *uuid_bin)
446*c30d921cSKever Yang {
447*c30d921cSKever Yang 	efi_guid_t id;
448*c30d921cSKever Yang 	unsigned int *ptr = (unsigned int *)&id;
449*c30d921cSKever Yang 	unsigned int i;
450*c30d921cSKever Yang 
451*c30d921cSKever Yang 	/* Set all fields randomly */
452*c30d921cSKever Yang 	for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
453*c30d921cSKever Yang 		*(ptr + i) = cpu_to_be32(rand());
454*c30d921cSKever Yang 
455*c30d921cSKever Yang 	id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
456*c30d921cSKever Yang 	id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
457*c30d921cSKever Yang 
458*c30d921cSKever Yang 	memcpy(uuid_bin, id.raw, sizeof(id));
459*c30d921cSKever Yang }
460*c30d921cSKever Yang 
461*c30d921cSKever Yang void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, u64 diskSectors)
462*c30d921cSKever Yang {
463*c30d921cSKever Yang 	legacy_mbr *mbr = (legacy_mbr *)gpt;
464*c30d921cSKever Yang 	gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
465*c30d921cSKever Yang 	gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
466*c30d921cSKever Yang 	u32 i,j;
467*c30d921cSKever Yang 	string strPartName;
468*c30d921cSKever Yang 	string::size_type colonPos;
469*c30d921cSKever Yang 	/*1.protective mbr*/
470*c30d921cSKever Yang 	memset(gpt, 0, SECTOR_SIZE);
471*c30d921cSKever Yang 	mbr->signature = MSDOS_MBR_SIGNATURE;
472*c30d921cSKever Yang 	mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
473*c30d921cSKever Yang 	mbr->partition_record[0].start_sect = 1;
474*c30d921cSKever Yang 	mbr->partition_record[0].nr_sects = (u32)-1;
475*c30d921cSKever Yang 	/*2.gpt header*/
476*c30d921cSKever Yang 	memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
477*c30d921cSKever Yang 	gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
478*c30d921cSKever Yang 	gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
479*c30d921cSKever Yang 	gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
480*c30d921cSKever Yang 	gptHead->my_lba = cpu_to_le64(1);
481*c30d921cSKever Yang 	gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
482*c30d921cSKever Yang 	gptHead->first_usable_lba = cpu_to_le64(34);
483*c30d921cSKever Yang 	gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
484*c30d921cSKever Yang 	gptHead->partition_entry_lba = cpu_to_le64(2);
485*c30d921cSKever Yang 	gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
486*c30d921cSKever Yang 	gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
487*c30d921cSKever Yang 	gptHead->header_crc32 = 0;
488*c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = 0;
489*c30d921cSKever Yang 	gen_rand_uuid(gptHead->disk_guid.raw);
490*c30d921cSKever Yang 
491*c30d921cSKever Yang 	/*3.gpt partition entry*/
492*c30d921cSKever Yang 	memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
493*c30d921cSKever Yang 	for (i = 0; i < vecParts.size(); i++) {
494*c30d921cSKever Yang 		gen_rand_uuid(gptEntry->partition_type_guid.raw);
495*c30d921cSKever Yang 		gen_rand_uuid(gptEntry->unique_partition_guid.raw);
496*c30d921cSKever Yang 		gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
497*c30d921cSKever Yang 		gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
498*c30d921cSKever Yang 		gptEntry->attributes.raw = 0;
499*c30d921cSKever Yang 		strPartName = vecParts[i].szItemName;
500*c30d921cSKever Yang 		colonPos = strPartName.find_first_of(':');
501*c30d921cSKever Yang 		if (colonPos != string::npos) {
502*c30d921cSKever Yang 			if (strPartName.find("bootable") != string::npos)
503*c30d921cSKever Yang 				gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
504*c30d921cSKever Yang 			strPartName = strPartName.substr(0, colonPos);
505*c30d921cSKever Yang 			vecParts[i].szItemName[strPartName.size()] = 0;
506*c30d921cSKever Yang 		}
507*c30d921cSKever Yang 		for (j = 0; j < strlen(vecParts[i].szItemName); j++)
508*c30d921cSKever Yang 			gptEntry->partition_name[j] = vecParts[i].szItemName[j];
509*c30d921cSKever Yang 		gptEntry++;
510*c30d921cSKever Yang 	}
511*c30d921cSKever Yang 
512*c30d921cSKever Yang 	gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
513*c30d921cSKever Yang 	gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
514*c30d921cSKever Yang 
515*c30d921cSKever Yang }
516*c30d921cSKever Yang bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec)
517*c30d921cSKever Yang {
518*c30d921cSKever Yang 	PRK28_IDB_SEC0 pSec0;
519*c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
520*c30d921cSKever Yang 	pSec0 = (PRK28_IDB_SEC0)pSector;
521*c30d921cSKever Yang 
522*c30d921cSKever Yang 	pSec0->dwTag = 0x0FF0AA55;
523*c30d921cSKever Yang 	pSec0->uiRc4Flag = 1;
524*c30d921cSKever Yang 	pSec0->usBootCode1Offset = 0x4;
525*c30d921cSKever Yang 	pSec0->usBootCode2Offset = 0x4;
526*c30d921cSKever Yang 	pSec0->usBootDataSize = usFlashDataSec;
527*c30d921cSKever Yang 	pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec;
528*c30d921cSKever Yang 	return true;
529*c30d921cSKever Yang }
530*c30d921cSKever Yang 
531*c30d921cSKever Yang 
532*c30d921cSKever Yang bool MakeSector1(PBYTE pSector)
533*c30d921cSKever Yang {
534*c30d921cSKever Yang 	PRK28_IDB_SEC1 pSec1;
535*c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
536*c30d921cSKever Yang 	pSec1 = (PRK28_IDB_SEC1)pSector;
537*c30d921cSKever Yang 
538*c30d921cSKever Yang 	pSec1->usSysReservedBlock = 0xC;
539*c30d921cSKever Yang 	pSec1->usDisk0Size = 0xFFFF;
540*c30d921cSKever Yang 	pSec1->uiChipTag = 0x38324B52;
541*c30d921cSKever Yang 	return true;
542*c30d921cSKever Yang }
543*c30d921cSKever Yang 
544*c30d921cSKever Yang bool MakeSector2(PBYTE pSector)
545*c30d921cSKever Yang {
546*c30d921cSKever Yang 	PRK28_IDB_SEC2 pSec2;
547*c30d921cSKever Yang 	memset(pSector, 0, SECTOR_SIZE);
548*c30d921cSKever Yang 	pSec2 = (PRK28_IDB_SEC2)pSector;
549*c30d921cSKever Yang 
550*c30d921cSKever Yang 	strcpy(pSec2->szVcTag, "VC");
551*c30d921cSKever Yang 	strcpy(pSec2->szCrcTag, "CRC");
552*c30d921cSKever Yang 	return true;
553*c30d921cSKever Yang }
554*c30d921cSKever Yang 
555*c30d921cSKever Yang bool MakeSector3(PBYTE pSector)
556*c30d921cSKever Yang {
557*c30d921cSKever Yang 	memset(pSector,0,SECTOR_SIZE);
558*c30d921cSKever Yang 	return true;
559*c30d921cSKever Yang }
560*c30d921cSKever Yang 
561*c30d921cSKever Yang int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize)
562*c30d921cSKever Yang {
563*c30d921cSKever Yang 	RK28_IDB_SEC0 sector0Info;
564*c30d921cSKever Yang 	RK28_IDB_SEC1 sector1Info;
565*c30d921cSKever Yang 	RK28_IDB_SEC2 sector2Info;
566*c30d921cSKever Yang 	RK28_IDB_SEC3 sector3Info;
567*c30d921cSKever Yang 	UINT i;
568*c30d921cSKever Yang 
569*c30d921cSKever Yang 	MakeSector0((PBYTE)&sector0Info, usFlashDataSec, usFlashBootSec);
570*c30d921cSKever Yang 	MakeSector1((PBYTE)&sector1Info);
571*c30d921cSKever Yang 	if (!MakeSector2((PBYTE)&sector2Info)) {
572*c30d921cSKever Yang 		return -6;
573*c30d921cSKever Yang 	}
574*c30d921cSKever Yang 	if (!MakeSector3((PBYTE)&sector3Info)) {
575*c30d921cSKever Yang 		return -7;
576*c30d921cSKever Yang 	}
577*c30d921cSKever Yang 	sector2Info.usSec0Crc = CRC_16((PBYTE)&sector0Info, SECTOR_SIZE);
578*c30d921cSKever Yang 	sector2Info.usSec1Crc = CRC_16((PBYTE)&sector1Info, SECTOR_SIZE);
579*c30d921cSKever Yang 	sector2Info.usSec3Crc = CRC_16((PBYTE)&sector3Info, SECTOR_SIZE);
580*c30d921cSKever Yang 
581*c30d921cSKever Yang 	memcpy(lpIDBlock, &sector0Info, SECTOR_SIZE);
582*c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE, &sector1Info, SECTOR_SIZE);
583*c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 3, &sector3Info, SECTOR_SIZE);
584*c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize);
585*c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize);
586*c30d921cSKever Yang 
587*c30d921cSKever Yang 	sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE);
588*c30d921cSKever Yang 	memcpy(lpIDBlock + SECTOR_SIZE * 2, &sector2Info, SECTOR_SIZE);
589*c30d921cSKever Yang 	for(i = 0; i < 4; i++) {
590*c30d921cSKever Yang 		if(i == 1) {
591*c30d921cSKever Yang 			continue;
592*c30d921cSKever Yang 		} else {
593*c30d921cSKever Yang 			P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE);
594*c30d921cSKever Yang 		}
595*c30d921cSKever Yang 	}
596*c30d921cSKever Yang 	return 0;
597*c30d921cSKever Yang }
598*c30d921cSKever Yang 
599*c30d921cSKever Yang 
60076af099aSliuyi 
60176af099aSliuyi bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType)
60276af099aSliuyi {
60376af099aSliuyi 	if ((dev.emUsbType & uiSupportType) == dev.emUsbType)
60476af099aSliuyi 		return true;
60576af099aSliuyi 	else
60676af099aSliuyi 	{
60776af099aSliuyi 		ERROR_COLOR_ATTR;
60876af099aSliuyi 		printf("The  Device did not support this operation!");
60976af099aSliuyi 		NORMAL_COLOR_ATTR;
61076af099aSliuyi 		printf("\r\n");
61176af099aSliuyi 		return false;
61276af099aSliuyi 	}
61376af099aSliuyi }
614*c30d921cSKever Yang bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter)
615*c30d921cSKever Yang {
616*c30d921cSKever Yang 	u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE];
617*c30d921cSKever Yang 	u32 total_size_sector;
618*c30d921cSKever Yang 	CRKComm *pComm = NULL;
619*c30d921cSKever Yang 	PARAM_ITEM_VECTOR vecItems;
620*c30d921cSKever Yang 	int iRet;
621*c30d921cSKever Yang 	bool bRet, bSuccess = false;
622*c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
623*c30d921cSKever Yang 		return false;
624*c30d921cSKever Yang 
625*c30d921cSKever Yang 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
626*c30d921cSKever Yang 	if (!bRet) {
627*c30d921cSKever Yang 		ERROR_COLOR_ATTR;
628*c30d921cSKever Yang 		printf("Creating Comm Object failed!");
629*c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
630*c30d921cSKever Yang 		printf("\r\n");
631*c30d921cSKever Yang 		return bSuccess;
632*c30d921cSKever Yang 	}
633*c30d921cSKever Yang 	printf("Write gpt...\r\n");
634*c30d921cSKever Yang 	//1.get flash info
635*c30d921cSKever Yang 	iRet = pComm->RKU_ReadFlashInfo(flash_info);
636*c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
637*c30d921cSKever Yang 		ERROR_COLOR_ATTR;
638*c30d921cSKever Yang 		printf("Reading Flash Info failed!");
639*c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
640*c30d921cSKever Yang 		printf("\r\n");
641*c30d921cSKever Yang 		return bSuccess;
642*c30d921cSKever Yang 	}
643*c30d921cSKever Yang 	total_size_sector = *(u32 *)flash_info;
644*c30d921cSKever Yang 	//2.get partition from parameter
645*c30d921cSKever Yang 	bRet = parse_parameter_file(szParameter, vecItems);
646*c30d921cSKever Yang 	if (!bRet) {
647*c30d921cSKever Yang 		ERROR_COLOR_ATTR;
648*c30d921cSKever Yang 		printf("Parsing parameter failed!");
649*c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
650*c30d921cSKever Yang 		printf("\r\n");
651*c30d921cSKever Yang 		return bSuccess;
652*c30d921cSKever Yang 	}
653*c30d921cSKever Yang 	vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 34;
654*c30d921cSKever Yang 	//3.generate gpt info
655*c30d921cSKever Yang 	create_gpt_buffer(master_gpt, vecItems, total_size_sector);
656*c30d921cSKever Yang 	memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
657*c30d921cSKever Yang 	memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE);
658*c30d921cSKever Yang 	//4. write gpt
659*c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(0, 34, master_gpt);
660*c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
661*c30d921cSKever Yang 		ERROR_COLOR_ATTR;
662*c30d921cSKever Yang 		printf("Writing master gpt failed!");
663*c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
664*c30d921cSKever Yang 		printf("\r\n");
665*c30d921cSKever Yang 		return bSuccess;
666*c30d921cSKever Yang 	}
667*c30d921cSKever Yang 	iRet = pComm->RKU_WriteLBA(total_size_sector - 34, 33, backup_gpt);
668*c30d921cSKever Yang 	if (iRet != ERR_SUCCESS) {
669*c30d921cSKever Yang 		ERROR_COLOR_ATTR;
670*c30d921cSKever Yang 		printf("Writing backup gpt failed!");
671*c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
672*c30d921cSKever Yang 		printf("\r\n");
673*c30d921cSKever Yang 		return bSuccess;
674*c30d921cSKever Yang 	}
675*c30d921cSKever Yang 	bSuccess = true;
676*c30d921cSKever Yang 	CURSOR_MOVEUP_LINE(1);
677*c30d921cSKever Yang 	CURSOR_DEL_LINE;
678*c30d921cSKever Yang 	printf("Write gpt ok.\r\n");
679*c30d921cSKever Yang 	return bSuccess;
680*c30d921cSKever Yang }
68176af099aSliuyi 
68276af099aSliuyi bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
68376af099aSliuyi {
68476af099aSliuyi 	if (!check_device_type(dev, RKUSB_MASKROM))
68576af099aSliuyi 		return false;
68676af099aSliuyi 	CRKImage *pImage = NULL;
68776af099aSliuyi 	CRKBoot *pBoot = NULL;
68876af099aSliuyi 	bool bRet, bSuccess = false;
68976af099aSliuyi 	int iRet;
69076af099aSliuyi 
69176af099aSliuyi 	pImage = new CRKImage(szLoader, bRet);
69276af099aSliuyi 	if (!bRet){
69376af099aSliuyi 		ERROR_COLOR_ATTR;
69476af099aSliuyi 		printf("Open loader failed,exit download boot!");
69576af099aSliuyi 		NORMAL_COLOR_ATTR;
69676af099aSliuyi 		printf("\r\n");
69776af099aSliuyi 		return bSuccess;
69876af099aSliuyi 	} else {
69976af099aSliuyi 		pBoot = (CRKBoot *)pImage->m_bootObject;
70076af099aSliuyi 		CRKComm *pComm = NULL;
70176af099aSliuyi 		CRKDevice *pDevice = NULL;
70276af099aSliuyi 
70376af099aSliuyi 		dev.emDeviceType = pBoot->SupportDevice;
70476af099aSliuyi 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
70576af099aSliuyi 		if (!bRet) {
70676af099aSliuyi 			if (pImage)
70776af099aSliuyi 				delete pImage;
70876af099aSliuyi 			ERROR_COLOR_ATTR;
70976af099aSliuyi 			printf("Creating Comm Object failed!");
71076af099aSliuyi 			NORMAL_COLOR_ATTR;
71176af099aSliuyi 			printf("\r\n");
71276af099aSliuyi 			return bSuccess;
71376af099aSliuyi 		}
71476af099aSliuyi 
71576af099aSliuyi 		pDevice = new CRKDevice(dev);
71676af099aSliuyi 		if (!pDevice) {
71776af099aSliuyi 			if (pImage)
71876af099aSliuyi 				delete pImage;
71976af099aSliuyi 			if (pComm)
72076af099aSliuyi 				delete pComm;
72176af099aSliuyi 			ERROR_COLOR_ATTR;
72276af099aSliuyi 			printf("Creating device object failed!");
72376af099aSliuyi 			NORMAL_COLOR_ATTR;
72476af099aSliuyi 			printf("\r\n");
72576af099aSliuyi 			return bSuccess;
72676af099aSliuyi 		}
72776af099aSliuyi 
72876af099aSliuyi 		pDevice->SetObject(pImage, pComm, g_pLogObject);
72976af099aSliuyi 		printf("Download boot...\r\n");
73076af099aSliuyi 		iRet = pDevice->DownloadBoot();
73176af099aSliuyi 
73276af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
73376af099aSliuyi 		CURSOR_DEL_LINE;
73476af099aSliuyi 		if (iRet == 0) {
73576af099aSliuyi 			pComm->Reset_Usb_Device();
73676af099aSliuyi 			CRKScan *pScan = NULL;
73776af099aSliuyi 			pScan = new CRKScan();
73876af099aSliuyi 			if (pScan) {
73976af099aSliuyi 				pScan->SetVidPid();
74076af099aSliuyi 				pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
74176af099aSliuyi 				delete pScan;
74276af099aSliuyi 			}
74376af099aSliuyi 			bSuccess = true;
74476af099aSliuyi 			printf("Download boot ok.\r\n");
74576af099aSliuyi 		}
74676af099aSliuyi 		else
74776af099aSliuyi 			printf("Download boot failed!\r\n");
74876af099aSliuyi 
74976af099aSliuyi 		if (pImage)
75076af099aSliuyi 			delete pImage;
75176af099aSliuyi 		if(pDevice)
75276af099aSliuyi 			delete pDevice;
75376af099aSliuyi 	}
75476af099aSliuyi 	return bSuccess;
75576af099aSliuyi }
756*c30d921cSKever Yang bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader)
757*c30d921cSKever Yang {
758*c30d921cSKever Yang 	if (!check_device_type(dev, RKUSB_MASKROM))
759*c30d921cSKever Yang 		return false;
760*c30d921cSKever Yang 	CRKImage *pImage = NULL;
761*c30d921cSKever Yang 	CRKBoot *pBoot = NULL;
762*c30d921cSKever Yang 	CRKComm *pComm = NULL;
763*c30d921cSKever Yang 	bool bRet, bSuccess = false;
764*c30d921cSKever Yang 	int iRet;
765*c30d921cSKever Yang 	char index;
766*c30d921cSKever Yang 	USHORT usFlashDataSec, usFlashBootSec;
767*c30d921cSKever Yang 	DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum;
768*c30d921cSKever Yang 	char loaderCodeName[] = "FlashBoot";
769*c30d921cSKever Yang 	char loaderDataName[] = "FlashData";
770*c30d921cSKever Yang 	PBYTE loaderCodeBuffer = NULL;
771*c30d921cSKever Yang 	PBYTE loaderDataBuffer = NULL;
772*c30d921cSKever Yang 	PBYTE pIDBData = NULL;
773*c30d921cSKever Yang 	pImage = new CRKImage(szLoader, bRet);
774*c30d921cSKever Yang 	if (!bRet){
775*c30d921cSKever Yang 		ERROR_COLOR_ATTR;
776*c30d921cSKever Yang 		printf("Open loader failed,exit upgrade loader!");
777*c30d921cSKever Yang 		NORMAL_COLOR_ATTR;
778*c30d921cSKever Yang 		printf("\r\n");
779*c30d921cSKever Yang 		goto Exit_UpgradeLoader;
780*c30d921cSKever Yang 	} else {
781*c30d921cSKever Yang 		pBoot = (CRKBoot *)pImage->m_bootObject;
782*c30d921cSKever Yang 		dev.emDeviceType = pBoot->SupportDevice;
783*c30d921cSKever Yang 		pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
784*c30d921cSKever Yang 		if (!bRet) {
785*c30d921cSKever Yang 			ERROR_COLOR_ATTR;
786*c30d921cSKever Yang 			printf("Creating Comm Object failed!");
787*c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
788*c30d921cSKever Yang 			printf("\r\n");
789*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
790*c30d921cSKever Yang 		}
791*c30d921cSKever Yang 
792*c30d921cSKever Yang 		printf("Upgrade loader...\r\n");
793*c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName);
794*c30d921cSKever Yang 		if (index == -1) {
795*c30d921cSKever Yang 			if (g_pLogObject) {
796*c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry failed");
797*c30d921cSKever Yang 			}
798*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
799*c30d921cSKever Yang 		}
800*c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay);
801*c30d921cSKever Yang 		if (!bRet) {
802*c30d921cSKever Yang 			if (g_pLogObject) {
803*c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Entry Size failed");
804*c30d921cSKever Yang 			}
805*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
806*c30d921cSKever Yang 		}
807*c30d921cSKever Yang 
808*c30d921cSKever Yang 		loaderCodeBuffer = new BYTE[dwLoaderSize];
809*c30d921cSKever Yang 		memset(loaderCodeBuffer, 0, dwLoaderSize);
810*c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) {
811*c30d921cSKever Yang 			if (g_pLogObject) {
812*c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderCode Data failed");
813*c30d921cSKever Yang 			}
814*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
815*c30d921cSKever Yang 		}
816*c30d921cSKever Yang 
817*c30d921cSKever Yang 		index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName);
818*c30d921cSKever Yang 		if (index == -1) {
819*c30d921cSKever Yang 			if (g_pLogObject) {
820*c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry failed");
821*c30d921cSKever Yang 			}
822*c30d921cSKever Yang 			delete []loaderCodeBuffer;
823*c30d921cSKever Yang 			return -4;
824*c30d921cSKever Yang 		}
825*c30d921cSKever Yang 
826*c30d921cSKever Yang 		bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay);
827*c30d921cSKever Yang 		if (!bRet) {
828*c30d921cSKever Yang 			if (g_pLogObject) {
829*c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Entry Size failed");
830*c30d921cSKever Yang 			}
831*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
832*c30d921cSKever Yang 		}
833*c30d921cSKever Yang 
834*c30d921cSKever Yang 		loaderDataBuffer = new BYTE[dwLoaderDataSize];
835*c30d921cSKever Yang 		memset(loaderDataBuffer, 0, dwLoaderDataSize);
836*c30d921cSKever Yang 		if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) {
837*c30d921cSKever Yang 			if (g_pLogObject) {
838*c30d921cSKever Yang 				g_pLogObject->Record("ERROR:upgrade_loader-->Get LoaderData Data failed");
839*c30d921cSKever Yang 			}
840*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
841*c30d921cSKever Yang 		}
842*c30d921cSKever Yang 
843*c30d921cSKever Yang 		usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE;
844*c30d921cSKever Yang 		usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE;
845*c30d921cSKever Yang 		dwSectorNum = 4 + usFlashDataSec + usFlashBootSec;
846*c30d921cSKever Yang 		pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
847*c30d921cSKever Yang 		if (!pIDBData) {
848*c30d921cSKever Yang 			ERROR_COLOR_ATTR;
849*c30d921cSKever Yang 			printf("New memory failed!");
850*c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
851*c30d921cSKever Yang 			printf("\r\n");
852*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
853*c30d921cSKever Yang 		}
854*c30d921cSKever Yang 		memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE);
855*c30d921cSKever Yang 		iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize);
856*c30d921cSKever Yang 		if (iRet != 0) {
857*c30d921cSKever Yang 			ERROR_COLOR_ATTR;
858*c30d921cSKever Yang 			printf("Make idblock failed!");
859*c30d921cSKever Yang 			NORMAL_COLOR_ATTR;
860*c30d921cSKever Yang 			printf("\r\n");
861*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
862*c30d921cSKever Yang 		}
863*c30d921cSKever Yang 		iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData);
864*c30d921cSKever Yang 		CURSOR_MOVEUP_LINE(1);
865*c30d921cSKever Yang 		CURSOR_DEL_LINE;
866*c30d921cSKever Yang 		if (iRet == ERR_SUCCESS) {
867*c30d921cSKever Yang 			pComm->Reset_Usb_Device();
868*c30d921cSKever Yang 			bSuccess = true;
869*c30d921cSKever Yang 			printf("Upgrade loader ok.\r\n");
870*c30d921cSKever Yang 		} else {
871*c30d921cSKever Yang 			printf("Upgrade loader failed!\r\n");
872*c30d921cSKever Yang 			goto Exit_UpgradeLoader;
873*c30d921cSKever Yang 		}
874*c30d921cSKever Yang 	}
875*c30d921cSKever Yang Exit_UpgradeLoader:
876*c30d921cSKever Yang 	if (pImage)
877*c30d921cSKever Yang 		delete pImage;
878*c30d921cSKever Yang 	if (pComm)
879*c30d921cSKever Yang 		delete pComm;
880*c30d921cSKever Yang 	if (loaderCodeBuffer)
881*c30d921cSKever Yang 		delete []loaderCodeBuffer;
882*c30d921cSKever Yang 	if (loaderDataBuffer)
883*c30d921cSKever Yang 		delete []loaderDataBuffer;
884*c30d921cSKever Yang 	if (pIDBData)
885*c30d921cSKever Yang 		delete []pIDBData;
886*c30d921cSKever Yang 	return bSuccess;
887*c30d921cSKever Yang }
888*c30d921cSKever Yang 
88976af099aSliuyi bool erase_flash(STRUCT_RKDEVICE_DESC &dev)
89076af099aSliuyi {
89176af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
89276af099aSliuyi 		return false;
89376af099aSliuyi 	CRKImage *pImage = NULL;
89476af099aSliuyi 	bool bRet, bSuccess = false;
89576af099aSliuyi 	int iRet;
89676af099aSliuyi 	CRKScan *pScan = NULL;
89776af099aSliuyi 	pScan = new CRKScan();
89876af099aSliuyi 	pScan->SetVidPid();
89976af099aSliuyi 
90076af099aSliuyi 	CRKComm *pComm = NULL;
90176af099aSliuyi 	CRKDevice *pDevice = NULL;
90276af099aSliuyi 
90376af099aSliuyi 	pComm = new CRKUsbComm(dev, g_pLogObject, bRet);
90476af099aSliuyi 	if (!bRet) {
90576af099aSliuyi 		if (pScan)
90676af099aSliuyi 			delete pScan;
90776af099aSliuyi 		ERROR_COLOR_ATTR;
90876af099aSliuyi 		printf("Creating Comm Object failed!");
90976af099aSliuyi 		NORMAL_COLOR_ATTR;
91076af099aSliuyi 		printf("\r\n");
91176af099aSliuyi 		return bSuccess;
91276af099aSliuyi 	}
91376af099aSliuyi 
91476af099aSliuyi 	pDevice = new CRKDevice(dev);
91576af099aSliuyi 	if (!pDevice) {
91676af099aSliuyi 		if (pComm)
91776af099aSliuyi 			delete pComm;
91876af099aSliuyi 		if (pScan)
91976af099aSliuyi 			delete pScan;
92076af099aSliuyi 		ERROR_COLOR_ATTR;
92176af099aSliuyi 		printf("Creating device object failed!");
92276af099aSliuyi 		NORMAL_COLOR_ATTR;
92376af099aSliuyi 		printf("\r\n");
92476af099aSliuyi 		return bSuccess;
92576af099aSliuyi 	}
92676af099aSliuyi 
92776af099aSliuyi 	pDevice->SetObject(pImage, pComm, g_pLogObject);
92876af099aSliuyi 	pDevice->CallBackPointer = ProgressInfoProc;
92976af099aSliuyi 
93076af099aSliuyi 	printf("Start to erase flash...\r\n");
93176af099aSliuyi 	iRet = pDevice->EraseAllBlocks();
93276af099aSliuyi 	if (pDevice)
93376af099aSliuyi 		delete pDevice;
93476af099aSliuyi 
93576af099aSliuyi 	if (iRet == 0) {
93676af099aSliuyi 		if (pScan) {
93776af099aSliuyi 			pScan->SetVidPid();
93876af099aSliuyi 			pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid);
93976af099aSliuyi 			delete pScan;
94076af099aSliuyi 		}
94176af099aSliuyi 		CURSOR_MOVEUP_LINE(1);
94276af099aSliuyi 		CURSOR_DEL_LINE;
94376af099aSliuyi 		bSuccess = true;
94476af099aSliuyi 		printf("Erase flash ok.\r\n");
94576af099aSliuyi 	}
94676af099aSliuyi 
94776af099aSliuyi 	return bSuccess;
94876af099aSliuyi }
94976af099aSliuyi 
95076af099aSliuyi bool test_device(STRUCT_RKDEVICE_DESC &dev)
95176af099aSliuyi {
95276af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
95376af099aSliuyi 		return false;
95476af099aSliuyi 	CRKUsbComm *pComm = NULL;
95576af099aSliuyi 	bool bRet, bSuccess = false;
95676af099aSliuyi 	int iRet;
95776af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
95876af099aSliuyi 	if (bRet) {
95976af099aSliuyi 		iRet = pComm->RKU_TestDeviceReady();
96076af099aSliuyi 		if (iRet != ERR_SUCCESS) {
96176af099aSliuyi 			if (g_pLogObject)
96276af099aSliuyi 				g_pLogObject->Record("Error:RKU_TestDeviceReady failed,err=%d", iRet);
96376af099aSliuyi 			printf("Test Device Fail!\r\n");
96476af099aSliuyi 		} else {
96576af099aSliuyi 			bSuccess = true;
96676af099aSliuyi 			printf("Test Device OK.\r\n");
96776af099aSliuyi 		}
96876af099aSliuyi 	} else {
96976af099aSliuyi 		printf("Test Device quit,Creating comm object failed!\r\n");
97076af099aSliuyi 	}
97176af099aSliuyi 	if (pComm) {
97276af099aSliuyi 		delete pComm;
97376af099aSliuyi 		pComm = NULL;
97476af099aSliuyi 	}
97576af099aSliuyi 	return bSuccess;
97676af099aSliuyi }
97776af099aSliuyi bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE)
97876af099aSliuyi {
97976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
98076af099aSliuyi 		return false;
98176af099aSliuyi 	CRKUsbComm *pComm = NULL;
98276af099aSliuyi 	bool bRet, bSuccess = false;
98376af099aSliuyi 	int iRet;
98476af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
98576af099aSliuyi 	if (bRet) {
98676af099aSliuyi 		iRet = pComm->RKU_ResetDevice(subCode);
98776af099aSliuyi 		if (iRet != ERR_SUCCESS) {
98876af099aSliuyi 			if (g_pLogObject)
98976af099aSliuyi 				g_pLogObject->Record("Error:RKU_ResetDevice failed,err=%d", iRet);
99076af099aSliuyi 			printf("Reset Device Fail!\r\n");
99176af099aSliuyi 		} else {
99276af099aSliuyi 			bSuccess = true;
99376af099aSliuyi 			printf("Reset Device OK.\r\n");
99476af099aSliuyi 		}
99576af099aSliuyi 	} else {
99676af099aSliuyi 		printf("Reset Device quit,Creating comm object failed!\r\n");
99776af099aSliuyi 	}
99876af099aSliuyi 	if (pComm) {
99976af099aSliuyi 		delete pComm;
100076af099aSliuyi 		pComm = NULL;
100176af099aSliuyi 	}
100276af099aSliuyi 	return bSuccess;
100376af099aSliuyi }
100476af099aSliuyi 
100576af099aSliuyi bool read_flash_id(STRUCT_RKDEVICE_DESC &dev)
100676af099aSliuyi {
100776af099aSliuyi 	CRKUsbComm *pComm = NULL;
100876af099aSliuyi 	bool bRet, bSuccess = false;
100976af099aSliuyi 	int iRet;
101076af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
101176af099aSliuyi 		return bSuccess;
101276af099aSliuyi 
101376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
101476af099aSliuyi 	if (bRet) {
101576af099aSliuyi 		BYTE flashID[5];
101676af099aSliuyi 		iRet = pComm->RKU_ReadFlashID(flashID);
101776af099aSliuyi 		if (iRet != ERR_SUCCESS) {
101876af099aSliuyi 			if (g_pLogObject)
101976af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadFlashID failed,err=%d", iRet);
102076af099aSliuyi 			printf("Read flash ID Fail!\r\n");
102176af099aSliuyi 		} else {
102276af099aSliuyi 			printf("Flash ID:%02X %02X %02X %02X %02X \r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]);
102376af099aSliuyi 			bSuccess = true;
102476af099aSliuyi 		}
102576af099aSliuyi 	} else {
102676af099aSliuyi 		printf("Read flash ID quit,Creating comm object failed!\r\n");
102776af099aSliuyi 	}
102876af099aSliuyi 	if (pComm) {
102976af099aSliuyi 		delete pComm;
103076af099aSliuyi 		pComm = NULL;
103176af099aSliuyi 	}
103276af099aSliuyi 	return bSuccess;
103376af099aSliuyi }
103476af099aSliuyi bool read_flash_info(STRUCT_RKDEVICE_DESC &dev)
103576af099aSliuyi {
103676af099aSliuyi 	CRKUsbComm *pComm = NULL;
103776af099aSliuyi 	bool bRet, bSuccess = false;
103876af099aSliuyi 	int iRet;
103976af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
104076af099aSliuyi 		return bSuccess;
104176af099aSliuyi 
104276af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
104376af099aSliuyi 	if (bRet) {
104476af099aSliuyi 		STRUCT_FLASHINFO_CMD info;
104576af099aSliuyi 		UINT uiRead;
104676af099aSliuyi 		iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead);
104776af099aSliuyi 		if (iRet != ERR_SUCCESS) {
104876af099aSliuyi 			if (g_pLogObject)
104976af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadFlashInfo failed,err=%d", iRet);
105076af099aSliuyi 			printf("Read flash Info Fail!\r\n");
105176af099aSliuyi 		} else {
105276af099aSliuyi 			printf("Flash Info:\r\n");
105376af099aSliuyi 			if (info.bManufCode <= 7) {
105476af099aSliuyi 				printf("\tManufacturer: %s,value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode);
105576af099aSliuyi 			}
105676af099aSliuyi 			else
105776af099aSliuyi 				printf("\tManufacturer: %s,value=%02X\r\n", "Unknown", info.bManufCode);
105876af099aSliuyi 
105976af099aSliuyi 			printf("\tFlash Size: %dMB\r\n", info.uiFlashSize / 2 / 1024);
106076af099aSliuyi 			printf("\tBlock Size: %dKB\r\n", info.usBlockSize / 2);
106176af099aSliuyi 			printf("\tPage Size: %dKB\r\n", info.bPageSize / 2);
106276af099aSliuyi 			printf("\tECC Bits: %d\r\n", info.bECCBits);
106376af099aSliuyi 			printf("\tAccess Time: %d\r\n", info.bAccessTime);
106476af099aSliuyi 			printf("\tFlash CS: ");
106576af099aSliuyi 			for(int i = 0; i < 8; i++) {
106676af099aSliuyi 				if( info.bFlashCS & (1 << i) )
106776af099aSliuyi 					printf("Flash<%d> ", i);
106876af099aSliuyi 			}
106976af099aSliuyi 			printf("\r\n");
107076af099aSliuyi 			bSuccess = true;
107176af099aSliuyi 		}
107276af099aSliuyi 	}else {
107376af099aSliuyi 		printf("Read flash Info quit,Creating comm object failed!\r\n");
107476af099aSliuyi 	}
107576af099aSliuyi 	if (pComm) {
107676af099aSliuyi 		delete pComm;
107776af099aSliuyi 		pComm = NULL;
107876af099aSliuyi 	}
107976af099aSliuyi 	return bSuccess;
108076af099aSliuyi }
108176af099aSliuyi bool read_chip_info(STRUCT_RKDEVICE_DESC &dev)
108276af099aSliuyi {
108376af099aSliuyi 	CRKUsbComm *pComm = NULL;
108476af099aSliuyi 	bool bRet, bSuccess = false;
108576af099aSliuyi 	int iRet;
108676af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
108776af099aSliuyi 		return bSuccess;
108876af099aSliuyi 
108976af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
109076af099aSliuyi 	if (bRet) {
109176af099aSliuyi 		BYTE chipInfo[16];
109276af099aSliuyi 		iRet = pComm->RKU_ReadChipInfo(chipInfo);
109376af099aSliuyi 		if (iRet != ERR_SUCCESS) {
109476af099aSliuyi 			if (g_pLogObject)
109576af099aSliuyi 				g_pLogObject->Record("Error:RKU_ReadChipInfo failed,err=%d", iRet);
109676af099aSliuyi 			printf("Read Chip Info Fail!\r\n");
109776af099aSliuyi 		} else {
109876af099aSliuyi 			string strChipInfo;
109976af099aSliuyi 			g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16);
110076af099aSliuyi 			printf("Chip Info:%s\r\n", strChipInfo.c_str());
110176af099aSliuyi 			bSuccess = true;
110276af099aSliuyi 		}
110376af099aSliuyi 	} else {
110476af099aSliuyi 		printf("Read Chip Info quit,Creating comm object failed!\r\n");
110576af099aSliuyi 	}
110676af099aSliuyi 	if (pComm) {
110776af099aSliuyi 		delete pComm;
110876af099aSliuyi 		pComm = NULL;
110976af099aSliuyi 	}
111076af099aSliuyi 	return bSuccess;
111176af099aSliuyi }
111276af099aSliuyi bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile)
111376af099aSliuyi {
111476af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
111576af099aSliuyi 		return false;
111676af099aSliuyi 	CRKUsbComm *pComm = NULL;
111776af099aSliuyi 	FILE *file = NULL;
111876af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
111976af099aSliuyi 	int iRet;
112076af099aSliuyi 	UINT iTotalRead = 0,iRead = 0;
112176af099aSliuyi 	int nSectorSize = 512;
112276af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
112376af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
112476af099aSliuyi 	if (bRet) {
112576af099aSliuyi 		if(szFile) {
112676af099aSliuyi 			file = fopen(szFile, "wb+");
112776af099aSliuyi 			if( !file ) {
112876af099aSliuyi 				printf("Read LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
112976af099aSliuyi 				goto Exit_ReadLBA;
113076af099aSliuyi 			}
113176af099aSliuyi 		}
113276af099aSliuyi 
113376af099aSliuyi 		while(uiLen > 0) {
113476af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
113576af099aSliuyi 			iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen;
113676af099aSliuyi 			iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf);
113776af099aSliuyi 			if(ERR_SUCCESS == iRet) {
113876af099aSliuyi 				uiLen -= iRead;
113976af099aSliuyi 				iTotalRead += iRead;
114076af099aSliuyi 
114176af099aSliuyi 				if(szFile) {
114276af099aSliuyi 					fwrite(pBuf, 1, iRead * nSectorSize, file);
114376af099aSliuyi 					if (bFirst){
114476af099aSliuyi 						if (iTotalRead >= 1024)
114576af099aSliuyi 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
114676af099aSliuyi 						else
114776af099aSliuyi 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
114876af099aSliuyi 						bFirst = false;
114976af099aSliuyi 					} else {
115076af099aSliuyi 						CURSOR_MOVEUP_LINE(1);
115176af099aSliuyi 						CURSOR_DEL_LINE;
115276af099aSliuyi 						if (iTotalRead >= 1024)
115376af099aSliuyi 							printf("Read LBA from file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024));
115476af099aSliuyi 						else
115576af099aSliuyi 							printf("Read LBA from file %d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead));
115676af099aSliuyi 					}
115776af099aSliuyi 				}
115876af099aSliuyi 				else
115976af099aSliuyi 					PrintData(pBuf, nSectorSize * iRead);
116076af099aSliuyi 			} else {
116176af099aSliuyi 				if (g_pLogObject)
116276af099aSliuyi 					g_pLogObject->Record("Error:RKU_ReadLBA failed,err=%d", iRet);
116376af099aSliuyi 
116476af099aSliuyi 				printf("Read LBA failed!\r\n");
116576af099aSliuyi 				goto Exit_ReadLBA;
116676af099aSliuyi 			}
116776af099aSliuyi 		}
116876af099aSliuyi 		bSuccess = true;
116976af099aSliuyi 	} else {
117076af099aSliuyi 		printf("Read LBA quit,Creating comm object failed!\r\n");
117176af099aSliuyi 	}
117276af099aSliuyi Exit_ReadLBA:
117376af099aSliuyi 	if (pComm) {
117476af099aSliuyi 		delete pComm;
117576af099aSliuyi 		pComm = NULL;
117676af099aSliuyi 	}
117776af099aSliuyi 	if (file)
117876af099aSliuyi 		fclose(file);
117976af099aSliuyi 	return bSuccess;
118076af099aSliuyi }
118176af099aSliuyi bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile)
118276af099aSliuyi {
118376af099aSliuyi 	if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM))
118476af099aSliuyi 		return false;
118576af099aSliuyi 	CRKUsbComm *pComm = NULL;
118676af099aSliuyi 	FILE *file = NULL;
118776af099aSliuyi 	bool bRet, bFirst = true, bSuccess = false;
118876af099aSliuyi 	int iRet;
118976af099aSliuyi 	long long iTotalWrite = 0, iFileSize = 0;
119076af099aSliuyi 	UINT iWrite = 0, iRead = 0;
119176af099aSliuyi 	UINT uiLen;
119276af099aSliuyi 	int nSectorSize = 512;
119376af099aSliuyi 	BYTE pBuf[nSectorSize * DEFAULT_RW_LBA];
119476af099aSliuyi 
119576af099aSliuyi 	pComm =  new CRKUsbComm(dev, g_pLogObject, bRet);
119676af099aSliuyi 	if (bRet) {
119776af099aSliuyi 		file = fopen(szFile, "rb");
119876af099aSliuyi 		if( !file ) {
119976af099aSliuyi 			printf("Write LBA failed,err=%d,can't open file: %s\r\n", errno, szFile);
120076af099aSliuyi 			goto Exit_WriteLBA;
120176af099aSliuyi 		}
120276af099aSliuyi 
120376af099aSliuyi 		iRet = fseeko(file, 0, SEEK_END);
120476af099aSliuyi 		iFileSize = ftello(file);
120576af099aSliuyi 		fseeko(file, 0, SEEK_SET);
120676af099aSliuyi 		while(iTotalWrite < iFileSize) {
120776af099aSliuyi 			memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA);
120876af099aSliuyi 			iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file);
120976af099aSliuyi 			uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1);
121076af099aSliuyi 			iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf);
121176af099aSliuyi 			if(ERR_SUCCESS == iRet) {
121276af099aSliuyi 				uiBegin += uiLen;
121376af099aSliuyi 				iTotalWrite += iWrite;
121476af099aSliuyi 				if (bFirst) {
121576af099aSliuyi 					if (iTotalWrite >= 1024)
121676af099aSliuyi 						printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
121776af099aSliuyi 					else
121876af099aSliuyi 						printf("Write LBA from file %lld%%)\r\n", iTotalWrite * 100 / iFileSize);
121976af099aSliuyi 					bFirst = false;
122076af099aSliuyi 				} else {
122176af099aSliuyi 					CURSOR_MOVEUP_LINE(1);
122276af099aSliuyi 					CURSOR_DEL_LINE;
122376af099aSliuyi 					printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024));
122476af099aSliuyi 				}
122576af099aSliuyi 			} else {
122676af099aSliuyi 				if (g_pLogObject)
122776af099aSliuyi 					g_pLogObject->Record("Error:RKU_WriteLBA failed,err=%d", iRet);
122876af099aSliuyi 
122976af099aSliuyi 				printf("Write LBA failed!\r\n");
123076af099aSliuyi 				goto Exit_WriteLBA;
123176af099aSliuyi 			}
123276af099aSliuyi 		}
123376af099aSliuyi 		bSuccess = true;
123476af099aSliuyi 	} else {
123576af099aSliuyi 		printf("Write LBA quit,Creating comm object failed!\r\n");
123676af099aSliuyi 	}
123776af099aSliuyi Exit_WriteLBA:
123876af099aSliuyi 	if (pComm) {
123976af099aSliuyi 		delete pComm;
124076af099aSliuyi 		pComm = NULL;
124176af099aSliuyi 	}
124276af099aSliuyi 	if (file)
124376af099aSliuyi 		fclose(file);
124476af099aSliuyi 	return bSuccess;
124576af099aSliuyi }
124676af099aSliuyi 
124776af099aSliuyi void split_item(STRING_VECTOR &vecItems, char *pszItems)
124876af099aSliuyi {
124976af099aSliuyi 	string strItem;
125076af099aSliuyi 	char szItem[100];
125176af099aSliuyi 	char *pos = NULL, *pStart;
125276af099aSliuyi 	pStart = pszItems;
125376af099aSliuyi 	pos = strchr(pStart, ',');
125476af099aSliuyi 	while(pos != NULL) {
125576af099aSliuyi 		memset(szItem, 0, 100);
125676af099aSliuyi 		strncpy(szItem, pStart, pos - pStart);
125776af099aSliuyi 		strItem = szItem;
125876af099aSliuyi 		vecItems.push_back(strItem);
125976af099aSliuyi 		pStart = pos + 1;
126076af099aSliuyi 		if (*pStart == 0)
126176af099aSliuyi 			break;
126276af099aSliuyi 		pos = strchr(pStart, ',');
126376af099aSliuyi 	}
126476af099aSliuyi 	if (strlen(pStart) > 0) {
126576af099aSliuyi 		memset(szItem, 0, 100);
126676af099aSliuyi 		strncpy(szItem, pStart, strlen(pStart));
126776af099aSliuyi 		strItem = szItem;
126876af099aSliuyi 		vecItems.push_back(strItem);
126976af099aSliuyi 	}
127076af099aSliuyi }
1271*c30d921cSKever Yang 
127276af099aSliuyi bool handle_command(int argc, char* argv[], CRKScan *pScan)
127376af099aSliuyi {
127476af099aSliuyi 	string strCmd;
127576af099aSliuyi 	strCmd = argv[1];
127676af099aSliuyi 	ssize_t cnt;
127776af099aSliuyi 	bool bRet,bSuccess = false;
127876af099aSliuyi 	int ret;
127976af099aSliuyi 	STRUCT_RKDEVICE_DESC dev;
128076af099aSliuyi 
128176af099aSliuyi 	transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper);
128276af099aSliuyi 	if(strcmp(strCmd.c_str(), "-H") == 0) {
128376af099aSliuyi 		usage();
128476af099aSliuyi 		return true;
128576af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "-V") == 0) {
1286*c30d921cSKever Yang 		printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION);
128776af099aSliuyi 		return true;
128876af099aSliuyi 	}
128976af099aSliuyi 	cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER);
129076af099aSliuyi 	if (cnt < 1) {
129176af099aSliuyi 		ERROR_COLOR_ATTR;
129276af099aSliuyi 		printf("No found any rockusb device,please plug device in!");
129376af099aSliuyi 		NORMAL_COLOR_ATTR;
129476af099aSliuyi 		printf("\r\n");
129576af099aSliuyi 		return bSuccess;
129676af099aSliuyi 	} else if (cnt > 1) {
129776af099aSliuyi 		ERROR_COLOR_ATTR;
129876af099aSliuyi 		printf("Found many rockusb devices,please plug device out!");
129976af099aSliuyi 		NORMAL_COLOR_ATTR;
130076af099aSliuyi 		printf("\r\n");
130176af099aSliuyi 		return bSuccess;
130276af099aSliuyi 	}
130376af099aSliuyi 
130476af099aSliuyi 	bRet = pScan->GetDevice(dev, 0);
130576af099aSliuyi 	if (!bRet) {
130676af099aSliuyi 		ERROR_COLOR_ATTR;
130776af099aSliuyi 		printf("Getting information of rockusb device failed!");
130876af099aSliuyi 		NORMAL_COLOR_ATTR;
130976af099aSliuyi 		printf("\r\n");
131076af099aSliuyi 		return bSuccess;
131176af099aSliuyi 	}
131276af099aSliuyi 
131376af099aSliuyi 	if(strcmp(strCmd.c_str(), "RD") == 0) {
131476af099aSliuyi 		if ((argc != 2) && (argc != 3))
131576af099aSliuyi 			printf("Parameter of [RD] command is invalid,please check help!\r\n");
131676af099aSliuyi 		else {
131776af099aSliuyi 			if (argc == 2)
131876af099aSliuyi 				bSuccess = reset_device(dev);
131976af099aSliuyi 			else {
132076af099aSliuyi 				UINT uiSubCode;
132176af099aSliuyi 				char *pszEnd;
132276af099aSliuyi 				uiSubCode = strtoul(argv[2], &pszEnd, 0);
132376af099aSliuyi 				if (*pszEnd)
132476af099aSliuyi 					printf("Subcode is invalid,please check!\r\n");
132576af099aSliuyi 				else {
132676af099aSliuyi 					if (uiSubCode <= 5)
132776af099aSliuyi 						bSuccess = reset_device(dev, uiSubCode);
132876af099aSliuyi 					else
132976af099aSliuyi 						printf("Subcode is invalid,please check!\r\n");
133076af099aSliuyi 				}
133176af099aSliuyi 			}
133276af099aSliuyi 		}
133376af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "TD") == 0) {
133476af099aSliuyi 		bSuccess = test_device(dev);
133576af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID
133676af099aSliuyi 		bSuccess = read_flash_id(dev);
133776af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info
133876af099aSliuyi 		bSuccess = read_flash_info(dev);
133976af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info
134076af099aSliuyi 		bSuccess = read_chip_info(dev);
134176af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "DB") == 0) {
134276af099aSliuyi 		if (argc > 2) {
134376af099aSliuyi 			string strLoader;
134476af099aSliuyi 			strLoader = argv[2];
134576af099aSliuyi 			bSuccess = download_boot(dev, (char *)strLoader.c_str());
134676af099aSliuyi 		} else if (argc == 2) {
134776af099aSliuyi 			ret = find_config_item("loader");
134876af099aSliuyi 			if (ret == -1)
134976af099aSliuyi 				printf("No found loader item from config!\r\n");
135076af099aSliuyi 			else
135176af099aSliuyi 				bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue);
135276af099aSliuyi 		} else
135376af099aSliuyi 			printf("Parameter of [DB] command is invalid,please check help!\r\n");
1354*c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "GPT") == 0) {
1355*c30d921cSKever Yang 		if (argc > 2) {
1356*c30d921cSKever Yang 			string strParameter;
1357*c30d921cSKever Yang 			strParameter = argv[2];
1358*c30d921cSKever Yang 			bSuccess = write_gpt(dev, (char *)strParameter.c_str());
1359*c30d921cSKever Yang 		} else
1360*c30d921cSKever Yang 			printf("Parameter of [GPT] command is invalid,please check help!\r\n");
1361*c30d921cSKever Yang 	} else if(strcmp(strCmd.c_str(), "UL") == 0) {
1362*c30d921cSKever Yang 		if (argc > 2) {
1363*c30d921cSKever Yang 			string strLoader;
1364*c30d921cSKever Yang 			strLoader = argv[2];
1365*c30d921cSKever Yang 			bSuccess = upgrade_loader(dev, (char *)strLoader.c_str());
1366*c30d921cSKever Yang 		} else
1367*c30d921cSKever Yang 			printf("Parameter of [UL] command is invalid,please check help!\r\n");
136876af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "EF") == 0) {
136976af099aSliuyi 		if (argc == 2) {
137076af099aSliuyi 			bSuccess = erase_flash(dev);
137176af099aSliuyi 		} else
137276af099aSliuyi 			printf("Parameter of [EF] command is invalid,please check help!\r\n");
137376af099aSliuyi 	} else if(strcmp(strCmd.c_str(), "WL") == 0) {
137476af099aSliuyi 		if (argc == 4) {
137576af099aSliuyi 			UINT uiBegin;
137676af099aSliuyi 			char *pszEnd;
137776af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
137876af099aSliuyi 			if (*pszEnd)
137976af099aSliuyi 				printf("Begin is invalid,please check!\r\n");
138076af099aSliuyi 			else
138176af099aSliuyi 				bSuccess = write_lba(dev, uiBegin, argv[3]);
138276af099aSliuyi 		} else
138376af099aSliuyi 			printf("Parameter of [WL] command is invalid,please check help!\r\n");
138476af099aSliuyi 	} else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA
138576af099aSliuyi 		char *pszEnd;
138676af099aSliuyi 		UINT uiBegin, uiLen;
138776af099aSliuyi 		if (argc != 5)
138876af099aSliuyi 			printf("Parameter of [RL] command is invalid,please check help!\r\n");
138976af099aSliuyi 		else {
139076af099aSliuyi 			uiBegin = strtoul(argv[2], &pszEnd, 0);
139176af099aSliuyi 			if (*pszEnd)
139276af099aSliuyi 				printf("Begin is invalid,please check!\r\n");
139376af099aSliuyi 			else {
139476af099aSliuyi 				uiLen = strtoul(argv[3], &pszEnd, 0);
139576af099aSliuyi 				if (*pszEnd)
139676af099aSliuyi 					printf("Len is invalid,please check!\r\n");
139776af099aSliuyi 				else {
139876af099aSliuyi 					bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]);
139976af099aSliuyi 				}
140076af099aSliuyi 			}
140176af099aSliuyi 		}
140276af099aSliuyi 	} else {
1403*c30d921cSKever Yang 		printf("command is invalid,please press rkDevelopTool -h to check usage!\r\n");
140476af099aSliuyi 	}
140576af099aSliuyi 	return bSuccess;
140676af099aSliuyi }
140776af099aSliuyi 
140876af099aSliuyi 
140976af099aSliuyi int main(int argc, char* argv[])
141076af099aSliuyi {
141176af099aSliuyi 	CRKScan *pScan = NULL;
141276af099aSliuyi 	int ret;
141376af099aSliuyi 	char szProgramProcPath[100];
141476af099aSliuyi 	char szProgramDir[256];
141576af099aSliuyi 	string strLogDir,strConfigFile;
141676af099aSliuyi 	struct stat statBuf;
141776af099aSliuyi 
141876af099aSliuyi 	g_ConfigItemVec.clear();
141976af099aSliuyi 	sprintf(szProgramProcPath, "/proc/%d/exe", getpid());
142076af099aSliuyi 	if (readlink(szProgramProcPath, szProgramDir, 256) == -1)
142176af099aSliuyi 		strcpy(szProgramDir, ".");
142276af099aSliuyi 	else {
142376af099aSliuyi 		char *pSlash;
142476af099aSliuyi 		pSlash = strrchr(szProgramDir, '/');
142576af099aSliuyi 		if (pSlash)
142676af099aSliuyi 			*pSlash = '\0';
142776af099aSliuyi 	}
142876af099aSliuyi 	strLogDir = szProgramDir;
142976af099aSliuyi 	strLogDir +=  "/log/";
143076af099aSliuyi 	strConfigFile = szProgramDir;
143176af099aSliuyi 	strConfigFile += "/config.ini";
143276af099aSliuyi 	if (opendir(strLogDir.c_str()) == NULL)
143376af099aSliuyi 		mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH);
143476af099aSliuyi 	g_pLogObject = new CRKLog(strLogDir.c_str(), "log");
143576af099aSliuyi 
143676af099aSliuyi 	if(stat(strConfigFile.c_str(), &statBuf) < 0) {
143776af099aSliuyi 		if (g_pLogObject) {
143876af099aSliuyi 			g_pLogObject->Record("Error:failed to stat config.ini,err=%d", errno);
143976af099aSliuyi 		}
144076af099aSliuyi 	} else if (S_ISREG(statBuf.st_mode)) {
144176af099aSliuyi 		parse_config_file(strConfigFile.c_str(), g_ConfigItemVec);
144276af099aSliuyi 	}
144376af099aSliuyi 
144476af099aSliuyi 	ret = libusb_init(NULL);
144576af099aSliuyi 	if (ret < 0) {
144676af099aSliuyi 		if (g_pLogObject) {
144776af099aSliuyi 			g_pLogObject->Record("Error:libusb_init failed,err=%d", ret);
144876af099aSliuyi 			delete g_pLogObject;
144976af099aSliuyi 		}
145076af099aSliuyi 		return -1;
145176af099aSliuyi 	}
145276af099aSliuyi 
145376af099aSliuyi 	pScan = new CRKScan();
145476af099aSliuyi 	if (!pScan) {
145576af099aSliuyi 		if (g_pLogObject) {
145676af099aSliuyi 			g_pLogObject->Record("Error:failed to Create object for searching device");
145776af099aSliuyi 			delete g_pLogObject;
145876af099aSliuyi 		}
145976af099aSliuyi 		libusb_exit(NULL);
146076af099aSliuyi 		return -2;
146176af099aSliuyi 	}
146276af099aSliuyi 	pScan->SetVidPid();
146376af099aSliuyi 
146476af099aSliuyi 	if (argc == 1)
146576af099aSliuyi 		usage();
146676af099aSliuyi 	else if (!handle_command(argc, argv, pScan))
146776af099aSliuyi 			return -0xFF;
146876af099aSliuyi 	if (pScan)
146976af099aSliuyi 		delete pScan;
147076af099aSliuyi 	if (g_pLogObject)
147176af099aSliuyi 		delete g_pLogObject;
147276af099aSliuyi 	libusb_exit(NULL);
147376af099aSliuyi 	return 0;
147476af099aSliuyi }
1475