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