1 /* 2 * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 3 * Seth Liu 2017.03.01 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <unistd.h> 9 #include <dirent.h> 10 #include "config.h" 11 #include "DefineHeader.h" 12 #include "gpt.h" 13 #include "RKLog.h" 14 #include "RKScan.h" 15 #include "RKComm.h" 16 #include "RKDevice.h" 17 #include "RKImage.h" 18 extern const char *szManufName[]; 19 CRKLog *g_pLogObject=NULL; 20 CONFIG_ITEM_VECTOR g_ConfigItemVec; 21 #define DEFAULT_RW_LBA 128 22 #define CURSOR_MOVEUP_LINE(n) printf("%c[%dA", 0x1B, n) 23 #define CURSOR_DEL_LINE printf("%c[2K", 0x1B) 24 #define CURSOR_MOVE_HOME printf("%c[H", 0x1B) 25 #define CURSOR_CLEAR_SCREEN printf("%c[2J", 0x1B) 26 #define ERROR_COLOR_ATTR printf("%c[30;41m", 0x1B); 27 #define NORMAL_COLOR_ATTR printf("%c[0m", 0x1B); 28 extern UINT CRC_32(unsigned char* pData, UINT ulSize); 29 extern unsigned short CRC_16(unsigned char* aData, UINT aSize); 30 extern void P_RC4(unsigned char* buf, unsigned short len); 31 extern unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len); 32 /* 33 u8 test_gpt_head[] = { 34 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00, 35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 0xFF, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 0xDE, 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x49, 0x94, 0xEC, 0x23, 0xE8, 0x58, 0x4B, 38 0xAE, 0xB7, 0xA9, 0x46, 0x51, 0xD0, 0x08, 0xF8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x51, 0xEA, 0xFE, 0x08}; 40 */ 41 42 void usage() 43 { 44 printf("\r\n---------------------Tool Usage ---------------------\r\n"); 45 printf("Help:\t\t\t-h or --help\r\n"); 46 printf("Version:\t\t-v or --version\r\n"); 47 printf("ListDevice:\t\tld\r\n"); 48 printf("DownloadBoot:\t\tdb <Loader>\r\n"); 49 printf("UpgradeLoader:\t\tul <Loader>\r\n"); 50 printf("ReadLBA:\t\trl <BeginSec> <SectorLen> <File>\r\n"); 51 printf("WriteLBA:\t\twl <BeginSec> <File>\r\n"); 52 printf("WriteLBA:\t\twlx <PartitionName> <File>\r\n"); 53 printf("WriteGPT:\t\tgpt <gpt partition table>\r\n"); 54 printf("WriteParameter:\t\tprm <parameter>\r\n"); 55 printf("PrintPartition:\t\tppt \r\n"); 56 printf("EraseFlash:\t\tef \r\n"); 57 printf("TestDevice:\t\ttd\r\n"); 58 printf("ResetDevice:\t\trd [subcode]\r\n"); 59 printf("ReadFlashID:\t\trid\r\n"); 60 printf("ReadFlashInfo:\t\trfi\r\n"); 61 printf("ReadChipInfo:\t\trci\r\n"); 62 printf("ReadCapability:\t\trcb\r\n"); 63 printf("PackBootLoader:\t\tpack\r\n"); 64 printf("UnpackBootLoader:\tunpack <boot loader>\r\n"); 65 printf("TagSPL:\t\t\ttagspl <tag> <U-Boot SPL>\r\n"); 66 printf("-------------------------------------------------------\r\n\r\n"); 67 } 68 void ProgressInfoProc(DWORD deviceLayer, ENUM_PROGRESS_PROMPT promptID, long long totalValue, long long currentValue, ENUM_CALL_STEP emCall) 69 { 70 string strInfoText=""; 71 char szText[256]; 72 switch (promptID) { 73 case TESTDEVICE_PROGRESS: 74 sprintf(szText, "Test Device total %lld, current %lld", totalValue, currentValue); 75 strInfoText = szText; 76 break; 77 case LOWERFORMAT_PROGRESS: 78 sprintf(szText, "Lowerformat Device total %lld, current %lld", totalValue, currentValue); 79 strInfoText = szText; 80 break; 81 case DOWNLOADIMAGE_PROGRESS: 82 sprintf(szText, "Download Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 83 strInfoText = szText; 84 break; 85 case CHECKIMAGE_PROGRESS: 86 sprintf(szText, "Check Image total %lldK, current %lldK", totalValue/1024, currentValue/1024); 87 strInfoText = szText; 88 break; 89 case TAGBADBLOCK_PROGRESS: 90 sprintf(szText, "Tag Bad Block total %lld, current %lld", totalValue, currentValue); 91 strInfoText = szText; 92 break; 93 case TESTBLOCK_PROGRESS: 94 sprintf(szText, "Test Block total %lld, current %lld", totalValue, currentValue); 95 strInfoText = szText; 96 break; 97 case ERASEFLASH_PROGRESS: 98 sprintf(szText, "Erase Flash total %lld, current %lld", totalValue, currentValue); 99 strInfoText = szText; 100 break; 101 case ERASESYSTEM_PROGRESS: 102 sprintf(szText, "Erase System partition total %lld, current %lld", totalValue, currentValue); 103 strInfoText = szText; 104 break; 105 case ERASEUSERDATA_PROGRESS: 106 sprintf(szText, "<LocationID=%x> Erase Userdata partition total %lld, current %lld", deviceLayer, totalValue, currentValue); 107 strInfoText = szText; 108 break; 109 } 110 if (strInfoText.size() > 0){ 111 CURSOR_MOVEUP_LINE(1); 112 CURSOR_DEL_LINE; 113 printf("%s\r\n", strInfoText.c_str()); 114 } 115 if (emCall == CALL_LAST) 116 deviceLayer = 0; 117 } 118 119 char *strupr(char *szSrc) 120 { 121 char *p = szSrc; 122 while(*p){ 123 if ((*p >= 'a') && (*p <= 'z')) 124 *p = *p - 'a' + 'A'; 125 p++; 126 } 127 return szSrc; 128 } 129 void PrintData(PBYTE pData, int nSize) 130 { 131 char szPrint[17] = "\0"; 132 int i; 133 for( i = 0; i < nSize; i++){ 134 if(i % 16 == 0){ 135 if(i / 16 > 0) 136 printf(" %s\r\n", szPrint); 137 printf("%08d ", i / 16); 138 } 139 printf("%02X ", pData[i]); 140 szPrint[i%16] = isprint(pData[i]) ? pData[i] : '.'; 141 } 142 if(i / 16 > 0) 143 printf(" %s\r\n", szPrint); 144 } 145 146 bool StringToWideString(char *pszSrc, wchar_t *&pszDest) 147 { 148 if (!pszSrc) 149 return false; 150 int nSrcLen = strlen(pszSrc); 151 int nDestLen = nSrcLen * 2; 152 153 pszDest = NULL; 154 pszDest = new wchar_t[nDestLen]; 155 if (!pszDest) 156 return false; 157 nDestLen = nDestLen * sizeof(wchar_t); 158 memset(pszDest, 0, nDestLen); 159 int iRet; 160 iconv_t cd; 161 cd = iconv_open("UTF-32", "UTF-8"); 162 if((iconv_t)-1 == cd) { 163 delete []pszDest; 164 pszDest = NULL; 165 return false; 166 } 167 char *pIn, *pOut; 168 pIn = (char *)pszSrc; 169 pOut = (char *)pszDest; 170 171 iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 172 173 if(iRet == -1) { 174 delete []pszDest; 175 pszDest = NULL; 176 iconv_close(cd); 177 return false; 178 } 179 180 iconv_close(cd); 181 182 return true; 183 } 184 bool WideStringToString(wchar_t *pszSrc, char *&pszDest) 185 { 186 if (!pszSrc) 187 return false; 188 int nSrcLen = wcslen(pszSrc); 189 int nDestLen = nSrcLen * 2; 190 nSrcLen = nSrcLen * sizeof(wchar_t); 191 pszDest = NULL; 192 pszDest = new char[nDestLen]; 193 if (!pszDest) 194 return false; 195 memset(pszDest, 0, nDestLen); 196 int iRet; 197 iconv_t cd; 198 cd = iconv_open("UTF-8", "UTF-32"); 199 200 if((iconv_t)-1 == cd) { 201 delete []pszDest; 202 pszDest = NULL; 203 return false; 204 } 205 char *pIn, *pOut; 206 pIn = (char *)pszSrc; 207 pOut = (char *)pszDest; 208 iRet = iconv(cd, (char **)&pIn, (size_t *)&nSrcLen, (char **)&pOut, (size_t *)&nDestLen); 209 210 if(iRet == -1) { 211 delete []pszDest; 212 pszDest = NULL; 213 iconv_close(cd); 214 return false; 215 } 216 217 iconv_close(cd); 218 219 return true; 220 } 221 int find_config_item(CONFIG_ITEM_VECTOR &vecItems, const char *pszName) 222 { 223 unsigned int i; 224 for(i = 0; i < vecItems.size(); i++){ 225 if (strcasecmp(pszName, vecItems[i].szItemName) == 0){ 226 return i; 227 } 228 } 229 return -1; 230 } 231 void string_to_uuid(string strUUid, char *uuid) 232 { 233 unsigned int i; 234 char value; 235 memset(uuid, 0, 16); 236 for (i =0; i < strUUid.size(); i++) { 237 value = 0; 238 if ((strUUid[i] >= '0')&&(strUUid[i] <= '9')) 239 value = strUUid[i] - '0'; 240 if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f')) 241 value = strUUid[i] - 'a' + 10; 242 if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F')) 243 value = strUUid[i] - 'A' + 10; 244 if ((i % 2) == 0) 245 uuid[i / 2] += (value << 4); 246 else 247 uuid[i / 2] += value; 248 } 249 unsigned int *p32; 250 unsigned short *p16; 251 p32 = (unsigned int*)uuid; 252 *p32 = cpu_to_be32(*p32); 253 p16 = (unsigned short *)(uuid + 4); 254 *p16 = cpu_to_be16(*p16); 255 p16 = (unsigned short *)(uuid + 6); 256 *p16 = cpu_to_be16(*p16); 257 } 258 259 bool parse_config(char *pConfig, CONFIG_ITEM_VECTOR &vecItem) 260 { 261 262 stringstream configStream(pConfig); 263 string strLine, strItemName, strItemValue; 264 string::size_type line_size,pos; 265 STRUCT_CONFIG_ITEM item; 266 vecItem.clear(); 267 while (!configStream.eof()){ 268 getline(configStream, strLine); 269 line_size = strLine.size(); 270 if (line_size == 0) 271 continue; 272 if (strLine[line_size-1] == '\r'){ 273 strLine = strLine.substr(0, line_size-1); 274 } 275 strLine.erase(0, strLine.find_first_not_of(" ")); 276 strLine.erase(strLine.find_last_not_of(" ") + 1); 277 if (strLine.size()==0 ) 278 continue; 279 if (strLine[0] == '#') 280 continue; 281 pos = strLine.find("="); 282 if (pos == string::npos){ 283 continue; 284 } 285 strItemName = strLine.substr(0, pos); 286 strItemValue = strLine.substr(pos + 1); 287 strItemName.erase(0, strItemName.find_first_not_of(" ")); 288 strItemName.erase(strItemName.find_last_not_of(" ") + 1); 289 strItemValue.erase(0, strItemValue.find_first_not_of(" ")); 290 strItemValue.erase(strItemValue.find_last_not_of(" ") + 1); 291 if ((strItemName.size() > 0) && (strItemValue.size() > 0)){ 292 strcpy(item.szItemName, strItemName.c_str()); 293 strcpy(item.szItemValue, strItemValue.c_str()); 294 vecItem.push_back(item); 295 } 296 } 297 return true; 298 299 } 300 bool parse_config_file(const char *pConfigFile, CONFIG_ITEM_VECTOR &vecItem) 301 { 302 FILE *file = NULL; 303 file = fopen(pConfigFile, "rb"); 304 if( !file ){ 305 if (g_pLogObject) 306 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pConfigFile); 307 return false; 308 } 309 int iFileSize; 310 fseek(file, 0, SEEK_END); 311 iFileSize = ftell(file); 312 fseek(file, 0, SEEK_SET); 313 char *pConfigBuf = NULL; 314 pConfigBuf = new char[iFileSize + 1]; 315 if (!pConfigBuf){ 316 fclose(file); 317 return false; 318 } 319 memset(pConfigBuf, 0, iFileSize + 1); 320 int iRead; 321 iRead = fread(pConfigBuf, 1, iFileSize, file); 322 if (iRead != iFileSize){ 323 if (g_pLogObject) 324 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, iRead, iFileSize); 325 fclose(file); 326 delete []pConfigBuf; 327 return false; 328 } 329 fclose(file); 330 bool bRet; 331 bRet = parse_config(pConfigBuf, vecItem); 332 delete []pConfigBuf; 333 return bRet; 334 } 335 bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen) 336 { 337 string::size_type pos,prevPos; 338 string strOffset,strLen; 339 int iCount; 340 prevPos = pos = 0; 341 if (strPartInfo.size() <= 0) { 342 return false; 343 } 344 pos = strPartInfo.find('@'); 345 if (pos == string::npos) { 346 return false; 347 } 348 strLen = strPartInfo.substr(prevPos, pos - prevPos); 349 strLen.erase(0, strLen.find_first_not_of(" ")); 350 strLen.erase(strLen.find_last_not_of(" ") + 1); 351 if (strchr(strLen.c_str(), '-')) { 352 uiLen = 0xFFFFFFFF; 353 } else { 354 iCount = sscanf(strLen.c_str(), "0x%x", &uiLen); 355 if (iCount != 1) { 356 return false; 357 } 358 } 359 360 prevPos = pos + 1; 361 pos = strPartInfo.find('(',prevPos); 362 if (pos == string::npos) { 363 return false; 364 } 365 strOffset = strPartInfo.substr(prevPos, pos - prevPos); 366 strOffset.erase(0, strOffset.find_first_not_of(" ")); 367 strOffset.erase(strOffset.find_last_not_of(" ") + 1); 368 iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset); 369 if (iCount != 1) { 370 return false; 371 } 372 prevPos = pos + 1; 373 pos = strPartInfo.find(')', prevPos); 374 if (pos == string::npos) { 375 return false; 376 } 377 strName = strPartInfo.substr(prevPos, pos - prevPos); 378 strName.erase(0, strName.find_first_not_of(" ")); 379 strName.erase(strName.find_last_not_of(" ") + 1); 380 381 return true; 382 } 383 bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid) 384 { 385 string::size_type pos(0); 386 387 if (strUuidInfo.size() <= 0) { 388 return false; 389 } 390 pos = strUuidInfo.find('='); 391 if (pos == string::npos) { 392 return false; 393 } 394 strName = strUuidInfo.substr(0, pos); 395 strName.erase(0, strName.find_first_not_of(" ")); 396 strName.erase(strName.find_last_not_of(" ") + 1); 397 398 strUUid = strUuidInfo.substr(pos+1); 399 strUUid.erase(0, strUUid.find_first_not_of(" ")); 400 strUUid.erase(strUUid.find_last_not_of(" ") + 1); 401 402 while(true) { 403 pos = 0; 404 if( (pos = strUUid.find("-")) != string::npos) 405 strUUid.replace(pos,1,""); 406 else 407 break; 408 } 409 if (strUUid.size() != 32) 410 return false; 411 return true; 412 } 413 414 415 bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 416 { 417 stringstream paramStream(pParameter); 418 bool bRet,bFind = false; 419 string strLine, strPartition, strPartInfo, strPartName, strUUid; 420 string::size_type line_size, pos, posColon, posComma; 421 UINT uiPartOffset, uiPartSize; 422 STRUCT_PARAM_ITEM item; 423 STRUCT_CONFIG_ITEM uuid_item; 424 vecItem.clear(); 425 vecUuidItem.clear(); 426 while (!paramStream.eof()) { 427 getline(paramStream,strLine); 428 line_size = strLine.size(); 429 if (line_size == 0) 430 continue; 431 if (strLine[line_size - 1] == '\r'){ 432 strLine = strLine.substr(0, line_size - 1); 433 } 434 strLine.erase(0, strLine.find_first_not_of(" ")); 435 strLine.erase(strLine.find_last_not_of(" ") + 1); 436 if (strLine.size()==0 ) 437 continue; 438 if (strLine[0] == '#') 439 continue; 440 pos = strLine.find("uuid:"); 441 if (pos != string::npos) { 442 strPartInfo = strLine.substr(pos+5); 443 bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid); 444 if (bRet) { 445 strcpy(uuid_item.szItemName, strPartName.c_str()); 446 string_to_uuid(strUUid,uuid_item.szItemValue); 447 vecUuidItem.push_back(uuid_item); 448 } 449 continue; 450 } 451 452 pos = strLine.find("mtdparts"); 453 if (pos == string::npos) { 454 continue; 455 } 456 bFind = true; 457 posColon = strLine.find(':', pos); 458 if (posColon == string::npos) { 459 continue; 460 } 461 strPartition = strLine.substr(posColon + 1); 462 pos = 0; 463 posComma = strPartition.find(',', pos); 464 while (posComma != string::npos) { 465 strPartInfo = strPartition.substr(pos, posComma - pos); 466 bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 467 if (bRet) { 468 strcpy(item.szItemName, strPartName.c_str()); 469 item.uiItemOffset = uiPartOffset; 470 item.uiItemSize = uiPartSize; 471 vecItem.push_back(item); 472 } 473 pos = posComma + 1; 474 posComma = strPartition.find(',', pos); 475 } 476 strPartInfo = strPartition.substr(pos); 477 if (strPartInfo.size() > 0) { 478 bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize); 479 if (bRet) { 480 strcpy(item.szItemName, strPartName.c_str()); 481 item.uiItemOffset = uiPartOffset; 482 item.uiItemSize = uiPartSize; 483 vecItem.push_back(item); 484 } 485 } 486 } 487 return bFind; 488 489 } 490 bool parse_parameter_file(char *pParamFile, PARAM_ITEM_VECTOR &vecItem, CONFIG_ITEM_VECTOR &vecUuidItem) 491 { 492 FILE *file = NULL; 493 file = fopen(pParamFile, "rb"); 494 if( !file ) { 495 if (g_pLogObject) 496 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 497 return false; 498 } 499 int iFileSize; 500 fseek(file, 0, SEEK_END); 501 iFileSize = ftell(file); 502 fseek(file, 0, SEEK_SET); 503 char *pParamBuf = NULL; 504 pParamBuf = new char[iFileSize]; 505 if (!pParamBuf) { 506 fclose(file); 507 return false; 508 } 509 int iRead; 510 iRead = fread(pParamBuf, 1, iFileSize, file); 511 if (iRead != iFileSize) { 512 if (g_pLogObject) 513 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno,iRead,iFileSize); 514 fclose(file); 515 delete []pParamBuf; 516 return false; 517 } 518 fclose(file); 519 bool bRet; 520 bRet = parse_parameter(pParamBuf, vecItem, vecUuidItem); 521 delete []pParamBuf; 522 return bRet; 523 } 524 bool is_sparse_image(char *szImage) 525 { 526 FILE *file = NULL; 527 sparse_header head; 528 u32 uiRead; 529 file = fopen(szImage, "rb"); 530 if( !file ) { 531 if (g_pLogObject) 532 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szImage); 533 return false; 534 } 535 uiRead = fread(&head, 1, sizeof(head), file); 536 if (uiRead != sizeof(head)) { 537 if (g_pLogObject) 538 g_pLogObject->Record("%s failed, err=%d, read=%d, total=%d\r\n", __func__, errno, uiRead, sizeof(head)); 539 fclose(file); 540 return false; 541 } 542 fclose(file); 543 if (head.magic!=SPARSE_HEADER_MAGIC) 544 { 545 return false; 546 } 547 return true; 548 549 } 550 void gen_rand_uuid(unsigned char *uuid_bin) 551 { 552 efi_guid_t id; 553 unsigned int *ptr = (unsigned int *)&id; 554 unsigned int i; 555 556 /* Set all fields randomly */ 557 for (i = 0; i < sizeof(id) / sizeof(*ptr); i++) 558 *(ptr + i) = cpu_to_be32(rand()); 559 560 id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000; 561 id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80; 562 563 memcpy(uuid_bin, id.raw, sizeof(id)); 564 } 565 566 void prepare_gpt_backup(u8 *master, u8 *backup) 567 { 568 gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 569 gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE); 570 u32 calc_crc32; 571 u64 val; 572 573 /* recalculate the values for the Backup GPT Header */ 574 val = le64_to_cpu(gptMasterHead->my_lba); 575 gptBackupHead->my_lba = gptMasterHead->alternate_lba; 576 gptBackupHead->alternate_lba = cpu_to_le64(val); 577 gptBackupHead->partition_entry_lba = cpu_to_le64(le64_to_cpu(gptMasterHead->last_usable_lba) + 1); 578 gptBackupHead->header_crc32 = 0; 579 580 calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size)); 581 gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32); 582 } 583 bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end) 584 { 585 gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 586 gpt_entry *gptEntry = NULL; 587 u32 i,j; 588 u8 zerobuf[GPT_ENTRY_SIZE]; 589 bool bFound = false; 590 memset(zerobuf,0,GPT_ENTRY_SIZE); 591 592 for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 593 gptEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 594 if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 595 break; 596 for (j = 0; j < strlen(pszName); j++) 597 if (gptEntry->partition_name[j] != pszName[j]) 598 break; 599 if (gptEntry->partition_name[j] != 0) 600 continue; 601 if (j == strlen(pszName)) { 602 bFound = true; 603 break; 604 } 605 } 606 if (bFound) { 607 *lba = le64_to_cpu(gptEntry->starting_lba); 608 *lba_end = le64_to_cpu(gptEntry->ending_lba); 609 return true; 610 } 611 return false; 612 } 613 bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size) 614 { 615 u32 i; 616 bool bFound = false, bRet; 617 PARAM_ITEM_VECTOR vecItem; 618 CONFIG_ITEM_VECTOR vecUuid; 619 620 bRet = parse_parameter((char *)param, vecItem, vecUuid); 621 if (!bRet) 622 return false; 623 624 for (i = 0; i < vecItem.size(); i++) { 625 if (strcasecmp(pszName, vecItem[i].szItemName)==0) { 626 bFound = true; 627 break; 628 } 629 } 630 if (bFound) { 631 *part_offset = vecItem[i].uiItemOffset; 632 *part_size = vecItem[i].uiItemSize; 633 return true; 634 } 635 return false; 636 } 637 638 void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) 639 { 640 gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); 641 gpt_entry *gptLastPartEntry = NULL; 642 u32 i; 643 u64 old_disksize; 644 u8 zerobuf[GPT_ENTRY_SIZE]; 645 646 memset(zerobuf,0,GPT_ENTRY_SIZE); 647 old_disksize = le64_to_cpu(gptMasterHead->alternate_lba) + 1; 648 for (i = 0; i < le32_to_cpu(gptMasterHead->num_partition_entries); i++) { 649 gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 650 if (memcmp(zerobuf, (u8 *)gptLastPartEntry, GPT_ENTRY_SIZE) == 0) 651 break; 652 } 653 i--; 654 gptLastPartEntry = (gpt_entry *)(master + 2 * SECTOR_SIZE + i * sizeof(gpt_entry)); 655 656 gptMasterHead->alternate_lba = cpu_to_le64(total_sector - 1); 657 gptMasterHead->last_usable_lba = cpu_to_le64(total_sector- 34); 658 659 if (gptLastPartEntry->ending_lba == (old_disksize - 34)) {//grow partition 660 gptLastPartEntry->ending_lba = cpu_to_le64(total_sector- 34); 661 gptMasterHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 662 } 663 gptMasterHead->header_crc32 = 0; 664 gptMasterHead->header_crc32 = cpu_to_le32(crc32_le(0, master + SECTOR_SIZE, sizeof(gpt_header))); 665 memcpy(backup,master + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS); 666 memcpy(backup + GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS, master + SECTOR_SIZE, SECTOR_SIZE); 667 prepare_gpt_backup(master, backup); 668 669 } 670 bool load_gpt_buffer(char *pParamFile, u8 *master, u8 *backup) 671 { 672 FILE *file = NULL; 673 file = fopen(pParamFile, "rb"); 674 if( !file ) { 675 if (g_pLogObject) 676 g_pLogObject->Record("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, pParamFile); 677 return false; 678 } 679 int iFileSize; 680 fseek(file, 0, SEEK_END); 681 iFileSize = ftell(file); 682 fseek(file, 0, SEEK_SET); 683 if (iFileSize != 67 * SECTOR_SIZE) { 684 if (g_pLogObject) 685 g_pLogObject->Record("%s failed, wrong size file: %s\r\n", __func__, pParamFile); 686 fclose(file); 687 return false; 688 } 689 690 int iRead; 691 iRead = fread(master, 1, 34 * SECTOR_SIZE, file); 692 if (iRead != 34 * SECTOR_SIZE) { 693 if (g_pLogObject) 694 g_pLogObject->Record("%s failed,read master gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 34 * SECTOR_SIZE); 695 fclose(file); 696 return false; 697 } 698 iRead = fread(backup, 1, 33 * SECTOR_SIZE, file); 699 if (iRead != 33 * SECTOR_SIZE) { 700 if (g_pLogObject) 701 g_pLogObject->Record("%s failed,read backup gpt err=%d, read=%d, total=%d\r\n", __func__, errno,iRead, 33 * SECTOR_SIZE); 702 fclose(file); 703 return false; 704 } 705 fclose(file); 706 return true; 707 } 708 void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors) 709 { 710 legacy_mbr *mbr = (legacy_mbr *)gpt; 711 gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE); 712 gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE); 713 u32 i,j; 714 int pos; 715 string strPartName; 716 string::size_type colonPos; 717 /*1.protective mbr*/ 718 memset(gpt, 0, SECTOR_SIZE); 719 mbr->signature = MSDOS_MBR_SIGNATURE; 720 mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 721 mbr->partition_record[0].start_sect = 1; 722 mbr->partition_record[0].nr_sects = (u32)-1; 723 /*2.gpt header*/ 724 memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE); 725 gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 726 gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 727 gptHead->header_size = cpu_to_le32(sizeof(gpt_header)); 728 gptHead->my_lba = cpu_to_le64(1); 729 gptHead->alternate_lba = cpu_to_le64(diskSectors - 1); 730 gptHead->first_usable_lba = cpu_to_le64(34); 731 gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34); 732 gptHead->partition_entry_lba = cpu_to_le64(2); 733 gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 734 gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE); 735 gptHead->header_crc32 = 0; 736 gptHead->partition_entry_array_crc32 = 0; 737 gen_rand_uuid(gptHead->disk_guid.raw); 738 739 /*3.gpt partition entry*/ 740 memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE); 741 for (i = 0; i < vecParts.size(); i++) { 742 gen_rand_uuid(gptEntry->partition_type_guid.raw); 743 gen_rand_uuid(gptEntry->unique_partition_guid.raw); 744 gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset); 745 gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1); 746 gptEntry->attributes.raw = 0; 747 strPartName = vecParts[i].szItemName; 748 colonPos = strPartName.find_first_of(':'); 749 if (colonPos != string::npos) { 750 if (strPartName.find("bootable") != string::npos) 751 gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE; 752 if (strPartName.find("grow") != string::npos) 753 gptEntry->ending_lba = cpu_to_le64(diskSectors - 34); 754 strPartName = strPartName.substr(0, colonPos); 755 vecParts[i].szItemName[strPartName.size()] = 0; 756 } 757 for (j = 0; j < strlen(vecParts[i].szItemName); j++) 758 gptEntry->partition_name[j] = vecParts[i].szItemName[j]; 759 if ((pos = find_config_item(vecUuid, vecParts[i].szItemName)) != -1) 760 memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16); 761 gptEntry++; 762 } 763 764 gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS)); 765 gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header))); 766 767 } 768 bool MakeSector0(PBYTE pSector, USHORT usFlashDataSec, USHORT usFlashBootSec, bool rc4Flag) 769 { 770 PRK28_IDB_SEC0 pSec0; 771 memset(pSector, 0, SECTOR_SIZE); 772 pSec0 = (PRK28_IDB_SEC0)pSector; 773 774 pSec0->dwTag = 0x0FF0AA55; 775 pSec0->uiRc4Flag = rc4Flag; 776 pSec0->usBootCode1Offset = 0x4; 777 pSec0->usBootCode2Offset = 0x4; 778 pSec0->usBootDataSize = usFlashDataSec; 779 pSec0->usBootCodeSize = usFlashDataSec + usFlashBootSec; 780 return true; 781 } 782 783 784 bool MakeSector1(PBYTE pSector) 785 { 786 PRK28_IDB_SEC1 pSec1; 787 memset(pSector, 0, SECTOR_SIZE); 788 pSec1 = (PRK28_IDB_SEC1)pSector; 789 790 pSec1->usSysReservedBlock = 0xC; 791 pSec1->usDisk0Size = 0xFFFF; 792 pSec1->uiChipTag = 0x38324B52; 793 return true; 794 } 795 796 bool MakeSector2(PBYTE pSector) 797 { 798 PRK28_IDB_SEC2 pSec2; 799 memset(pSector, 0, SECTOR_SIZE); 800 pSec2 = (PRK28_IDB_SEC2)pSector; 801 802 strcpy(pSec2->szVcTag, "VC"); 803 strcpy(pSec2->szCrcTag, "CRC"); 804 return true; 805 } 806 807 bool MakeSector3(PBYTE pSector) 808 { 809 memset(pSector,0,SECTOR_SIZE); 810 return true; 811 } 812 813 int MakeIDBlockData(PBYTE pDDR, PBYTE pLoader, PBYTE lpIDBlock, USHORT usFlashDataSec, USHORT usFlashBootSec, DWORD dwLoaderDataSize, DWORD dwLoaderSize, bool rc4Flag) 814 { 815 RK28_IDB_SEC0 sector0Info; 816 RK28_IDB_SEC1 sector1Info; 817 RK28_IDB_SEC2 sector2Info; 818 RK28_IDB_SEC3 sector3Info; 819 UINT i; 820 MakeSector0((PBYTE)§or0Info, usFlashDataSec, usFlashBootSec, rc4Flag); 821 MakeSector1((PBYTE)§or1Info); 822 if (!MakeSector2((PBYTE)§or2Info)) { 823 return -6; 824 } 825 if (!MakeSector3((PBYTE)§or3Info)) { 826 return -7; 827 } 828 sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info, SECTOR_SIZE); 829 sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info, SECTOR_SIZE); 830 sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info, SECTOR_SIZE); 831 832 memcpy(lpIDBlock, §or0Info, SECTOR_SIZE); 833 memcpy(lpIDBlock + SECTOR_SIZE, §or1Info, SECTOR_SIZE); 834 memcpy(lpIDBlock + SECTOR_SIZE * 3, §or3Info, SECTOR_SIZE); 835 836 if (rc4Flag) { 837 for (i = 0; i < dwLoaderDataSize/SECTOR_SIZE; i++) 838 P_RC4(pDDR + i * SECTOR_SIZE, SECTOR_SIZE); 839 for (i = 0; i < dwLoaderSize/SECTOR_SIZE; i++) 840 P_RC4(pLoader + i * SECTOR_SIZE, SECTOR_SIZE); 841 } 842 843 memcpy(lpIDBlock + SECTOR_SIZE * 4, pDDR, dwLoaderDataSize); 844 memcpy(lpIDBlock + SECTOR_SIZE * (4 + usFlashDataSec), pLoader, dwLoaderSize); 845 846 sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock + SECTOR_SIZE * 4), sector0Info.usBootCodeSize * SECTOR_SIZE); 847 memcpy(lpIDBlock + SECTOR_SIZE * 2, §or2Info, SECTOR_SIZE); 848 for(i = 0; i < 4; i++) { 849 if(i == 1) { 850 continue; 851 } else { 852 P_RC4(lpIDBlock + SECTOR_SIZE * i, SECTOR_SIZE); 853 } 854 } 855 return 0; 856 } 857 858 859 860 bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) 861 { 862 if (((UINT)dev.emUsbType & uiSupportType) == (UINT)dev.emUsbType) 863 return true; 864 else 865 { 866 ERROR_COLOR_ATTR; 867 printf("The device does not support this operation!"); 868 NORMAL_COLOR_ATTR; 869 printf("\r\n"); 870 return false; 871 } 872 } 873 bool MakeParamBuffer(char *pParamFile, char* &pParamData) 874 { 875 FILE *file=NULL; 876 file = fopen(pParamFile, "rb"); 877 if( !file ) 878 { 879 if (g_pLogObject) 880 g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile); 881 return false; 882 } 883 int iFileSize; 884 fseek(file,0,SEEK_END); 885 iFileSize = ftell(file); 886 fseek(file,0,SEEK_SET); 887 char *pParamBuf=NULL; 888 pParamBuf = new char[iFileSize + 12]; 889 if (!pParamBuf) 890 { 891 fclose(file); 892 return false; 893 } 894 memset(pParamBuf,0,iFileSize+12); 895 *(UINT *)(pParamBuf) = 0x4D524150; 896 897 int iRead; 898 iRead = fread(pParamBuf+8,1,iFileSize,file); 899 if (iRead!=iFileSize) 900 { 901 if (g_pLogObject) 902 g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize); 903 fclose(file); 904 delete []pParamBuf; 905 return false; 906 } 907 fclose(file); 908 909 *(UINT *)(pParamBuf+4) = iFileSize; 910 *(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize); 911 pParamData = pParamBuf; 912 return true; 913 } 914 915 bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 916 { 917 CRKComm *pComm = NULL; 918 char *pParamBuf = NULL, writeBuf[512*1024]; 919 int iRet, nParamSec, nParamSize; 920 bool bRet, bSuccess = false; 921 if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER)) 922 return false; 923 924 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 925 if (!bRet) { 926 ERROR_COLOR_ATTR; 927 printf("Creating Comm Object failed!"); 928 NORMAL_COLOR_ATTR; 929 printf("\r\n"); 930 return bSuccess; 931 } 932 if (!MakeParamBuffer(szParameter, pParamBuf)) { 933 ERROR_COLOR_ATTR; 934 printf("Generating parameter failed!"); 935 NORMAL_COLOR_ATTR; 936 printf("\r\n"); 937 return bSuccess; 938 } 939 printf("Writing parameter...\r\n"); 940 nParamSize = *(UINT *)(pParamBuf+4) + 12; 941 nParamSec = BYTE2SECTOR(nParamSize); 942 if (nParamSec > 1024) { 943 ERROR_COLOR_ATTR; 944 printf("parameter is too large!"); 945 NORMAL_COLOR_ATTR; 946 printf("\r\n"); 947 return bSuccess; 948 } 949 memset(writeBuf, 0, nParamSec*512); 950 memcpy(writeBuf, pParamBuf, nParamSize); 951 iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf); 952 if (iRet != ERR_SUCCESS) { 953 ERROR_COLOR_ATTR; 954 printf("Writing parameter failed!"); 955 NORMAL_COLOR_ATTR; 956 printf("\r\n"); 957 return bSuccess; 958 } 959 960 bSuccess = true; 961 CURSOR_MOVEUP_LINE(1); 962 CURSOR_DEL_LINE; 963 printf("Writing parameter succeeded.\r\n"); 964 return bSuccess; 965 } 966 967 bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) 968 { 969 u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; 970 u32 total_size_sector; 971 CRKComm *pComm = NULL; 972 PARAM_ITEM_VECTOR vecItems; 973 CONFIG_ITEM_VECTOR vecUuid; 974 int iRet; 975 bool bRet, bSuccess = false; 976 if (!check_device_type(dev, RKUSB_MASKROM)) 977 return false; 978 979 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 980 if (!bRet) { 981 ERROR_COLOR_ATTR; 982 printf("Creating Comm Object failed!"); 983 NORMAL_COLOR_ATTR; 984 printf("\r\n"); 985 return bSuccess; 986 } 987 printf("Writing gpt...\r\n"); 988 //1.get flash info 989 iRet = pComm->RKU_ReadFlashInfo(flash_info); 990 if (iRet != ERR_SUCCESS) { 991 ERROR_COLOR_ATTR; 992 printf("Reading Flash Info failed!"); 993 NORMAL_COLOR_ATTR; 994 printf("\r\n"); 995 return bSuccess; 996 } 997 total_size_sector = *(u32 *)flash_info; 998 if (strstr(szParameter, ".img")) { 999 if (!load_gpt_buffer(szParameter, master_gpt, backup_gpt)) { 1000 ERROR_COLOR_ATTR; 1001 printf("Loading partition image failed!"); 1002 NORMAL_COLOR_ATTR; 1003 printf("\r\n"); 1004 return bSuccess; 1005 } 1006 update_gpt_disksize(master_gpt, backup_gpt, total_size_sector); 1007 } else { 1008 //2.get partition from parameter 1009 bRet = parse_parameter_file(szParameter, vecItems, vecUuid); 1010 if (!bRet) { 1011 ERROR_COLOR_ATTR; 1012 printf("Parsing parameter failed!"); 1013 NORMAL_COLOR_ATTR; 1014 printf("\r\n"); 1015 return bSuccess; 1016 } 1017 vecItems[vecItems.size()-1].uiItemSize = total_size_sector - 33; 1018 //3.generate gpt info 1019 create_gpt_buffer(master_gpt, vecItems, vecUuid, total_size_sector); 1020 memcpy(backup_gpt, master_gpt + 2* SECTOR_SIZE, 32 * SECTOR_SIZE); 1021 memcpy(backup_gpt + 32 * SECTOR_SIZE, master_gpt + SECTOR_SIZE, SECTOR_SIZE); 1022 prepare_gpt_backup(master_gpt, backup_gpt); 1023 } 1024 1025 //4. write gpt 1026 iRet = pComm->RKU_WriteLBA(0, 34, master_gpt); 1027 if (iRet != ERR_SUCCESS) { 1028 ERROR_COLOR_ATTR; 1029 printf("Writing master gpt failed!"); 1030 NORMAL_COLOR_ATTR; 1031 printf("\r\n"); 1032 return bSuccess; 1033 } 1034 iRet = pComm->RKU_WriteLBA(total_size_sector - 33, 33, backup_gpt); 1035 if (iRet != ERR_SUCCESS) { 1036 ERROR_COLOR_ATTR; 1037 printf("Writing backup gpt failed!"); 1038 NORMAL_COLOR_ATTR; 1039 printf("\r\n"); 1040 return bSuccess; 1041 } 1042 1043 bSuccess = true; 1044 CURSOR_MOVEUP_LINE(1); 1045 CURSOR_DEL_LINE; 1046 printf("Writing gpt succeeded.\r\n"); 1047 return bSuccess; 1048 } 1049 1050 #include "boot_merger.h" 1051 #define ENTRY_ALIGN (2048) 1052 options gOpts; 1053 1054 1055 char gSubfix[MAX_LINE_LEN] = OUT_SUBFIX; 1056 char* gConfigPath; 1057 uint8_t gBuf[MAX_MERGE_SIZE]; 1058 1059 static inline void fixPath(char* path) { 1060 int i, len = strlen(path); 1061 for(i=0; i<len; i++) { 1062 if (path[i] == '\\') 1063 path[i] = '/'; 1064 else if (path[i] == '\r' || path[i] == '\n') 1065 path[i] = '\0'; 1066 } 1067 } 1068 1069 static bool parseChip(FILE* file) { 1070 if (SCANF_EAT(file) != 0) { 1071 return false; 1072 } 1073 if (fscanf(file, OPT_NAME "=%s", gOpts.chip) != 1) { 1074 return false; 1075 } 1076 printf("chip: %s\n", gOpts.chip); 1077 return true; 1078 } 1079 1080 static bool parseVersion(FILE* file) { 1081 if (SCANF_EAT(file) != 0) { 1082 return false; 1083 } 1084 if (fscanf(file, OPT_MAJOR "=%d", &gOpts.major) != 1) 1085 return false; 1086 if (SCANF_EAT(file) != 0) { 1087 return false; 1088 } 1089 if (fscanf(file, OPT_MINOR "=%d", &gOpts.minor) != 1) 1090 return false; 1091 printf("major: %d, minor: %d\n", gOpts.major, gOpts.minor); 1092 return true; 1093 } 1094 1095 static bool parse471(FILE* file) { 1096 int i, index, pos; 1097 char buf[MAX_LINE_LEN]; 1098 1099 if (SCANF_EAT(file) != 0) { 1100 return false; 1101 } 1102 if (fscanf(file, OPT_NUM "=%d", &gOpts.code471Num) != 1) 1103 return false; 1104 printf("num: %d\n", gOpts.code471Num); 1105 if (!gOpts.code471Num) 1106 return true; 1107 if (gOpts.code471Num < 0) 1108 return false; 1109 gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 1110 for (i=0; i<gOpts.code471Num; i++) { 1111 if (SCANF_EAT(file) != 0) { 1112 return false; 1113 } 1114 if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 1115 != 2) 1116 return false; 1117 index--; 1118 fixPath(buf); 1119 strcpy((char*)gOpts.code471Path[index], buf); 1120 printf("path%i: %s\n", index, gOpts.code471Path[index]); 1121 } 1122 pos = ftell(file); 1123 if (SCANF_EAT(file) != 0) { 1124 return false; 1125 } 1126 if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code471Sleep) != 1) 1127 fseek(file, pos, SEEK_SET); 1128 printf("sleep: %d\n", gOpts.code471Sleep); 1129 return true; 1130 } 1131 1132 static bool parse472(FILE* file) { 1133 int i, index, pos; 1134 char buf[MAX_LINE_LEN]; 1135 1136 if (SCANF_EAT(file) != 0) { 1137 return false; 1138 } 1139 if (fscanf(file, OPT_NUM "=%d", &gOpts.code472Num) != 1) 1140 return false; 1141 printf("num: %d\n", gOpts.code472Num); 1142 if (!gOpts.code472Num) 1143 return true; 1144 if (gOpts.code472Num < 0) 1145 return false; 1146 gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 1147 for (i=0; i<gOpts.code472Num; i++) { 1148 if (SCANF_EAT(file) != 0) { 1149 return false; 1150 } 1151 if (fscanf(file, OPT_PATH "%d=%[^\r^\n]", &index, buf) 1152 != 2) 1153 return false; 1154 fixPath(buf); 1155 index--; 1156 strcpy((char*)gOpts.code472Path[index], buf); 1157 printf("path%i: %s\n", index, gOpts.code472Path[index]); 1158 } 1159 pos = ftell(file); 1160 if (SCANF_EAT(file) != 0) { 1161 return false; 1162 } 1163 if (fscanf(file, OPT_SLEEP "=%d", &gOpts.code472Sleep) != 1) 1164 fseek(file, pos, SEEK_SET); 1165 printf("sleep: %d\n", gOpts.code472Sleep); 1166 return true; 1167 } 1168 1169 static bool parseLoader(FILE* file) { 1170 int i, j, index, pos; 1171 char buf[MAX_LINE_LEN]; 1172 char buf2[MAX_LINE_LEN]; 1173 1174 if (SCANF_EAT(file) != 0) { 1175 return false; 1176 } 1177 pos = ftell(file); 1178 if (fscanf(file, OPT_NUM "=%d", &gOpts.loaderNum) != 1) { 1179 fseek(file, pos, SEEK_SET); 1180 if(fscanf(file, OPT_LOADER_NUM "=%d", &gOpts.loaderNum) != 1) { 1181 return false; 1182 } 1183 } 1184 printf("num: %d\n", gOpts.loaderNum); 1185 if (!gOpts.loaderNum) 1186 return false; 1187 if (gOpts.loaderNum < 0) 1188 return false; 1189 gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 1190 for (i=0; i<gOpts.loaderNum; i++) { 1191 if (SCANF_EAT(file) != 0) { 1192 return false; 1193 } 1194 if (fscanf(file, OPT_LOADER_NAME "%d=%s", &index, buf) 1195 != 2) 1196 return false; 1197 strcpy(gOpts.loader[index].name, buf); 1198 printf("name%d: %s\n", index, gOpts.loader[index].name); 1199 index++; 1200 } 1201 for (i=0; i<gOpts.loaderNum; i++) { 1202 if (SCANF_EAT(file) != 0) { 1203 return false; 1204 } 1205 if (fscanf(file, "%[^=]=%[^\r^\n]", buf, buf2) 1206 != 2) 1207 return false; 1208 for (j=0; j<gOpts.loaderNum; j++) { 1209 if (!strcmp(gOpts.loader[j].name, buf)) { 1210 fixPath(buf2); 1211 strcpy(gOpts.loader[j].path, buf2); 1212 printf("%s=%s\n", gOpts.loader[j].name, gOpts.loader[j].path); 1213 break; 1214 } 1215 } 1216 if (j >= gOpts.loaderNum) { 1217 return false; 1218 } 1219 } 1220 return true; 1221 } 1222 1223 static bool parseOut(FILE* file) { 1224 if (SCANF_EAT(file) != 0) { 1225 return false; 1226 } 1227 if (fscanf(file, OPT_OUT_PATH "=%[^\r^\n]", gOpts.outPath) != 1) 1228 return false; 1229 fixPath(gOpts.outPath); 1230 printf("out: %s\n", gOpts.outPath); 1231 return true; 1232 } 1233 1234 1235 void printOpts(FILE* out) { 1236 int i; 1237 fprintf(out, SEC_CHIP "\n" OPT_NAME "=%s\n", gOpts.chip); 1238 fprintf(out, SEC_VERSION "\n" OPT_MAJOR "=%d\n" OPT_MINOR 1239 "=%d\n", gOpts.major, gOpts.minor); 1240 1241 fprintf(out, SEC_471 "\n" OPT_NUM "=%d\n", gOpts.code471Num); 1242 for (i=0 ;i<gOpts.code471Num ;i++) { 1243 fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code471Path[i]); 1244 } 1245 if (gOpts.code471Sleep > 0) 1246 fprintf(out, OPT_SLEEP "=%d\n", gOpts.code471Sleep); 1247 1248 fprintf(out, SEC_472 "\n" OPT_NUM "=%d\n", gOpts.code472Num); 1249 for (i=0 ;i<gOpts.code472Num ;i++) { 1250 fprintf(out, OPT_PATH "%d=%s\n", i+1, gOpts.code472Path[i]); 1251 } 1252 if (gOpts.code472Sleep > 0) 1253 fprintf(out, OPT_SLEEP "=%d\n", gOpts.code472Sleep); 1254 1255 fprintf(out, SEC_LOADER "\n" OPT_NUM "=%d\n", gOpts.loaderNum); 1256 for (i=0 ;i<gOpts.loaderNum ;i++) { 1257 fprintf(out, OPT_LOADER_NAME "%d=%s\n", i+1, gOpts.loader[i].name); 1258 } 1259 for (i=0 ;i<gOpts.loaderNum ;i++) { 1260 fprintf(out, "%s=%s\n", gOpts.loader[i].name, gOpts.loader[i].path); 1261 } 1262 1263 fprintf(out, SEC_OUT "\n" OPT_OUT_PATH "=%s\n", gOpts.outPath); 1264 } 1265 1266 static bool parseOpts(void) { 1267 bool ret = false; 1268 bool chipOk = false; 1269 bool versionOk = false; 1270 bool code471Ok = true; 1271 bool code472Ok = true; 1272 bool loaderOk = false; 1273 bool outOk = false; 1274 char buf[MAX_LINE_LEN]; 1275 1276 char* configPath = (gConfigPath == (char*)NULL)? (char*)DEF_CONFIG_FILE: gConfigPath; 1277 FILE* file; 1278 file = fopen(configPath, "r"); 1279 if (!file) { 1280 fprintf(stderr, "config (%s) not found!\n", configPath); 1281 if (strcmp(configPath, (char*)DEF_CONFIG_FILE) == 0) { 1282 file = fopen(DEF_CONFIG_FILE, "w"); 1283 if (file) { 1284 fprintf(stderr, "creating defconfig\n"); 1285 printOpts(file); 1286 } 1287 } 1288 goto end; 1289 } 1290 1291 printf("Starting to parse...\n"); 1292 1293 if (SCANF_EAT(file) != 0) { 1294 goto end; 1295 } 1296 while(fscanf(file, "%s", buf) == 1) { 1297 if (!strcmp(buf, SEC_CHIP)) { 1298 chipOk = parseChip(file); 1299 if (!chipOk) { 1300 printf("parseChip failed!\n"); 1301 goto end; 1302 } 1303 } else if (!strcmp(buf, SEC_VERSION)) { 1304 versionOk = parseVersion(file); 1305 if (!versionOk) { 1306 printf("parseVersion failed!\n"); 1307 goto end; 1308 } 1309 } else if (!strcmp(buf, SEC_471)) { 1310 code471Ok = parse471(file); 1311 if (!code471Ok) { 1312 printf("parse471 failed!\n"); 1313 goto end; 1314 } 1315 } else if (!strcmp(buf, SEC_472)) { 1316 code472Ok = parse472(file); 1317 if (!code472Ok) { 1318 printf("parse472 failed!\n"); 1319 goto end; 1320 } 1321 } else if (!strcmp(buf, SEC_LOADER)) { 1322 loaderOk = parseLoader(file); 1323 if (!loaderOk) { 1324 printf("parseLoader failed!\n"); 1325 goto end; 1326 } 1327 } else if (!strcmp(buf, SEC_OUT)) { 1328 outOk = parseOut(file); 1329 if (!outOk) { 1330 printf("parseOut failed!\n"); 1331 goto end; 1332 } 1333 } else if (buf[0] == '#') { 1334 continue; 1335 } else { 1336 printf("unknown sec: %s!\n", buf); 1337 goto end; 1338 } 1339 if (SCANF_EAT(file) != 0) { 1340 goto end; 1341 } 1342 } 1343 1344 if (chipOk && versionOk && code471Ok && code472Ok 1345 && loaderOk && outOk) 1346 ret = true; 1347 end: 1348 if (file) 1349 fclose(file); 1350 return ret; 1351 } 1352 1353 bool initOpts(void) { 1354 //set default opts 1355 gOpts.major = DEF_MAJOR; 1356 gOpts.minor = DEF_MINOR; 1357 strcpy(gOpts.chip, DEF_CHIP); 1358 gOpts.code471Sleep = DEF_CODE471_SLEEP; 1359 gOpts.code472Sleep = DEF_CODE472_SLEEP; 1360 gOpts.code471Num = DEF_CODE471_NUM; 1361 gOpts.code471Path = (line_t*) malloc(sizeof(line_t) * gOpts.code471Num); 1362 strcpy((char*)gOpts.code471Path[0], DEF_CODE471_PATH); 1363 gOpts.code472Num = DEF_CODE472_NUM; 1364 gOpts.code472Path = (line_t*) malloc(sizeof(line_t) * gOpts.code472Num); 1365 strcpy((char*)gOpts.code472Path[0], DEF_CODE472_PATH); 1366 gOpts.loaderNum = DEF_LOADER_NUM; 1367 gOpts.loader = (name_entry*) malloc(sizeof(name_entry) * gOpts.loaderNum); 1368 strcpy(gOpts.loader[0].name, DEF_LOADER0); 1369 strcpy(gOpts.loader[0].path, DEF_LOADER0_PATH); 1370 strcpy(gOpts.loader[1].name, DEF_LOADER1); 1371 strcpy(gOpts.loader[1].path, DEF_LOADER1_PATH); 1372 strcpy(gOpts.outPath, DEF_OUT_PATH); 1373 1374 return parseOpts(); 1375 } 1376 1377 /************merge code****************/ 1378 1379 static inline uint32_t getBCD(unsigned short value) { 1380 uint8_t tmp[2] = {0}; 1381 int i; 1382 uint32_t ret; 1383 //if (value > 0xFFFF) { 1384 // return 0; 1385 //} 1386 for(i=0; i < 2; i++) { 1387 tmp[i] = (((value/10)%10)<<4) | (value%10); 1388 value /= 100; 1389 } 1390 ret = ((uint16_t)(tmp[1] << 8)) | tmp[0]; 1391 1392 printf("ret: %x\n",ret); 1393 return ret&0xFF; 1394 } 1395 1396 static inline void str2wide(const char* str, uint16_t* wide, int len) 1397 { 1398 int i; 1399 for (i = 0; i < len; i++) { 1400 wide[i] = (uint16_t) str[i]; 1401 } 1402 wide[len] = 0; 1403 } 1404 1405 static inline void getName(char* path, uint16_t* dst) { 1406 char* end; 1407 char* start; 1408 int len; 1409 if (!path || !dst) 1410 return; 1411 start = strrchr(path, '/'); 1412 if (!start) 1413 start = path; 1414 else 1415 start++; 1416 end = strrchr(path, '.'); 1417 if (!end || (end < start)) 1418 end = path + strlen(path); 1419 len = end - start; 1420 if (len >= MAX_NAME_LEN) 1421 len = MAX_NAME_LEN -1; 1422 str2wide(start, dst, len); 1423 1424 1425 char name[MAX_NAME_LEN]; 1426 memset(name, 0, sizeof(name)); 1427 memcpy(name, start, len); 1428 printf("path: %s, name: %s\n", path, name); 1429 1430 } 1431 1432 static inline bool getFileSize(const char *path, uint32_t* size) { 1433 struct stat st; 1434 if(stat(path, &st) < 0) 1435 return false; 1436 *size = st.st_size; 1437 printf("path: %s, size: %d\n", path, *size); 1438 return true; 1439 } 1440 1441 static inline rk_time getTime(void) { 1442 rk_time rkTime; 1443 1444 struct tm *tm; 1445 time_t tt = time(NULL); 1446 tm = localtime(&tt); 1447 rkTime.year = tm->tm_year + 1900; 1448 rkTime.month = tm->tm_mon + 1; 1449 rkTime.day = tm->tm_mday; 1450 rkTime.hour = tm->tm_hour; 1451 rkTime.minute = tm->tm_min; 1452 rkTime.second = tm->tm_sec; 1453 printf("%d-%d-%d %02d:%02d:%02d\n", 1454 rkTime.year, rkTime.month, rkTime.day, 1455 rkTime.hour, rkTime.minute, rkTime.second); 1456 return rkTime; 1457 } 1458 1459 static bool writeFile(FILE* outFile, const char* path, bool fix) { 1460 bool ret = false; 1461 uint32_t size = 0, fixSize = 0; 1462 uint8_t* buf; 1463 1464 FILE* inFile = fopen(path, "rb"); 1465 if (!inFile) 1466 goto end; 1467 1468 if (!getFileSize(path, &size)) 1469 goto end; 1470 if (fix) { 1471 fixSize = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1472 uint32_t tmp = fixSize % ENTRY_ALIGN; 1473 tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 1474 fixSize +=tmp; 1475 memset(gBuf, 0, fixSize); 1476 } else { 1477 memset(gBuf, 0, size+ENTRY_ALIGN); 1478 } 1479 if (!fread(gBuf, size, 1, inFile)) 1480 goto end; 1481 1482 if (fix) { 1483 1484 buf = gBuf; 1485 size = fixSize; 1486 while(1) { 1487 P_RC4(buf, fixSize < SMALL_PACKET ? fixSize : SMALL_PACKET); 1488 buf += SMALL_PACKET; 1489 if (fixSize <= SMALL_PACKET) 1490 break; 1491 fixSize -= SMALL_PACKET; 1492 } 1493 } else { 1494 uint32_t tmp = size % ENTRY_ALIGN; 1495 tmp = tmp ? (ENTRY_ALIGN - tmp): 0; 1496 size +=tmp; 1497 P_RC4(gBuf, size); 1498 } 1499 1500 if (!fwrite(gBuf, size, 1, outFile)) 1501 goto end; 1502 ret = true; 1503 end: 1504 if (inFile) 1505 fclose(inFile); 1506 if (!ret) 1507 printf("writing entry (%s) failed\n", path); 1508 return ret; 1509 } 1510 1511 static bool saveEntry(FILE* outFile, char* path, rk_entry_type type, 1512 uint16_t delay, uint32_t* offset, char* fixName, bool fix) { 1513 uint32_t size; 1514 rk_boot_entry entry; 1515 1516 printf("writing: %s\n", path); 1517 memset(&entry, 0, sizeof(rk_boot_entry)); 1518 getName(fixName ? fixName: path, entry.name); 1519 entry.size = sizeof(rk_boot_entry); 1520 entry.type = type; 1521 entry.dataOffset = *offset; 1522 if (!getFileSize(path, &size)) { 1523 printf("Saving entry (%s) failed:\n\tCannot get file size.\n", path); 1524 return false; 1525 } 1526 if (fix) 1527 size = ((size - 1) / SMALL_PACKET + 1) * SMALL_PACKET; 1528 uint32_t tmp = size % ENTRY_ALIGN; 1529 size += tmp ? (ENTRY_ALIGN - tmp): 0; 1530 printf("alignment size: %d\n", size); 1531 entry.dataSize = size; 1532 entry.dataDelay = delay; 1533 *offset += size; 1534 fwrite(&entry, sizeof(rk_boot_entry), 1, outFile); 1535 return true; 1536 } 1537 1538 static inline uint32_t convertChipType(const char* chip) { 1539 char buffer[5]; 1540 memset(buffer, 0, sizeof(buffer)); 1541 snprintf(buffer, sizeof(buffer), "%s", chip); 1542 return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 1543 } 1544 1545 static inline uint32_t getChipType(const char* chip) { 1546 printf("chip: %s\n", chip); 1547 int chipType = RKNONE_DEVICE; 1548 if(!chip) { 1549 goto end; 1550 } 1551 if (!strcmp(chip, CHIP_RK28)) { 1552 chipType = RK28_DEVICE; 1553 } else if (!strcmp(chip, CHIP_RK28)) { 1554 chipType = RK28_DEVICE; 1555 } else if (!strcmp(chip, CHIP_RK281X)) { 1556 chipType = RK281X_DEVICE; 1557 } else if (!strcmp(chip, CHIP_RKPANDA)) { 1558 chipType = RKPANDA_DEVICE; 1559 } else if (!strcmp(chip, CHIP_RK27)) { 1560 chipType = RK27_DEVICE; 1561 } else if (!strcmp(chip, CHIP_RKNANO)) { 1562 chipType = RKNANO_DEVICE; 1563 } else if (!strcmp(chip, CHIP_RKSMART)) { 1564 chipType = RKSMART_DEVICE; 1565 } else if (!strcmp(chip, CHIP_RKCROWN)) { 1566 chipType = RKCROWN_DEVICE; 1567 } else if (!strcmp(chip, CHIP_RKCAYMAN)) { 1568 chipType = RKCAYMAN_DEVICE; 1569 } else if (!strcmp(chip, CHIP_RK29)) { 1570 chipType = RK29_DEVICE; 1571 } else if (!strcmp(chip, CHIP_RK292X)) { 1572 chipType = RK292X_DEVICE; 1573 } else if (!strcmp(chip, CHIP_RK30)) { 1574 chipType = RK30_DEVICE; 1575 } else if (!strcmp(chip, CHIP_RK30B)) { 1576 chipType = RK30B_DEVICE; 1577 } else if (!strcmp(chip, CHIP_RK31)) { 1578 chipType = RK31_DEVICE; 1579 } else if (!strcmp(chip, CHIP_RK32)) { 1580 chipType = RK32_DEVICE; 1581 } else { 1582 chipType = convertChipType(chip + 2); 1583 } 1584 1585 end: 1586 printf("type: 0x%x\n", chipType); 1587 if (chipType == RKNONE_DEVICE) { 1588 printf("chip type not supported!\n"); 1589 } 1590 return chipType; 1591 } 1592 1593 static inline void getBoothdr(rk_boot_header* hdr) { 1594 memset(hdr, 0, sizeof(rk_boot_header)); 1595 hdr->tag = TAG; 1596 hdr->size = sizeof(rk_boot_header); 1597 hdr->version = (getBCD(gOpts.major) << 8) | getBCD(gOpts.minor); 1598 hdr->mergerVersion = MERGER_VERSION; 1599 hdr->releaseTime = getTime(); 1600 hdr->chipType = getChipType(gOpts.chip); 1601 1602 hdr->code471Num = gOpts.code471Num; 1603 hdr->code471Offset = sizeof(rk_boot_header); 1604 hdr->code471Size = sizeof(rk_boot_entry); 1605 1606 hdr->code472Num = gOpts.code472Num; 1607 hdr->code472Offset = hdr->code471Offset + gOpts.code471Num * hdr->code471Size; 1608 hdr->code472Size = sizeof(rk_boot_entry); 1609 1610 hdr->loaderNum = gOpts.loaderNum; 1611 hdr->loaderOffset = hdr->code472Offset + gOpts.code472Num * hdr->code472Size; 1612 hdr->loaderSize = sizeof(rk_boot_entry); 1613 #ifndef USE_P_RC4 1614 hdr->rc4Flag = 1; 1615 #endif 1616 } 1617 1618 static inline uint32_t getCrc(const char* path) { 1619 uint32_t size = 0; 1620 uint32_t crc = 0; 1621 1622 FILE* file = fopen(path, "rb"); 1623 getFileSize(path, &size); 1624 if (!file) 1625 goto end; 1626 if (!fread(gBuf, size, 1, file)) 1627 goto end; 1628 crc = CRC_32(gBuf, size); 1629 printf("crc: 0x%08x\n", crc); 1630 end: 1631 if (file) 1632 fclose(file); 1633 return crc; 1634 } 1635 1636 bool mergeBoot(void) { 1637 uint32_t dataOffset; 1638 bool ret = false; 1639 int i; 1640 FILE* outFile; 1641 uint32_t crc; 1642 rk_boot_header hdr; 1643 1644 if (!initOpts()) 1645 return false; 1646 { 1647 char* subfix = strstr(gOpts.outPath, OUT_SUBFIX); 1648 char version[MAX_LINE_LEN]; 1649 snprintf(version, sizeof(version), "%s", gSubfix); 1650 if (subfix && !strcmp(subfix, OUT_SUBFIX)) { 1651 subfix[0] = '\0'; 1652 } 1653 strcat(gOpts.outPath, version); 1654 printf("fix opt: %s\n", gOpts.outPath); 1655 } 1656 1657 printf("---------------\nUSING CONFIG:\n"); 1658 printOpts(stdout); 1659 printf("---------------\n\n"); 1660 1661 1662 outFile = fopen(gOpts.outPath, "wb+"); 1663 if (!outFile) { 1664 printf("Opening output file (%s) failed\n", gOpts.outPath); 1665 goto end; 1666 } 1667 1668 getBoothdr(&hdr); 1669 printf("Writing header...\n"); 1670 fwrite(&hdr, 1, sizeof(rk_boot_header), outFile); 1671 1672 dataOffset = sizeof(rk_boot_header) + 1673 (gOpts.code471Num + gOpts.code472Num + gOpts.loaderNum) * 1674 sizeof(rk_boot_entry); 1675 1676 printf("Writing code 471 entry...\n"); 1677 for (i=0; i<gOpts.code471Num; i++) { 1678 if (!saveEntry(outFile, (char*)gOpts.code471Path[i], ENTRY_471, gOpts.code471Sleep, 1679 &dataOffset, NULL, false)) 1680 goto end; 1681 } 1682 printf("Writing code 472 entry...\n"); 1683 for (i=0; i<gOpts.code472Num; i++) { 1684 if (!saveEntry(outFile, (char*)gOpts.code472Path[i], ENTRY_472, gOpts.code472Sleep, 1685 &dataOffset, NULL, false)) 1686 goto end; 1687 } 1688 printf("Writing loader entry...\n"); 1689 for (i=0; i<gOpts.loaderNum; i++) { 1690 if (!saveEntry(outFile, gOpts.loader[i].path, ENTRY_LOADER, 0, 1691 &dataOffset, gOpts.loader[i].name, true)) 1692 goto end; 1693 } 1694 1695 printf("Writing code 471...\n"); 1696 for (i=0; i<gOpts.code471Num; i++) { 1697 if (!writeFile(outFile, (char*)gOpts.code471Path[i], false)) 1698 goto end; 1699 } 1700 printf("Writing code 472...\n"); 1701 for (i=0; i<gOpts.code472Num; i++) { 1702 if (!writeFile(outFile, (char*)gOpts.code472Path[i], false)) 1703 goto end; 1704 } 1705 printf("Writing loader...\n"); 1706 for (i=0; i<gOpts.loaderNum; i++) { 1707 if (!writeFile(outFile, gOpts.loader[i].path, true)) 1708 goto end; 1709 } 1710 fflush(outFile); 1711 1712 printf("Writing crc...\n"); 1713 crc = getCrc(gOpts.outPath); 1714 if (!fwrite(&crc, sizeof(crc), 1, outFile)) 1715 goto end; 1716 printf("Done.\n"); 1717 ret = true; 1718 end: 1719 if (outFile) 1720 fclose(outFile); 1721 return ret; 1722 } 1723 1724 /************merge code end************/ 1725 /************unpack code***************/ 1726 1727 static inline void wide2str(const uint16_t* wide, char* str, int len) 1728 { 1729 int i; 1730 for (i = 0; i < len; i++) { 1731 str[i] = (char) (wide[i] & 0xFF); 1732 } 1733 str[len] = 0; 1734 } 1735 1736 static bool unpackEntry(rk_boot_entry* entry, const char* name, 1737 FILE* inFile) { 1738 bool ret = false; 1739 int size, i; 1740 FILE* outFile = fopen(name, "wb+"); 1741 if (!outFile) 1742 goto end; 1743 printf("unpacking entry (%s)\n", name); 1744 fseek(inFile, entry->dataOffset, SEEK_SET); 1745 size = entry->dataSize; 1746 if (!fread(gBuf, size, 1, inFile)) 1747 goto end; 1748 if (entry->type == ENTRY_LOADER) { 1749 for(i=0; i<size/SMALL_PACKET; i++) 1750 P_RC4(gBuf + i * SMALL_PACKET, SMALL_PACKET); 1751 if (size % SMALL_PACKET) 1752 { 1753 P_RC4(gBuf + i * SMALL_PACKET, size - SMALL_PACKET * 512); 1754 } 1755 } else { 1756 P_RC4(gBuf, size); 1757 } 1758 if (!fwrite(gBuf, size, 1, outFile)) 1759 goto end; 1760 ret = true; 1761 end: 1762 if (outFile) 1763 fclose(outFile); 1764 return ret; 1765 } 1766 1767 bool unpackBoot(char* path) { 1768 bool ret = false; 1769 FILE* inFile = fopen(path, "rb"); 1770 int entryNum, i; 1771 char name[MAX_NAME_LEN]; 1772 rk_boot_entry* entrys; 1773 if (!inFile) { 1774 fprintf(stderr, "loader (%s) not found\n", path); 1775 goto end; 1776 } 1777 1778 rk_boot_header hdr; 1779 if (!fread(&hdr, sizeof(rk_boot_header), 1, inFile)) { 1780 fprintf(stderr, "reading header failed\n"); 1781 goto end; 1782 } 1783 printf("471 num:%d, 472 num:%d, loader num:%d\n", hdr.code471Num, hdr.code472Num, hdr.loaderNum); 1784 entryNum = hdr.code471Num + hdr.code472Num + hdr.loaderNum; 1785 entrys = (rk_boot_entry*) malloc(sizeof(rk_boot_entry) * entryNum); 1786 if (!fread(entrys, sizeof(rk_boot_entry) * entryNum, 1, inFile)) { 1787 fprintf(stderr, "reading data failed\n"); 1788 goto end; 1789 } 1790 1791 printf("entry num: %d\n", entryNum); 1792 for (i=0; i<entryNum; i++) { 1793 wide2str(entrys[i].name, name, MAX_NAME_LEN); 1794 1795 printf("entry: t=%d, name=%s, off=%d, size=%d\n", 1796 entrys[i].type, name, entrys[i].dataOffset, 1797 entrys[i].dataSize); 1798 if (!unpackEntry(entrys + i, name, inFile)) { 1799 fprintf(stderr, "unpacking entry (%s) failed\n", name); 1800 goto end; 1801 } 1802 } 1803 printf("done\n"); 1804 ret = true; 1805 end: 1806 if (inFile) 1807 fclose(inFile); 1808 return ret; 1809 } 1810 1811 bool download_boot(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1812 { 1813 if (!check_device_type(dev, RKUSB_MASKROM)) 1814 return false; 1815 CRKImage *pImage = NULL; 1816 CRKBoot *pBoot = NULL; 1817 bool bRet, bSuccess = false; 1818 int iRet; 1819 1820 pImage = new CRKImage(szLoader, bRet); 1821 if (!bRet){ 1822 ERROR_COLOR_ATTR; 1823 printf("Opening loader failed, exiting download boot!"); 1824 NORMAL_COLOR_ATTR; 1825 printf("\r\n"); 1826 return bSuccess; 1827 } else { 1828 pBoot = (CRKBoot *)pImage->m_bootObject; 1829 CRKComm *pComm = NULL; 1830 CRKDevice *pDevice = NULL; 1831 1832 dev.emDeviceType = pBoot->SupportDevice; 1833 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1834 if (!bRet) { 1835 if (pImage) 1836 delete pImage; 1837 ERROR_COLOR_ATTR; 1838 printf("Creating Comm Object failed!"); 1839 NORMAL_COLOR_ATTR; 1840 printf("\r\n"); 1841 return bSuccess; 1842 } 1843 1844 pDevice = new CRKDevice(dev); 1845 if (!pDevice) { 1846 if (pImage) 1847 delete pImage; 1848 if (pComm) 1849 delete pComm; 1850 ERROR_COLOR_ATTR; 1851 printf("Creating device object failed!"); 1852 NORMAL_COLOR_ATTR; 1853 printf("\r\n"); 1854 return bSuccess; 1855 } 1856 1857 pDevice->SetObject(pImage, pComm, g_pLogObject); 1858 printf("Downloading bootloader...\r\n"); 1859 iRet = pDevice->DownloadBoot(); 1860 1861 CURSOR_MOVEUP_LINE(1); 1862 CURSOR_DEL_LINE; 1863 if (iRet == 0) { 1864 bSuccess = true; 1865 printf("Downloading bootloader succeeded.\r\n"); 1866 } 1867 else 1868 printf("Downloading bootloader failed!\r\n"); 1869 1870 if (pImage) 1871 delete pImage; 1872 if(pDevice) 1873 delete pDevice; 1874 } 1875 return bSuccess; 1876 } 1877 bool upgrade_loader(STRUCT_RKDEVICE_DESC &dev, char *szLoader) 1878 { 1879 if (!check_device_type(dev, RKUSB_MASKROM)) 1880 return false; 1881 CRKImage *pImage = NULL; 1882 CRKBoot *pBoot = NULL; 1883 CRKComm *pComm = NULL; 1884 bool bRet, bSuccess = false; 1885 int iRet; 1886 char index; 1887 USHORT usFlashDataSec, usFlashBootSec; 1888 DWORD dwLoaderSize, dwLoaderDataSize, dwDelay, dwSectorNum; 1889 char loaderCodeName[] = "FlashBoot"; 1890 char loaderDataName[] = "FlashData"; 1891 PBYTE loaderCodeBuffer = NULL; 1892 PBYTE loaderDataBuffer = NULL; 1893 PBYTE pIDBData = NULL; 1894 pImage = new CRKImage(szLoader, bRet); 1895 if (!bRet){ 1896 ERROR_COLOR_ATTR; 1897 printf("Opening loader failed, exiting upgrade loader!"); 1898 NORMAL_COLOR_ATTR; 1899 printf("\r\n"); 1900 goto Exit_UpgradeLoader; 1901 } else { 1902 pBoot = (CRKBoot *)pImage->m_bootObject; 1903 dev.emDeviceType = pBoot->SupportDevice; 1904 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 1905 if (!bRet) { 1906 ERROR_COLOR_ATTR; 1907 printf("Creating Comm Object failed!"); 1908 NORMAL_COLOR_ATTR; 1909 printf("\r\n"); 1910 goto Exit_UpgradeLoader; 1911 } 1912 1913 printf("Upgrading loader...\r\n"); 1914 index = pBoot->GetIndexByName(ENTRYLOADER, loaderCodeName); 1915 if (index == -1) { 1916 if (g_pLogObject) { 1917 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry failed", __func__); 1918 } 1919 goto Exit_UpgradeLoader; 1920 } 1921 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderSize, dwDelay); 1922 if (!bRet) { 1923 if (g_pLogObject) { 1924 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Entry Size failed", __func__); 1925 } 1926 goto Exit_UpgradeLoader; 1927 } 1928 1929 loaderCodeBuffer = new BYTE[dwLoaderSize]; 1930 memset(loaderCodeBuffer, 0, dwLoaderSize); 1931 if (!pBoot->GetEntryData(ENTRYLOADER, index, loaderCodeBuffer)) { 1932 if (g_pLogObject) { 1933 g_pLogObject->Record("ERROR: %s --> Get LoaderCode Data failed", __func__); 1934 } 1935 goto Exit_UpgradeLoader; 1936 } 1937 1938 index = pBoot->GetIndexByName(ENTRYLOADER, loaderDataName); 1939 if (index == -1) { 1940 if (g_pLogObject) { 1941 g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry failed", __func__); 1942 } 1943 delete []loaderCodeBuffer; 1944 return -4; 1945 } 1946 1947 bRet = pBoot->GetEntryProperty(ENTRYLOADER, index, dwLoaderDataSize, dwDelay); 1948 if (!bRet) { 1949 if (g_pLogObject) { 1950 g_pLogObject->Record("ERROR: %s --> Get LoaderData Entry Size failed", __func__); 1951 } 1952 goto Exit_UpgradeLoader; 1953 } 1954 1955 loaderDataBuffer = new BYTE[dwLoaderDataSize]; 1956 memset(loaderDataBuffer, 0, dwLoaderDataSize); 1957 if (!pBoot->GetEntryData(ENTRYLOADER,index,loaderDataBuffer)) { 1958 if (g_pLogObject) { 1959 g_pLogObject->Record("ERROR: %s --> Get LoaderData Data failed", __func__); 1960 } 1961 goto Exit_UpgradeLoader; 1962 } 1963 1964 usFlashDataSec = (ALIGN(dwLoaderDataSize, 2048)) / SECTOR_SIZE; 1965 usFlashBootSec = (ALIGN(dwLoaderSize, 2048)) / SECTOR_SIZE; 1966 dwSectorNum = 4 + usFlashDataSec + usFlashBootSec; 1967 pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE]; 1968 if (!pIDBData) { 1969 ERROR_COLOR_ATTR; 1970 printf("Allocating memory failed!"); 1971 NORMAL_COLOR_ATTR; 1972 printf("\r\n"); 1973 goto Exit_UpgradeLoader; 1974 } 1975 memset(pIDBData, 0, dwSectorNum * SECTOR_SIZE); 1976 iRet = MakeIDBlockData(loaderDataBuffer, loaderCodeBuffer, pIDBData, usFlashDataSec, usFlashBootSec, dwLoaderDataSize, dwLoaderSize, pBoot->Rc4DisableFlag); 1977 if (iRet != 0) { 1978 ERROR_COLOR_ATTR; 1979 printf("Making idblock failed!"); 1980 NORMAL_COLOR_ATTR; 1981 printf("\r\n"); 1982 goto Exit_UpgradeLoader; 1983 } 1984 iRet = pComm->RKU_WriteLBA(64, dwSectorNum, pIDBData); 1985 CURSOR_MOVEUP_LINE(1); 1986 CURSOR_DEL_LINE; 1987 if (iRet == ERR_SUCCESS) { 1988 //pComm->Reset_Usb_Device(); 1989 bSuccess = true; 1990 printf("Upgrading loader succeeded.\r\n"); 1991 } else { 1992 printf("Upgrading loader failed!\r\n"); 1993 goto Exit_UpgradeLoader; 1994 } 1995 } 1996 Exit_UpgradeLoader: 1997 if (pImage) 1998 delete pImage; 1999 if (pComm) 2000 delete pComm; 2001 if (loaderCodeBuffer) 2002 delete []loaderCodeBuffer; 2003 if (loaderDataBuffer) 2004 delete []loaderDataBuffer; 2005 if (pIDBData) 2006 delete []pIDBData; 2007 return bSuccess; 2008 } 2009 bool print_gpt(STRUCT_RKDEVICE_DESC &dev) 2010 { 2011 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2012 return false; 2013 u8 master_gpt[34 * SECTOR_SIZE]; 2014 gpt_header *gptHead = (gpt_header *)(master_gpt + SECTOR_SIZE); 2015 bool bRet, bSuccess = false; 2016 int iRet; 2017 gpt_entry *gptEntry = NULL; 2018 u32 i,j; 2019 u8 zerobuf[GPT_ENTRY_SIZE]; 2020 memset(zerobuf,0,GPT_ENTRY_SIZE); 2021 CRKComm *pComm = NULL; 2022 char partName[36]; 2023 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2024 if (!bRet) { 2025 ERROR_COLOR_ATTR; 2026 printf("Creating Comm Object failed!"); 2027 NORMAL_COLOR_ATTR; 2028 printf("\r\n"); 2029 return bSuccess; 2030 } 2031 iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt); 2032 if(ERR_SUCCESS == iRet) { 2033 if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 2034 goto Exit_PrintGpt; 2035 } 2036 2037 } else { 2038 if (g_pLogObject) 2039 g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 2040 printf("Read GPT failed!\r\n"); 2041 goto Exit_PrintGpt; 2042 } 2043 2044 printf("**********Partition Info(GPT)**********\r\n"); 2045 printf("NO LBA Name \r\n"); 2046 for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) { 2047 gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); 2048 if (memcmp(zerobuf, (u8 *)gptEntry, GPT_ENTRY_SIZE) == 0) 2049 break; 2050 memset(partName, 0 , 36); 2051 j = 0; 2052 while (gptEntry->partition_name[j]) { 2053 partName[j] = (char)gptEntry->partition_name[j]; 2054 j++; 2055 } 2056 printf("%02d %08X %s\r\n", i, (u32)le64_to_cpu(gptEntry->starting_lba), partName); 2057 } 2058 bSuccess = true; 2059 Exit_PrintGpt: 2060 if (pComm) 2061 delete pComm; 2062 return bSuccess; 2063 } 2064 bool print_parameter(STRUCT_RKDEVICE_DESC &dev) 2065 { 2066 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2067 return false; 2068 u8 param_buf[512 * SECTOR_SIZE]; 2069 bool bRet, bSuccess = false; 2070 int iRet; 2071 u32 i, nParamSize; 2072 CRKComm *pComm = NULL; 2073 PARAM_ITEM_VECTOR vecParamItem; 2074 CONFIG_ITEM_VECTOR vecUuidItem; 2075 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2076 if (!bRet) { 2077 ERROR_COLOR_ATTR; 2078 printf("Creating Comm Object failed!"); 2079 NORMAL_COLOR_ATTR; 2080 printf("\r\n"); 2081 return bSuccess; 2082 } 2083 iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf); 2084 if(ERR_SUCCESS == iRet) { 2085 if (*(u32 *)param_buf != 0x4D524150) { 2086 goto Exit_PrintParam; 2087 } 2088 2089 } else { 2090 if (g_pLogObject) 2091 g_pLogObject->Record("Error: read parameter failed, err=%d", iRet); 2092 printf("Read parameter failed!\r\n"); 2093 goto Exit_PrintParam; 2094 } 2095 nParamSize = *(u32 *)(param_buf + 4); 2096 memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8); 2097 2098 bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem); 2099 if (!bRet) { 2100 if (g_pLogObject) 2101 g_pLogObject->Record("Error: parse parameter failed"); 2102 printf("Parse parameter failed!\r\n"); 2103 goto Exit_PrintParam; 2104 } 2105 printf("**********Partition Info(parameter)**********\r\n"); 2106 printf("NO LBA Name \r\n"); 2107 for (i = 0; i < vecParamItem.size(); i++) { 2108 printf("%02d %08X %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName); 2109 } 2110 bSuccess = true; 2111 Exit_PrintParam: 2112 if (pComm) 2113 delete pComm; 2114 return bSuccess; 2115 } 2116 2117 bool erase_flash(STRUCT_RKDEVICE_DESC &dev) 2118 { 2119 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2120 return false; 2121 CRKImage *pImage = NULL; 2122 bool bRet, bSuccess = false; 2123 int iRet; 2124 CRKScan *pScan = NULL; 2125 pScan = new CRKScan(); 2126 pScan->SetVidPid(); 2127 2128 CRKComm *pComm = NULL; 2129 CRKDevice *pDevice = NULL; 2130 2131 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2132 if (!bRet) { 2133 if (pScan) 2134 delete pScan; 2135 ERROR_COLOR_ATTR; 2136 printf("Creating Comm Object failed!"); 2137 NORMAL_COLOR_ATTR; 2138 printf("\r\n"); 2139 return bSuccess; 2140 } 2141 2142 pDevice = new CRKDevice(dev); 2143 if (!pDevice) { 2144 if (pComm) 2145 delete pComm; 2146 if (pScan) 2147 delete pScan; 2148 ERROR_COLOR_ATTR; 2149 printf("Creating device object failed!"); 2150 NORMAL_COLOR_ATTR; 2151 printf("\r\n"); 2152 return bSuccess; 2153 } 2154 2155 pDevice->SetObject(pImage, pComm, g_pLogObject); 2156 pDevice->CallBackPointer = ProgressInfoProc; 2157 2158 printf("Starting to erase flash...\r\n"); 2159 bRet = pDevice->GetFlashInfo(); 2160 if (!bRet) { 2161 if (pDevice) 2162 delete pDevice; 2163 if (pScan) 2164 delete pScan; 2165 ERROR_COLOR_ATTR; 2166 printf("Getting flash info from device failed!"); 2167 NORMAL_COLOR_ATTR; 2168 printf("\r\n"); 2169 return bSuccess; 2170 } 2171 iRet = pDevice->EraseAllBlocks(); 2172 if (pDevice) 2173 delete pDevice; 2174 2175 if (iRet == 0) { 2176 if (pScan) { 2177 pScan->SetVidPid(); 2178 pScan->Wait(dev, RKUSB_MASKROM, dev.usVid, dev.usPid); 2179 delete pScan; 2180 } 2181 CURSOR_MOVEUP_LINE(1); 2182 CURSOR_DEL_LINE; 2183 bSuccess = true; 2184 printf("Erasing flash complete.\r\n"); 2185 } 2186 2187 return bSuccess; 2188 } 2189 2190 bool test_device(STRUCT_RKDEVICE_DESC &dev) 2191 { 2192 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2193 return false; 2194 CRKUsbComm *pComm = NULL; 2195 bool bRet, bSuccess = false; 2196 int iRet; 2197 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2198 if (bRet) { 2199 iRet = pComm->RKU_TestDeviceReady(); 2200 if (iRet != ERR_SUCCESS) { 2201 if (g_pLogObject) 2202 g_pLogObject->Record("Error: RKU_TestDeviceReady failed, err=%d", iRet); 2203 printf("Test Device failed!\r\n"); 2204 } else { 2205 bSuccess = true; 2206 printf("Test Device OK.\r\n"); 2207 } 2208 } else { 2209 printf("Test Device quit, creating comm object failed!\r\n"); 2210 } 2211 if (pComm) { 2212 delete pComm; 2213 pComm = NULL; 2214 } 2215 return bSuccess; 2216 } 2217 bool reset_device(STRUCT_RKDEVICE_DESC &dev, BYTE subCode = RST_NONE_SUBCODE) 2218 { 2219 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2220 return false; 2221 CRKUsbComm *pComm = NULL; 2222 bool bRet, bSuccess = false; 2223 int iRet; 2224 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2225 if (bRet) { 2226 iRet = pComm->RKU_ResetDevice(subCode); 2227 if (iRet != ERR_SUCCESS) { 2228 if (g_pLogObject) 2229 g_pLogObject->Record("Error: RKU_ResetDevice failed, err=%d", iRet); 2230 printf("Reset Device failed!\r\n"); 2231 } else { 2232 bSuccess = true; 2233 printf("Reset Device OK.\r\n"); 2234 } 2235 } else { 2236 printf("Reset Device quit, creating comm object failed!\r\n"); 2237 } 2238 if (pComm) { 2239 delete pComm; 2240 pComm = NULL; 2241 } 2242 return bSuccess; 2243 } 2244 2245 bool read_flash_id(STRUCT_RKDEVICE_DESC &dev) 2246 { 2247 CRKUsbComm *pComm = NULL; 2248 bool bRet, bSuccess = false; 2249 int iRet; 2250 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2251 return bSuccess; 2252 2253 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2254 if (bRet) { 2255 BYTE flashID[5]; 2256 iRet = pComm->RKU_ReadFlashID(flashID); 2257 if (iRet != ERR_SUCCESS) { 2258 if (g_pLogObject) 2259 g_pLogObject->Record("Error: RKU_ReadFlashID failed, err=%d", iRet); 2260 printf("Reading flash ID failed!\r\n"); 2261 } else { 2262 printf("Flash ID: %02X %02X %02X %02X %02X\r\n", flashID[0], flashID[1], flashID[2], flashID[3], flashID[4]); 2263 bSuccess = true; 2264 } 2265 } else { 2266 printf("Read Flash ID quit, creating comm object failed!\r\n"); 2267 } 2268 if (pComm) { 2269 delete pComm; 2270 pComm = NULL; 2271 } 2272 return bSuccess; 2273 } 2274 bool read_flash_info(STRUCT_RKDEVICE_DESC &dev) 2275 { 2276 CRKUsbComm *pComm = NULL; 2277 bool bRet, bSuccess = false; 2278 int iRet; 2279 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2280 return bSuccess; 2281 2282 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2283 if (bRet) { 2284 STRUCT_FLASHINFO_CMD info; 2285 UINT uiRead; 2286 iRet = pComm->RKU_ReadFlashInfo((BYTE *)&info, &uiRead); 2287 if (iRet != ERR_SUCCESS) { 2288 if (g_pLogObject) 2289 g_pLogObject->Record("Error: RKU_ReadFlashInfo failed, err=%d", iRet); 2290 printf("Read Flash Info failed!\r\n"); 2291 } else { 2292 printf("Flash Info:\r\n"); 2293 if (info.bManufCode <= 7) { 2294 printf("\tManufacturer: %s, value=%02X\r\n", szManufName[info.bManufCode], info.bManufCode); 2295 } 2296 else 2297 printf("\tManufacturer: %s, value=%02X\r\n", "Unknown", info.bManufCode); 2298 2299 printf("\tFlash Size: %d MB\r\n", info.uiFlashSize / 2 / 1024); 2300 printf("\tBlock Size: %d KB\r\n", info.usBlockSize / 2); 2301 printf("\tPage Size: %d KB\r\n", info.bPageSize / 2); 2302 printf("\tECC Bits: %d\r\n", info.bECCBits); 2303 printf("\tAccess Time: %d\r\n", info.bAccessTime); 2304 printf("\tFlash CS: "); 2305 for(int i = 0; i < 8; i++) { 2306 if( info.bFlashCS & (1 << i) ) 2307 printf("Flash<%d> ", i); 2308 } 2309 printf("\r\n"); 2310 bSuccess = true; 2311 } 2312 }else { 2313 printf("Read Flash Info quit, creating comm object failed!\r\n"); 2314 } 2315 if (pComm) { 2316 delete pComm; 2317 pComm = NULL; 2318 } 2319 return bSuccess; 2320 } 2321 bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) 2322 { 2323 CRKUsbComm *pComm = NULL; 2324 bool bRet, bSuccess = false; 2325 int iRet; 2326 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2327 return bSuccess; 2328 2329 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2330 if (bRet) { 2331 BYTE chipInfo[16]; 2332 iRet = pComm->RKU_ReadChipInfo(chipInfo); 2333 if (iRet != ERR_SUCCESS) { 2334 if (g_pLogObject) 2335 g_pLogObject->Record("Error: RKU_ReadChipInfo failed, err=%d", iRet); 2336 printf("Read Chip Info failed!\r\n"); 2337 } else { 2338 string strChipInfo; 2339 g_pLogObject->PrintBuffer(strChipInfo, chipInfo, 16, 16); 2340 printf("Chip Info: %s\r\n", strChipInfo.c_str()); 2341 bSuccess = true; 2342 } 2343 } else { 2344 printf("Read Chip Info quit, creating comm object failed!\r\n"); 2345 } 2346 if (pComm) { 2347 delete pComm; 2348 pComm = NULL; 2349 } 2350 return bSuccess; 2351 } 2352 bool read_capability(STRUCT_RKDEVICE_DESC &dev) 2353 { 2354 CRKUsbComm *pComm = NULL; 2355 bool bRet, bSuccess = false; 2356 int iRet; 2357 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2358 return bSuccess; 2359 2360 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2361 if (bRet) { 2362 2363 BYTE capability[8]; 2364 iRet = pComm->RKU_ReadCapability(capability); 2365 if (iRet != ERR_SUCCESS) 2366 { 2367 if (g_pLogObject) 2368 g_pLogObject->Record("Error:read_capability failed,err=%d", iRet); 2369 printf("Read capability Fail!\r\n"); 2370 } else { 2371 printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n", 2372 capability[0], capability[1], capability[2], capability[3], 2373 capability[4], capability[5], capability[6], capability[7]); 2374 if (capability[0] & 1) 2375 { 2376 printf("Direct LBA:\tenabled\r\n"); 2377 } 2378 2379 if (capability[0] & 2) 2380 { 2381 printf("Vendor Storage:\tenabled\r\n"); 2382 } 2383 2384 if (capability[0] & 4) 2385 { 2386 printf("First 4m Access:\tenabled\r\n"); 2387 } 2388 bSuccess = true; 2389 } 2390 } else { 2391 printf("Read capability quit, creating comm object failed!\r\n"); 2392 } 2393 if (pComm) { 2394 delete pComm; 2395 pComm = NULL; 2396 } 2397 return bSuccess; 2398 } 2399 bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam) 2400 { 2401 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2402 return false; 2403 CRKUsbComm *pComm = NULL; 2404 bool bRet, bSuccess = false; 2405 int iRet; 2406 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2407 if (bRet) { 2408 iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam); 2409 if(ERR_SUCCESS == iRet) { 2410 if (*(u32 *)pParam != 0x4D524150) { 2411 goto Exit_ReadParam; 2412 } 2413 } else { 2414 if (g_pLogObject) 2415 g_pLogObject->Record("Error: read parameter failed, err=%d", iRet); 2416 printf("Read parameter failed!\r\n"); 2417 goto Exit_ReadParam; 2418 } 2419 bSuccess = true; 2420 } 2421 Exit_ReadParam: 2422 if (pComm) { 2423 delete pComm; 2424 pComm = NULL; 2425 } 2426 return bSuccess; 2427 } 2428 2429 2430 bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) 2431 { 2432 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2433 return false; 2434 gpt_header *gptHead = (gpt_header *)(pGpt + SECTOR_SIZE); 2435 CRKUsbComm *pComm = NULL; 2436 bool bRet, bSuccess = false; 2437 int iRet; 2438 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2439 if (bRet) { 2440 iRet = pComm->RKU_ReadLBA( 0, 34, pGpt); 2441 if(ERR_SUCCESS == iRet) { 2442 if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { 2443 goto Exit_ReadGPT; 2444 } 2445 } else { 2446 if (g_pLogObject) 2447 g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); 2448 printf("Read GPT failed!\r\n"); 2449 goto Exit_ReadGPT; 2450 } 2451 bSuccess = true; 2452 } 2453 Exit_ReadGPT: 2454 if (pComm) { 2455 delete pComm; 2456 pComm = NULL; 2457 } 2458 return bSuccess; 2459 } 2460 bool read_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiLen, char *szFile) 2461 { 2462 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2463 return false; 2464 CRKUsbComm *pComm = NULL; 2465 FILE *file = NULL; 2466 bool bRet, bFirst = true, bSuccess = false; 2467 int iRet; 2468 UINT iTotalRead = 0,iRead = 0; 2469 int nSectorSize = 512; 2470 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 2471 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2472 if (bRet) { 2473 if(szFile) { 2474 file = fopen(szFile, "wb+"); 2475 if( !file ) { 2476 printf("Read LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 2477 goto Exit_ReadLBA; 2478 } 2479 } 2480 2481 while(uiLen > 0) { 2482 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 2483 iRead = (uiLen >= DEFAULT_RW_LBA) ? DEFAULT_RW_LBA : uiLen; 2484 iRet = pComm->RKU_ReadLBA( uiBegin + iTotalRead, iRead, pBuf); 2485 if(ERR_SUCCESS == iRet) { 2486 uiLen -= iRead; 2487 iTotalRead += iRead; 2488 2489 if(szFile) { 2490 fwrite(pBuf, 1, iRead * nSectorSize, file); 2491 if (bFirst){ 2492 if (iTotalRead >= 1024) 2493 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 2494 else 2495 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 2496 bFirst = false; 2497 } else { 2498 CURSOR_MOVEUP_LINE(1); 2499 CURSOR_DEL_LINE; 2500 if (iTotalRead >= 1024) 2501 printf("Read LBA to file (%d%%)\r\n", (iTotalRead / 1024) * 100 / ((uiLen + iTotalRead) / 1024)); 2502 else 2503 printf("Read LBA to file (%d%%)\r\n", iTotalRead * 100 / (uiLen + iTotalRead)); 2504 } 2505 } 2506 else 2507 PrintData(pBuf, nSectorSize * iRead); 2508 } else { 2509 if (g_pLogObject) 2510 g_pLogObject->Record("Error: RKU_ReadLBA failed, err=%d", iRet); 2511 2512 printf("Read LBA failed!\r\n"); 2513 goto Exit_ReadLBA; 2514 } 2515 } 2516 bSuccess = true; 2517 } else { 2518 printf("Read LBA quit, creating comm object failed!\r\n"); 2519 } 2520 Exit_ReadLBA: 2521 if (pComm) { 2522 delete pComm; 2523 pComm = NULL; 2524 } 2525 if (file) 2526 fclose(file); 2527 return bSuccess; 2528 } 2529 bool erase_partition(CRKUsbComm *pComm, UINT uiOffset, UINT uiSize) 2530 { 2531 UINT uiErase=1024*32; 2532 bool bSuccess = true; 2533 int iRet; 2534 while (uiSize) 2535 { 2536 if (uiSize>=uiErase) 2537 { 2538 iRet = pComm->RKU_EraseLBA(uiOffset,uiErase); 2539 uiSize -= uiErase; 2540 uiOffset += uiErase; 2541 } 2542 else 2543 { 2544 iRet = pComm->RKU_EraseLBA(uiOffset,uiSize); 2545 uiSize = 0; 2546 uiOffset += uiSize; 2547 } 2548 if (iRet!=ERR_SUCCESS) 2549 { 2550 if (g_pLogObject) 2551 { 2552 g_pLogObject->Record("ERROR:erase_partition failed,err=%d",iRet); 2553 } 2554 bSuccess = false; 2555 break; 2556 } 2557 } 2558 return bSuccess; 2559 2560 } 2561 bool EatSparseChunk(FILE *file, chunk_header &chunk) 2562 { 2563 UINT uiRead; 2564 uiRead = fread(&chunk, 1, sizeof(chunk_header), file); 2565 if (uiRead != sizeof(chunk_header)) { 2566 if (g_pLogObject) 2567 { 2568 g_pLogObject->Record("Error:EatSparseChunk failed,err=%d", errno); 2569 } 2570 return false; 2571 } 2572 return true; 2573 } 2574 bool EatSparseData(FILE *file, PBYTE pBuf, DWORD dwSize) 2575 { 2576 UINT uiRead; 2577 uiRead = fread(pBuf, 1, dwSize, file); 2578 if (uiRead!=dwSize) 2579 { 2580 if (g_pLogObject) 2581 { 2582 g_pLogObject->Record("Error:EatSparseData failed,err=%d",errno); 2583 } 2584 return false; 2585 } 2586 return true; 2587 } 2588 2589 bool write_sparse_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, UINT uiSize, char *szFile) 2590 { 2591 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2592 return false; 2593 CRKUsbComm *pComm = NULL; 2594 FILE *file = NULL; 2595 bool bRet, bSuccess = false, bFirst = true; 2596 int iRet; 2597 u64 iTotalWrite = 0, iFileSize = 0; 2598 UINT iRead = 0, uiTransferSec, curChunk, i; 2599 UINT dwChunkDataSize, dwMaxReadWriteBytes, dwTransferBytes, dwFillByte, dwCrc; 2600 BYTE pBuf[SECTOR_SIZE * DEFAULT_RW_LBA]; 2601 sparse_header header; 2602 chunk_header chunk; 2603 dwMaxReadWriteBytes = DEFAULT_RW_LBA * SECTOR_SIZE; 2604 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2605 if (bRet) { 2606 2607 file = fopen(szFile, "rb"); 2608 if( !file ) { 2609 printf("%s failed, err=%d, can't open file: %s\r\n", __func__, errno, szFile); 2610 goto Exit_WriteSparseLBA; 2611 } 2612 fseeko(file, 0, SEEK_SET); 2613 iRead = fread(&header, 1, sizeof(header), file); 2614 if (iRead != sizeof(sparse_header)) 2615 { 2616 if (g_pLogObject) 2617 { 2618 g_pLogObject->Record("ERROR:%s-->read sparse header failed,file=%s,err=%d", __func__, szFile, errno); 2619 } 2620 goto Exit_WriteSparseLBA; 2621 } 2622 iFileSize = header.blk_sz * (u64)header.total_blks; 2623 iTotalWrite = 0; 2624 curChunk = 0; 2625 if (uiSize==(u32)-1) 2626 uiSize = ALIGN(iFileSize, SECTOR_SIZE); 2627 bRet = erase_partition(pComm, uiBegin, uiSize); 2628 if (!bRet) { 2629 printf("%s failed, erase partition error\r\n", __func__); 2630 goto Exit_WriteSparseLBA; 2631 } 2632 while(curChunk < header.total_chunks) 2633 { 2634 if (!EatSparseChunk(file, chunk)) { 2635 goto Exit_WriteSparseLBA; 2636 } 2637 curChunk++; 2638 switch (chunk.chunk_type) { 2639 case CHUNK_TYPE_RAW: 2640 dwChunkDataSize = chunk.total_sz - sizeof(chunk_header); 2641 while (dwChunkDataSize) { 2642 memset(pBuf, 0, dwMaxReadWriteBytes); 2643 if (dwChunkDataSize >= dwMaxReadWriteBytes) { 2644 dwTransferBytes = dwMaxReadWriteBytes; 2645 uiTransferSec = DEFAULT_RW_LBA; 2646 } else { 2647 dwTransferBytes = dwChunkDataSize; 2648 uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 2649 } 2650 if (!EatSparseData(file, pBuf, dwTransferBytes)) { 2651 goto Exit_WriteSparseLBA; 2652 } 2653 iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 2654 if( ERR_SUCCESS == iRet ) { 2655 dwChunkDataSize -= dwTransferBytes; 2656 iTotalWrite += dwTransferBytes; 2657 uiBegin += uiTransferSec; 2658 } else { 2659 if (g_pLogObject) { 2660 g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)", __func__, iTotalWrite, iRet); 2661 } 2662 goto Exit_WriteSparseLBA; 2663 } 2664 if (bFirst) { 2665 if (iTotalWrite >= 1024) 2666 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2667 else 2668 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2669 bFirst = false; 2670 } else { 2671 CURSOR_MOVEUP_LINE(1); 2672 CURSOR_DEL_LINE; 2673 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2674 } 2675 } 2676 break; 2677 case CHUNK_TYPE_FILL: 2678 dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 2679 if (!EatSparseData(file, (PBYTE)&dwFillByte, 4)) { 2680 goto Exit_WriteSparseLBA; 2681 } 2682 while (dwChunkDataSize) { 2683 memset(pBuf, 0, dwMaxReadWriteBytes); 2684 if (dwChunkDataSize >= dwMaxReadWriteBytes) { 2685 dwTransferBytes = dwMaxReadWriteBytes; 2686 uiTransferSec = DEFAULT_RW_LBA; 2687 } else { 2688 dwTransferBytes = dwChunkDataSize; 2689 uiTransferSec = ((dwTransferBytes % SECTOR_SIZE == 0) ? (dwTransferBytes / SECTOR_SIZE) : (dwTransferBytes / SECTOR_SIZE + 1)); 2690 } 2691 for (i = 0; i < dwTransferBytes / 4; i++) { 2692 *(DWORD *)(pBuf + i * 4) = dwFillByte; 2693 } 2694 iRet = pComm->RKU_WriteLBA(uiBegin, uiTransferSec, pBuf); 2695 if( ERR_SUCCESS == iRet ) { 2696 dwChunkDataSize -= dwTransferBytes; 2697 iTotalWrite += dwTransferBytes; 2698 uiBegin += uiTransferSec; 2699 } else { 2700 if (g_pLogObject) { 2701 g_pLogObject->Record("ERROR:%s-->RKU_WriteLBA failed,Written(%d),RetCode(%d)" ,__func__, iTotalWrite, iRet); 2702 } 2703 goto Exit_WriteSparseLBA; 2704 } 2705 if (bFirst) { 2706 if (iTotalWrite >= 1024) 2707 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2708 else 2709 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2710 bFirst = false; 2711 } else { 2712 CURSOR_MOVEUP_LINE(1); 2713 CURSOR_DEL_LINE; 2714 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2715 } 2716 } 2717 break; 2718 case CHUNK_TYPE_DONT_CARE: 2719 dwChunkDataSize = chunk.chunk_sz * header.blk_sz; 2720 iTotalWrite += dwChunkDataSize; 2721 uiTransferSec = ((dwChunkDataSize % SECTOR_SIZE == 0) ? (dwChunkDataSize / SECTOR_SIZE) : (dwChunkDataSize / SECTOR_SIZE + 1)); 2722 uiBegin += uiTransferSec; 2723 if (bFirst) { 2724 if (iTotalWrite >= 1024) 2725 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2726 else 2727 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2728 bFirst = false; 2729 } else { 2730 CURSOR_MOVEUP_LINE(1); 2731 CURSOR_DEL_LINE; 2732 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2733 } 2734 break; 2735 case CHUNK_TYPE_CRC32: 2736 EatSparseData(file,(PBYTE)&dwCrc,4); 2737 break; 2738 } 2739 } 2740 bSuccess = true; 2741 } else { 2742 printf("Write LBA quit, creating comm object failed!\r\n"); 2743 } 2744 Exit_WriteSparseLBA: 2745 if (pComm) { 2746 delete pComm; 2747 pComm = NULL; 2748 } 2749 if (file) 2750 fclose(file); 2751 return bSuccess; 2752 2753 } 2754 2755 bool write_lba(STRUCT_RKDEVICE_DESC &dev, UINT uiBegin, char *szFile) 2756 { 2757 if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) 2758 return false; 2759 CRKUsbComm *pComm = NULL; 2760 FILE *file = NULL; 2761 bool bRet, bFirst = true, bSuccess = false; 2762 int iRet; 2763 long long iTotalWrite = 0, iFileSize = 0; 2764 UINT iWrite = 0, iRead = 0; 2765 UINT uiLen; 2766 int nSectorSize = 512; 2767 BYTE pBuf[nSectorSize * DEFAULT_RW_LBA]; 2768 2769 pComm = new CRKUsbComm(dev, g_pLogObject, bRet); 2770 if (bRet) { 2771 file = fopen(szFile, "rb"); 2772 if( !file ) { 2773 printf("Write LBA failed, err=%d, can't open file: %s\r\n", errno, szFile); 2774 goto Exit_WriteLBA; 2775 } 2776 2777 iRet = fseeko(file, 0, SEEK_END); 2778 iFileSize = ftello(file); 2779 fseeko(file, 0, SEEK_SET); 2780 while(iTotalWrite < iFileSize) { 2781 memset(pBuf, 0, nSectorSize * DEFAULT_RW_LBA); 2782 iWrite = iRead= fread(pBuf, 1, nSectorSize * DEFAULT_RW_LBA, file); 2783 uiLen = ((iWrite % 512) == 0) ? (iWrite / 512) : (iWrite / 512 + 1); 2784 iRet = pComm->RKU_WriteLBA( uiBegin, uiLen, pBuf); 2785 if(ERR_SUCCESS == iRet) { 2786 uiBegin += uiLen; 2787 iTotalWrite += iWrite; 2788 if (bFirst) { 2789 if (iTotalWrite >= 1024) 2790 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2791 else 2792 printf("Write LBA from file (%lld%%)\r\n", iTotalWrite * 100 / iFileSize); 2793 bFirst = false; 2794 } else { 2795 CURSOR_MOVEUP_LINE(1); 2796 CURSOR_DEL_LINE; 2797 printf("Write LBA from file (%lld%%)\r\n", (iTotalWrite / 1024) * 100 / (iFileSize / 1024)); 2798 } 2799 } else { 2800 if (g_pLogObject) 2801 g_pLogObject->Record("Error: RKU_WriteLBA failed, err=%d", iRet); 2802 2803 printf("Write LBA failed!\r\n"); 2804 goto Exit_WriteLBA; 2805 } 2806 } 2807 bSuccess = true; 2808 } else { 2809 printf("Write LBA quit, creating comm object failed!\r\n"); 2810 } 2811 Exit_WriteLBA: 2812 if (pComm) { 2813 delete pComm; 2814 pComm = NULL; 2815 } 2816 if (file) 2817 fclose(file); 2818 return bSuccess; 2819 } 2820 2821 void split_item(STRING_VECTOR &vecItems, char *pszItems) 2822 { 2823 string strItem; 2824 char szItem[100]; 2825 char *pos = NULL, *pStart; 2826 pStart = pszItems; 2827 pos = strchr(pStart, ','); 2828 while(pos != NULL) { 2829 memset(szItem, 0, 100); 2830 strncpy(szItem, pStart, pos - pStart); 2831 strItem = szItem; 2832 vecItems.push_back(strItem); 2833 pStart = pos + 1; 2834 if (*pStart == 0) 2835 break; 2836 pos = strchr(pStart, ','); 2837 } 2838 if (strlen(pStart) > 0) { 2839 memset(szItem, 0, 100); 2840 strncpy(szItem, pStart, strlen(pStart)); 2841 strItem = szItem; 2842 vecItems.push_back(strItem); 2843 } 2844 } 2845 2846 void tag_spl(char *tag, char *spl) 2847 { 2848 FILE *file = NULL; 2849 int len; 2850 2851 if(!tag || !spl) 2852 return; 2853 len = strlen(tag); 2854 printf("tag len=%d\n",len); 2855 file = fopen(spl, "rb"); 2856 if( !file ){ 2857 return; 2858 } 2859 int iFileSize; 2860 fseek(file, 0, SEEK_END); 2861 iFileSize = ftell(file); 2862 fseek(file, 0, SEEK_SET); 2863 char *Buf = NULL; 2864 Buf = new char[iFileSize + len + 1]; 2865 if (!Buf){ 2866 fclose(file); 2867 return; 2868 } 2869 memset(Buf, 0, iFileSize + 1); 2870 memcpy(Buf, tag, len); 2871 int iRead; 2872 iRead = fread(Buf+len, 1, iFileSize, file); 2873 if (iRead != iFileSize){ 2874 fclose(file); 2875 delete []Buf; 2876 return; 2877 } 2878 fclose(file); 2879 2880 len = strlen(spl); 2881 char *taggedspl = new char[len + 5]; 2882 strcpy(taggedspl, spl); 2883 strcpy(taggedspl + len, ".tag"); 2884 taggedspl[len+4] = 0; 2885 printf("Writing tagged spl to %s\n", taggedspl); 2886 2887 file = fopen(taggedspl, "wb"); 2888 if( !file ){ 2889 delete []taggedspl; 2890 delete []Buf; 2891 return; 2892 } 2893 fwrite(Buf, 1, iFileSize+len, file); 2894 fclose(file); 2895 delete []taggedspl; 2896 delete []Buf; 2897 printf("done\n"); 2898 return; 2899 } 2900 void list_device(CRKScan *pScan) 2901 { 2902 STRUCT_RKDEVICE_DESC desc; 2903 string strDevType; 2904 int i,cnt; 2905 cnt = pScan->DEVICE_COUNTS; 2906 if (cnt == 0) { 2907 printf("not found any devices!\r\n"); 2908 return; 2909 } 2910 for (i=0;i<cnt;i++) 2911 { 2912 pScan->GetDevice(desc, i); 2913 if (desc.emUsbType==RKUSB_MASKROM) 2914 strDevType = "Maskrom"; 2915 else if (desc.emUsbType==RKUSB_LOADER) 2916 strDevType = "Loader"; 2917 else 2918 strDevType = "Unknown"; 2919 printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid, 2920 desc.usPid,desc.uiLocationID,strDevType.c_str()); 2921 } 2922 2923 } 2924 2925 2926 bool handle_command(int argc, char* argv[], CRKScan *pScan) 2927 { 2928 string strCmd; 2929 strCmd = argv[1]; 2930 ssize_t cnt; 2931 bool bRet,bSuccess = false; 2932 char *s; 2933 int i, ret; 2934 STRUCT_RKDEVICE_DESC dev; 2935 u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE]; 2936 u64 lba, lba_end; 2937 u32 part_size, part_offset; 2938 2939 transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); 2940 s = (char*)strCmd.c_str(); 2941 for(i = 0; i < (int)strlen(s); i++) 2942 s[i] = toupper(s[i]); 2943 2944 if((strcmp(strCmd.c_str(), "-H") == 0) || (strcmp(strCmd.c_str(), "--HELP")) == 0){ 2945 usage(); 2946 return true; 2947 } else if((strcmp(strCmd.c_str(), "-V") == 0) || (strcmp(strCmd.c_str(), "--VERSION") == 0)) { 2948 printf("rkdeveloptool ver %s\r\n", PACKAGE_VERSION); 2949 return true; 2950 } else if (strcmp(strCmd.c_str(), "PACK") == 0) {//pack boot loader 2951 mergeBoot(); 2952 2953 return true; 2954 } else if (strcmp(strCmd.c_str(), "UNPACK") == 0) {//unpack boot loader 2955 string strLoader = argv[2]; 2956 2957 unpackBoot((char*)strLoader.c_str()); 2958 return true; 2959 } else if (strcmp(strCmd.c_str(), "TAGSPL") == 0) {//tag u-boot spl 2960 if (argc == 4) { 2961 string tag = argv[2]; 2962 string spl = argv[3]; 2963 printf("tag %s to %s\n", tag.c_str(), spl.c_str()); 2964 tag_spl((char*)tag.c_str(), (char*)spl.c_str()); 2965 return true; 2966 } 2967 printf("tagspl: parameter error\n"); 2968 usage(); 2969 } 2970 cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); 2971 if(strcmp(strCmd.c_str(), "LD") == 0) { 2972 list_device(pScan); 2973 return true; 2974 } 2975 2976 if (cnt < 1) { 2977 ERROR_COLOR_ATTR; 2978 printf("Did not find any rockusb device, please plug device in!"); 2979 NORMAL_COLOR_ATTR; 2980 printf("\r\n"); 2981 return bSuccess; 2982 } else if (cnt > 1) { 2983 ERROR_COLOR_ATTR; 2984 printf("Found too many rockusb devices, please plug devices out!"); 2985 NORMAL_COLOR_ATTR; 2986 printf("\r\n"); 2987 return bSuccess; 2988 } 2989 2990 bRet = pScan->GetDevice(dev, 0); 2991 if (!bRet) { 2992 ERROR_COLOR_ATTR; 2993 printf("Getting information about rockusb device failed!"); 2994 NORMAL_COLOR_ATTR; 2995 printf("\r\n"); 2996 return bSuccess; 2997 } 2998 2999 if(strcmp(strCmd.c_str(), "RD") == 0) { 3000 if ((argc != 2) && (argc != 3)) 3001 printf("Parameter of [RD] command is invalid, please check help!\r\n"); 3002 else { 3003 if (argc == 2) 3004 bSuccess = reset_device(dev); 3005 else { 3006 UINT uiSubCode; 3007 char *pszEnd; 3008 uiSubCode = strtoul(argv[2], &pszEnd, 0); 3009 if (*pszEnd) 3010 printf("Subcode is invalid, please check!\r\n"); 3011 else { 3012 if (uiSubCode <= 5) 3013 bSuccess = reset_device(dev, uiSubCode); 3014 else 3015 printf("Subcode is invalid, please check!\r\n"); 3016 } 3017 } 3018 } 3019 } else if(strcmp(strCmd.c_str(), "TD") == 0) { 3020 bSuccess = test_device(dev); 3021 } else if (strcmp(strCmd.c_str(), "RID") == 0) {//Read Flash ID 3022 bSuccess = read_flash_id(dev); 3023 } else if (strcmp(strCmd.c_str(), "RFI") == 0){//Read Flash Info 3024 bSuccess = read_flash_info(dev); 3025 } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info 3026 bSuccess = read_chip_info(dev); 3027 } else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability 3028 bSuccess = read_capability(dev); 3029 } else if(strcmp(strCmd.c_str(), "DB") == 0) { 3030 if (argc > 2) { 3031 string strLoader; 3032 strLoader = argv[2]; 3033 bSuccess = download_boot(dev, (char *)strLoader.c_str()); 3034 } else if (argc == 2) { 3035 ret = find_config_item(g_ConfigItemVec, "loader"); 3036 if (ret == -1) 3037 printf("Did not find loader item in config!\r\n"); 3038 else 3039 bSuccess = download_boot(dev, g_ConfigItemVec[ret].szItemValue); 3040 } else 3041 printf("Parameter of [DB] command is invalid, please check help!\r\n"); 3042 } else if(strcmp(strCmd.c_str(), "GPT") == 0) { 3043 if (argc > 2) { 3044 string strParameter; 3045 strParameter = argv[2]; 3046 bSuccess = write_gpt(dev, (char *)strParameter.c_str()); 3047 } else 3048 printf("Parameter of [GPT] command is invalid, please check help!\r\n"); 3049 } else if(strcmp(strCmd.c_str(), "PRM") == 0) { 3050 if (argc > 2) { 3051 string strParameter; 3052 strParameter = argv[2]; 3053 bSuccess = write_parameter(dev, (char *)strParameter.c_str()); 3054 } else 3055 printf("Parameter of [PRM] command is invalid, please check help!\r\n"); 3056 } else if(strcmp(strCmd.c_str(), "UL") == 0) { 3057 if (argc > 2) { 3058 string strLoader; 3059 strLoader = argv[2]; 3060 bSuccess = upgrade_loader(dev, (char *)strLoader.c_str()); 3061 } else 3062 printf("Parameter of [UL] command is invalid, please check help!\r\n"); 3063 } else if(strcmp(strCmd.c_str(), "EF") == 0) { 3064 if (argc == 2) { 3065 bSuccess = erase_flash(dev); 3066 } else 3067 printf("Parameter of [EF] command is invalid, please check help!\r\n"); 3068 } else if(strcmp(strCmd.c_str(), "WL") == 0) { 3069 if (argc == 4) { 3070 UINT uiBegin; 3071 char *pszEnd; 3072 uiBegin = strtoul(argv[2], &pszEnd, 0); 3073 if (*pszEnd) 3074 printf("Begin is invalid, please check!\r\n"); 3075 else { 3076 if (is_sparse_image(argv[3])) 3077 bSuccess = write_sparse_lba(dev, (u32)uiBegin, (u32)-1, argv[3]); 3078 else 3079 bSuccess = write_lba(dev, (u32)uiBegin, argv[3]); 3080 } 3081 } else 3082 printf("Parameter of [WL] command is invalid, please check help!\r\n"); 3083 } else if(strcmp(strCmd.c_str(), "WLX") == 0) { 3084 if (argc == 4) { 3085 bRet = read_gpt(dev, master_gpt); 3086 if (bRet) { 3087 bRet = get_lba_from_gpt(master_gpt, argv[2], &lba, &lba_end); 3088 if (bRet) { 3089 if (is_sparse_image(argv[3])) 3090 bSuccess = write_sparse_lba(dev, (u32)lba, (u32)(lba_end - lba + 1), argv[3]); 3091 else 3092 bSuccess = write_lba(dev, (u32)lba, argv[3]); 3093 } else 3094 printf("No found %s partition\r\n", argv[2]); 3095 } else { 3096 bRet = read_param(dev, param_buffer); 3097 if (bRet) { 3098 bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size); 3099 if (bRet) { 3100 if (is_sparse_image(argv[3])) 3101 bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]); 3102 else 3103 bSuccess = write_lba(dev, part_offset, argv[3]); 3104 } else 3105 printf("No found %s partition\r\n", argv[2]); 3106 } 3107 else 3108 printf("Not found any partition table!\r\n"); 3109 } 3110 3111 } else 3112 printf("Parameter of [WLX] command is invalid, please check help!\r\n"); 3113 } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA 3114 char *pszEnd; 3115 UINT uiBegin, uiLen; 3116 if (argc != 5) 3117 printf("Parameter of [RL] command is invalid, please check help!\r\n"); 3118 else { 3119 uiBegin = strtoul(argv[2], &pszEnd, 0); 3120 if (*pszEnd) 3121 printf("Begin is invalid, please check!\r\n"); 3122 else { 3123 uiLen = strtoul(argv[3], &pszEnd, 0); 3124 if (*pszEnd) 3125 printf("Len is invalid, please check!\r\n"); 3126 else { 3127 bSuccess = read_lba(dev, uiBegin, uiLen, argv[4]); 3128 } 3129 } 3130 } 3131 } else if(strcmp(strCmd.c_str(), "PPT") == 0) { 3132 if (argc == 2) { 3133 bSuccess = print_gpt(dev); 3134 if (!bSuccess) { 3135 bSuccess = print_parameter(dev); 3136 if (!bSuccess) 3137 printf("Not found any partition table!\r\n"); 3138 } 3139 } else 3140 printf("Parameter of [PPT] command is invalid, please check help!\r\n"); 3141 } else { 3142 printf("command is invalid!\r\n"); 3143 usage(); 3144 } 3145 return bSuccess; 3146 } 3147 3148 3149 int main(int argc, char* argv[]) 3150 { 3151 CRKScan *pScan = NULL; 3152 int ret; 3153 char szProgramProcPath[100]; 3154 char szProgramDir[256]; 3155 string strLogDir,strConfigFile; 3156 struct stat statBuf; 3157 3158 g_ConfigItemVec.clear(); 3159 sprintf(szProgramProcPath, "/proc/%d/exe", getpid()); 3160 if (readlink(szProgramProcPath, szProgramDir, 256) == -1) 3161 strcpy(szProgramDir, "."); 3162 else { 3163 char *pSlash; 3164 pSlash = strrchr(szProgramDir, '/'); 3165 if (pSlash) 3166 *pSlash = '\0'; 3167 } 3168 strLogDir = szProgramDir; 3169 strLogDir += "/log/"; 3170 strConfigFile = szProgramDir; 3171 strConfigFile += "/config.ini"; 3172 if (opendir(strLogDir.c_str()) == NULL) 3173 mkdir(strLogDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH); 3174 g_pLogObject = new CRKLog(strLogDir.c_str(), "log",true); 3175 3176 if(stat(strConfigFile.c_str(), &statBuf) < 0) { 3177 if (g_pLogObject) { 3178 g_pLogObject->Record("Error: failed to stat config.ini, err=%d", errno); 3179 } 3180 } else if (S_ISREG(statBuf.st_mode)) { 3181 parse_config_file(strConfigFile.c_str(), g_ConfigItemVec); 3182 } 3183 3184 ret = libusb_init(NULL); 3185 if (ret < 0) { 3186 if (g_pLogObject) { 3187 g_pLogObject->Record("Error: libusb_init failed, err=%d", ret); 3188 delete g_pLogObject; 3189 } 3190 return -1; 3191 } 3192 3193 pScan = new CRKScan(); 3194 if (!pScan) { 3195 if (g_pLogObject) { 3196 g_pLogObject->Record("Error: failed to create object for searching device"); 3197 delete g_pLogObject; 3198 } 3199 libusb_exit(NULL); 3200 return -2; 3201 } 3202 pScan->SetVidPid(); 3203 3204 if (argc == 1) 3205 usage(); 3206 else if (!handle_command(argc, argv, pScan)) 3207 return -0xFF; 3208 if (pScan) 3209 delete pScan; 3210 if (g_pLogObject) 3211 delete g_pLogObject; 3212 libusb_exit(NULL); 3213 return 0; 3214 } 3215