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