1530 lines
35 KiB
C++
Executable File
1530 lines
35 KiB
C++
Executable File
/*
|
||
* Copyright 2019 Rockchip Electronics Co., Ltd
|
||
* Dayao Ji <jdy@rock-chips.com>
|
||
*
|
||
* SPDX-License-Identifier: GPL-2.0+
|
||
*/
|
||
|
||
//#include "RKImage.h"
|
||
//#include "RKLog.h"
|
||
//#include "RKComm.h"
|
||
#include "rkupdate/RKAndroidDevice.h"
|
||
//#include "rkrsa_api.h"
|
||
//#include "uuid/uuid.h"
|
||
#include "rkupdate/RKSparse.h"
|
||
UpgradeCallbackFunc g_callback=NULL;
|
||
UpgradeProgressCallbackFunc g_progress_callback=NULL;
|
||
|
||
bool CreateUid(PBYTE pUid)
|
||
{
|
||
if (!pUid)
|
||
{
|
||
return false;
|
||
}
|
||
memset(pUid,0,RKDEVICE_UID_LEN);
|
||
|
||
PBYTE pManufactory,pTime,pGuid,pCrc;
|
||
pManufactory = pUid;
|
||
pTime = pManufactory + 8;
|
||
pGuid = pTime + 4;
|
||
pCrc = pGuid + 16;
|
||
memcpy(pManufactory,"ROCKCHIP",8);
|
||
time_t now;
|
||
now = time(NULL);
|
||
memcpy(pTime,(BYTE *)&now,4);
|
||
#if 0
|
||
uuid_t guidValue;
|
||
uuid_generate(guidValue);
|
||
#else
|
||
unsigned char raw[16]={0};
|
||
gen_rand_uuid(raw);
|
||
#endif
|
||
|
||
#if 0
|
||
memcpy(pGuid,(BYTE *)guidValue,16);
|
||
#else
|
||
memcpy(pGuid,(BYTE *)raw,16);
|
||
#endif
|
||
|
||
USHORT usCrc=0;
|
||
usCrc = CRC_CCITT(pManufactory,28);
|
||
memcpy(pCrc,(BYTE *)&usCrc,2);
|
||
return true;
|
||
|
||
}
|
||
|
||
bool ParsePartitionInfo(string &strPartInfo,string &strName,UINT &uiOffset,UINT &uiLen)
|
||
{
|
||
string::size_type pos,prevPos;
|
||
string strOffset,strLen;
|
||
int iCount;
|
||
prevPos = pos = 0;
|
||
if (strPartInfo.size()<=0)
|
||
{
|
||
return false;
|
||
}
|
||
pos = strPartInfo.find('@');
|
||
if (pos==string::npos)
|
||
{
|
||
return false;
|
||
}
|
||
strLen = strPartInfo.substr(prevPos,pos-prevPos);
|
||
strLen.erase(0,strLen.find_first_not_of(_T(" ")));
|
||
strLen.erase(strLen.find_last_not_of(_T(" "))+1);
|
||
if (strchr(strLen.c_str(),'-'))
|
||
{
|
||
uiLen = 0xFFFFFFFF;
|
||
}
|
||
else
|
||
{
|
||
iCount = sscanf(strLen.c_str(),"0x%x",&uiLen);
|
||
if (iCount!=1)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
prevPos = pos +1;
|
||
pos = strPartInfo.find('(',prevPos);
|
||
if (pos==string::npos)
|
||
{
|
||
return false;
|
||
}
|
||
strOffset = strPartInfo.substr(prevPos,pos-prevPos);
|
||
strOffset.erase(0,strOffset.find_first_not_of(_T(" ")));
|
||
strOffset.erase(strOffset.find_last_not_of(_T(" "))+1);
|
||
iCount = sscanf(strOffset.c_str(),"0x%x",&uiOffset);
|
||
if (iCount!=1)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
prevPos = pos +1;
|
||
pos = strPartInfo.find(')',prevPos);
|
||
if (pos==string::npos)
|
||
{
|
||
return false;
|
||
}
|
||
strName = strPartInfo.substr(prevPos,pos-prevPos);
|
||
strName.erase(0,strName.find_first_not_of(_T(" ")));
|
||
strName.erase(strName.find_last_not_of(_T(" "))+1);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool parse_parameter(char *pParameter,PARAM_ITEM_VECTOR &vecItem)
|
||
{
|
||
|
||
stringstream paramStream(pParameter);
|
||
bool bRet,bFind=false;
|
||
string strLine,strPartition,strPartInfo,strPartName;
|
||
string::size_type line_size,pos,posColon,posComma;
|
||
UINT uiPartOffset,uiPartSize;
|
||
STRUCT_PARAM_ITEM item;
|
||
vecItem.clear();
|
||
int i=0;
|
||
while (!paramStream.eof())
|
||
{
|
||
i++;
|
||
getline(paramStream,strLine);
|
||
line_size = strLine.size();
|
||
if (line_size==0)
|
||
{
|
||
continue;
|
||
}
|
||
if(strLine[0]=='#')
|
||
{
|
||
continue;
|
||
}
|
||
if (strLine[line_size-1]=='\r')
|
||
{
|
||
strLine = strLine.substr(0,line_size-1);
|
||
}
|
||
pos = strLine.find("mtdparts");
|
||
if (pos==string::npos)
|
||
{
|
||
continue;
|
||
}
|
||
bFind = true;
|
||
posColon = strLine.find(':',pos);
|
||
if (posColon==string::npos)
|
||
{
|
||
continue;
|
||
}
|
||
strPartition = strLine.substr(posColon+1);
|
||
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||
pos = 0;
|
||
posComma = strPartition.find(',',pos);
|
||
while (posComma!=string::npos)
|
||
{
|
||
strPartInfo = strPartition.substr(pos,posComma-pos);
|
||
bRet = ParsePartitionInfo(strPartInfo,strPartName,uiPartOffset,uiPartSize);
|
||
if (bRet)
|
||
{
|
||
strcpy(item.szItemName,strPartName.c_str());
|
||
item.uiItemOffset = uiPartOffset;
|
||
item.uiItemSize = uiPartSize;
|
||
vecItem.push_back(item);
|
||
}
|
||
pos = posComma+1;
|
||
posComma = strPartition.find(',',pos);
|
||
}
|
||
strPartInfo = strPartition.substr(pos);
|
||
if (strPartInfo.size()>0)
|
||
{
|
||
bRet = ParsePartitionInfo(strPartInfo,strPartName,uiPartOffset,uiPartSize);
|
||
if (bRet)
|
||
{
|
||
strcpy(item.szItemName,strPartName.c_str());
|
||
item.uiItemOffset = uiPartOffset;
|
||
item.uiItemSize = uiPartSize;
|
||
vecItem.push_back(item);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
return bFind;
|
||
|
||
}
|
||
|
||
bool parse_Gptparameter(string str,PARAM_ITEM_VECTOR &vecItem)
|
||
{
|
||
bool bRet,bFind=false;
|
||
string strLine,strPartition,strPartInfo,strPartName;
|
||
string::size_type line_size,pos,posColon,posComma;
|
||
UINT uiPartOffset,uiPartSize;
|
||
ifstream fin(str);
|
||
STRUCT_PARAM_ITEM item;
|
||
vecItem.clear();
|
||
int i=0;
|
||
while (getline(fin,strLine))
|
||
{
|
||
i++;
|
||
printf("str = %s",strLine.c_str());
|
||
line_size = strLine.size();
|
||
if (line_size==0)
|
||
{
|
||
continue;
|
||
}
|
||
if(strLine[0]=='#')
|
||
{
|
||
continue;
|
||
}
|
||
if (strLine[line_size-1]=='\r')
|
||
{
|
||
strLine = strLine.substr(0,line_size-1);
|
||
}
|
||
pos = strLine.find("mtdparts");
|
||
if (pos==string::npos)
|
||
{
|
||
continue;
|
||
}
|
||
bFind = true;
|
||
posColon = strLine.find(':',pos);
|
||
if (posColon==string::npos)
|
||
{
|
||
continue;
|
||
}
|
||
strPartition = strLine.substr(posColon+1);
|
||
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||
pos = 0;
|
||
posComma = strPartition.find(',',pos);
|
||
while (posComma!=string::npos)
|
||
{
|
||
strPartInfo = strPartition.substr(pos,posComma-pos);
|
||
bRet = ParsePartitionInfo(strPartInfo,strPartName,uiPartOffset,uiPartSize);
|
||
if (bRet)
|
||
{
|
||
strcpy(item.szItemName,strPartName.c_str());
|
||
item.uiItemOffset = uiPartOffset;
|
||
item.uiItemSize = uiPartSize;
|
||
vecItem.push_back(item);
|
||
}
|
||
pos = posComma+1;
|
||
posComma = strPartition.find(',',pos);
|
||
}
|
||
strPartInfo = strPartition.substr(pos);
|
||
if (strPartInfo.size()>0)
|
||
{
|
||
bRet = ParsePartitionInfo(strPartInfo,strPartName,uiPartOffset,uiPartSize);
|
||
if (bRet)
|
||
{
|
||
strcpy(item.szItemName,strPartName.c_str());
|
||
item.uiItemOffset = uiPartOffset;
|
||
item.uiItemSize = uiPartSize;
|
||
vecItem.push_back(item);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
return bFind;
|
||
}
|
||
|
||
bool get_parameter_loader( CRKComm *pComm,char *pParameter, int &nParamSize)
|
||
{
|
||
if ((nParamSize!=-1)&&(!pParameter))
|
||
{
|
||
return false;
|
||
}
|
||
BYTE paramHead[512];
|
||
DWORD *pParamTag=(DWORD *)paramHead;
|
||
DWORD *pParamSize=(DWORD *)(paramHead+4);
|
||
int iRet;
|
||
|
||
iRet = pComm->RKU_ReadLBA(0,1,paramHead);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
return false;
|
||
}
|
||
if (*pParamTag!=0x4D524150)
|
||
{
|
||
return false;
|
||
}
|
||
if (nParamSize==-1)
|
||
{//<2F><>ȡparameter<65><72>С
|
||
nParamSize = *pParamSize;
|
||
return true;
|
||
}
|
||
if (nParamSize<*pParamSize)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
nParamSize = *pParamSize;
|
||
int nParamSec;
|
||
nParamSec = (nParamSize+12-1)/512+1;
|
||
PBYTE pBuffer=NULL;
|
||
pBuffer = new BYTE[nParamSec*512];
|
||
if (!pBuffer)
|
||
{
|
||
|
||
return false;
|
||
}
|
||
iRet = pComm->RKU_ReadLBA(0,nParamSec,pBuffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
|
||
memcpy(pParameter,pBuffer+8,nParamSize);
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return true;
|
||
}
|
||
bool read_bytes_from_partition(DWORD dwPartitionOffset,long long ullstart,DWORD dwCount,PBYTE pOut,CRKComm *pComm)
|
||
{
|
||
int iRet;
|
||
UINT uiTransferSize = 16*1024;
|
||
UINT uiTransferSec = uiTransferSize/SECTOR_SIZE;
|
||
BYTE *pBuffer = NULL;
|
||
UINT uiBegin=dwPartitionOffset,uiLen,uiReadBytes=0,uiTmp;
|
||
DWORD dwWritePos=0;
|
||
pBuffer = new BYTE[uiTransferSize];
|
||
if (!pBuffer)
|
||
return false;
|
||
uiTmp = ullstart % 2048;
|
||
if (uiTmp==0)
|
||
{
|
||
uiBegin += ullstart / SECTOR_SIZE;
|
||
}
|
||
else
|
||
{
|
||
uiReadBytes = 2048 - uiTmp;
|
||
uiBegin += ((ullstart/2048)*4);
|
||
uiLen = 4;
|
||
iRet = pComm->RKU_ReadLBA(uiBegin,uiLen,pBuffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
delete []pBuffer;
|
||
return false;
|
||
}
|
||
if (dwCount>=uiReadBytes)
|
||
{
|
||
memcpy(pOut+dwWritePos,pBuffer+uiTmp,uiReadBytes);
|
||
dwWritePos += uiReadBytes;
|
||
dwCount -= uiReadBytes;
|
||
}
|
||
else
|
||
{
|
||
memcpy(pOut+dwWritePos,pBuffer+uiTmp,dwCount);
|
||
dwWritePos += dwCount;
|
||
dwCount = 0;
|
||
}
|
||
uiBegin += uiLen;
|
||
}
|
||
while (dwCount>0)
|
||
{
|
||
if (dwCount>=uiTransferSize)
|
||
{
|
||
uiReadBytes = uiTransferSize;
|
||
uiLen = uiTransferSec;
|
||
}
|
||
else
|
||
{
|
||
uiReadBytes = dwCount;
|
||
uiLen = BYTE2SECTOR(uiReadBytes);
|
||
}
|
||
iRet = pComm->RKU_ReadLBA(uiBegin,uiLen,pBuffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
delete []pBuffer;
|
||
return false;
|
||
}
|
||
memcpy(pOut+dwWritePos,pBuffer,uiReadBytes);
|
||
dwWritePos += uiReadBytes;
|
||
dwCount -= uiReadBytes;
|
||
uiBegin += uiLen;
|
||
}
|
||
delete []pBuffer;
|
||
return true;
|
||
}
|
||
|
||
bool check_fw_header(CRKComm *pComm,DWORD dwOffset,PSTRUCT_RKIMAGE_HDR pHeader,CRKLog *pLog=NULL)
|
||
{
|
||
int nHeaderSec = BYTE2SECTOR(sizeof(STRUCT_RKIMAGE_HDR));
|
||
char model[256]={0};
|
||
PBYTE pBuf=NULL;
|
||
pBuf = new BYTE[nHeaderSec*SECTOR_SIZE];
|
||
if (!pBuf)
|
||
return false;
|
||
int iRet;
|
||
iRet = pComm->RKU_ReadLBA(dwOffset,nHeaderSec,pBuf);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
delete []pBuf;
|
||
pBuf = NULL;
|
||
return false;
|
||
}
|
||
memcpy(pHeader,pBuf,sizeof(STRUCT_RKIMAGE_HDR));
|
||
delete []pBuf;
|
||
pBuf = NULL;
|
||
if (pHeader->tag!=RKIMAGE_TAG)
|
||
return false;
|
||
|
||
property_get("ro.product.model", model, "");
|
||
if (pLog)
|
||
pLog->Record(_T("model:%s\nbackup firmware model:%s\n"),model,pHeader->machine_model);
|
||
if(strcmp(model, pHeader->machine_model))
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
bool check_fw_crc(CRKComm *pComm,DWORD dwOffset,PSTRUCT_RKIMAGE_HDR pHeader,CRKLog *pLog=NULL)
|
||
{
|
||
int iRet;
|
||
long long ullRemain,ullCrcOffset;
|
||
if (pHeader->machine_model[29]=='H')
|
||
{
|
||
ullRemain = *((DWORD *)(&pHeader->machine_model[30]));
|
||
ullRemain <<= 32;
|
||
ullRemain += pHeader->size;
|
||
}
|
||
else
|
||
ullRemain = pHeader->size;
|
||
if (ullRemain<=0)
|
||
return false;
|
||
ullCrcOffset = ullRemain;
|
||
UINT uiTransferSize = 16*1024;
|
||
UINT uiTransferSec = uiTransferSize/SECTOR_SIZE;
|
||
BYTE *pBuffer = NULL;
|
||
BYTE oldCrc[4];
|
||
UINT uiBegin=dwOffset,uiLen,uiCrc=0,uiReadBytes=0;
|
||
pBuffer = new BYTE[uiTransferSize];
|
||
if (!pBuffer)
|
||
return false;
|
||
while(ullRemain>0)
|
||
{
|
||
if (ullRemain>=uiTransferSize)
|
||
{
|
||
uiReadBytes = uiTransferSize;
|
||
uiLen = uiTransferSec;
|
||
}
|
||
else
|
||
{
|
||
uiReadBytes = ullRemain;
|
||
uiLen = BYTE2SECTOR(uiReadBytes);
|
||
}
|
||
iRet = pComm->RKU_ReadLBA(uiBegin,uiLen,pBuffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
delete []pBuffer;
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:check_fw_crc-->RKU_ReadLBA failed,err=%d"),iRet);
|
||
return false;
|
||
}
|
||
uiCrc = CRC_32(pBuffer,uiReadBytes,uiCrc);
|
||
uiBegin += uiLen;
|
||
ullRemain -= uiReadBytes;
|
||
}
|
||
delete []pBuffer;
|
||
if (!read_bytes_from_partition(dwOffset,ullCrcOffset,4,oldCrc,pComm))
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:check_fw_crc-->read old crc failed"));
|
||
return false;
|
||
}
|
||
if (uiCrc!=*((UINT *)(oldCrc)))
|
||
return false;
|
||
return true;
|
||
|
||
}
|
||
|
||
bool download_backup_image(PARAM_ITEM_VECTOR &vecParam,char *pszItemName,DWORD dwBackupOffset,STRUCT_RKIMAGE_HDR &hdr,CRKComm *pComm,CRKLog *pLog=NULL)
|
||
{
|
||
DWORD dwToOffset,dwToSize;
|
||
int i,iRet;
|
||
if (g_progress_callback)
|
||
g_progress_callback(0.5,50);
|
||
for (i=0;i<vecParam.size();i++)
|
||
{
|
||
if (strcmp(pszItemName,vecParam[i].szItemName)==0)
|
||
{
|
||
dwToOffset = vecParam[i].uiItemOffset;
|
||
dwToSize = vecParam[i].uiItemSize;
|
||
break;
|
||
}
|
||
}
|
||
if (i>=vecParam.size())
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:download_backup_image-->no found dest partition."));
|
||
return false;
|
||
}
|
||
long long ullSrcPos,ullSrcSize;
|
||
for (i=0;i<hdr.item_count;i++)
|
||
{
|
||
if (strcmp(pszItemName,hdr.item[i].name)==0)
|
||
{
|
||
if (hdr.item[i].file[50]=='H')
|
||
{
|
||
ullSrcPos= *((DWORD *)(&hdr.item[i].file[51]));
|
||
ullSrcPos <<= 32;
|
||
ullSrcPos += hdr.item[i].offset;
|
||
}
|
||
else
|
||
{
|
||
ullSrcPos = hdr.item[i].offset;
|
||
}
|
||
if (hdr.item[i].file[55]=='H')
|
||
{
|
||
ullSrcSize= *((DWORD *)(&hdr.item[i].file[56]));
|
||
ullSrcSize <<= 32;
|
||
ullSrcSize += hdr.item[i].size;
|
||
}
|
||
else
|
||
{
|
||
ullSrcSize = hdr.item[i].size;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if (i>=hdr.item_count)
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:download_backup_image-->no found source in the backup."));
|
||
return false;
|
||
}
|
||
long long ullRemain,ullstart,ullToStart;
|
||
UINT uiBegin,uiLen,uiTransferByte;
|
||
UINT uiBufferSize=16*1024;
|
||
BYTE buffer[16*1024];
|
||
BYTE readbuffer[16*1024];
|
||
|
||
//write image
|
||
ullRemain = ullSrcSize;
|
||
uiBegin = dwToOffset;
|
||
ullstart = ullSrcPos;
|
||
while(ullRemain>0)
|
||
{
|
||
if (ullRemain>=uiBufferSize)
|
||
{
|
||
uiTransferByte = uiBufferSize;
|
||
uiLen = 32;
|
||
}
|
||
else
|
||
{
|
||
uiTransferByte = ullRemain;
|
||
uiLen = BYTE2SECTOR(uiTransferByte);
|
||
}
|
||
if (!read_bytes_from_partition(dwBackupOffset,ullstart,uiTransferByte,buffer,pComm))
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:download_backup_image-->read data from backup failed."));
|
||
return false;
|
||
}
|
||
iRet = pComm->RKU_WriteLBA(uiBegin,uiLen,buffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:download_backup_image-->write data to partition failed."));
|
||
return false;
|
||
}
|
||
ullRemain -= uiTransferByte;
|
||
uiBegin += uiLen;
|
||
ullstart += uiTransferByte;
|
||
|
||
}
|
||
pComm->RKU_ReopenLBAHandle();
|
||
if (g_progress_callback)
|
||
g_progress_callback(1,0);
|
||
if (g_progress_callback)
|
||
g_progress_callback(0.4,30);
|
||
//check image
|
||
if (pLog)
|
||
pLog->Record(_T("Start to check system..."));
|
||
ullRemain = ullSrcSize;
|
||
ullToStart = 0;
|
||
ullstart = ullSrcPos;
|
||
while(ullRemain>0)
|
||
{
|
||
if (ullRemain>=uiBufferSize)
|
||
{
|
||
uiTransferByte = uiBufferSize;
|
||
}
|
||
else
|
||
{
|
||
uiTransferByte = ullRemain;
|
||
}
|
||
if (!read_bytes_from_partition(dwBackupOffset,ullstart,uiTransferByte,buffer,pComm))
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:download_backup_image-->read data from backup failed."));
|
||
return false;
|
||
}
|
||
if (!read_bytes_from_partition(dwToOffset,ullToStart,uiTransferByte,readbuffer,pComm))
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:download_backup_image-->read data from partition failed."));
|
||
return false;
|
||
}
|
||
if (memcmp(buffer,readbuffer,uiTransferByte)!=0)
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:download_backup_image-->compare data failed."));
|
||
return false;
|
||
}
|
||
|
||
ullRemain -= uiTransferByte;
|
||
ullToStart += uiTransferByte;
|
||
ullstart += uiTransferByte;
|
||
|
||
}
|
||
if (g_progress_callback)
|
||
g_progress_callback(1,0);
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
bool IsDeviceLock(CRKComm *pComm,bool &bLock)
|
||
{
|
||
bLock = false;(void)pComm;
|
||
return true;
|
||
#if 0
|
||
int iRet;
|
||
BYTE buffer[4];
|
||
iRet = pComm->RKU_GetLockFlag(buffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
return false;
|
||
DWORD *pFlag=(DWORD *)buffer;
|
||
if (*pFlag==1)
|
||
bLock = true;
|
||
else
|
||
bLock = false;
|
||
return true;
|
||
#endif
|
||
}
|
||
bool GetPubicKeyFromExternal(char *szDev,CRKLog *pLog,unsigned char *pKey,unsigned int &nKeySize)
|
||
{
|
||
int hDev=-1;
|
||
int j,ret,nRsaByte;
|
||
bool bSuccess=false;
|
||
BYTE bData[SECTOR_SIZE*8];
|
||
PRKANDROID_IDB_SEC0 pSec0=(PRKANDROID_IDB_SEC0)bData;
|
||
PRK_SECURE_HEADER pSecureHdr=(PRK_SECURE_HEADER)(bData+SECTOR_SIZE*4);
|
||
string strOutput;
|
||
if (!szDev)
|
||
{
|
||
printf("In GetPubicKeyFromExternal device=NULL\n");
|
||
return false;
|
||
}
|
||
else
|
||
printf("In GetPubicKeyFromExternal device=%s\n",szDev);
|
||
hDev= open(szDev,O_RDONLY,0);
|
||
if (hDev<0)
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->open %s failed,err=%d"),szDev,errno);
|
||
goto Exit_GetPubicKeyFromExternal;
|
||
}
|
||
else
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("INFO:GetPubicKeyFromExternal-->%s=%d"),szDev,hDev);
|
||
}
|
||
|
||
ret = lseek(hDev,64*512,SEEK_SET);
|
||
if (ret<0)
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->seek IDBlock failed,err=%d"),errno);
|
||
goto Exit_GetPubicKeyFromExternal;
|
||
}
|
||
ret = read(hDev,bData,8*512);
|
||
if (ret!=8*512)
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->read IDBlock failed,err=%d"),errno);
|
||
goto Exit_GetPubicKeyFromExternal;
|
||
}
|
||
// if (pLog)
|
||
// {
|
||
// pLog->PrintBuffer(strOutput,bData,512,16);
|
||
// pLog->Record("INFO:idb\n%s",strOutput.c_str());
|
||
// }
|
||
P_RC4(bData,SECTOR_SIZE);
|
||
// if (pLog)
|
||
// {
|
||
// pLog->PrintBuffer(strOutput,bData,512,16);
|
||
// pLog->Record("INFO:idb rc4\n%s",strOutput.c_str());
|
||
// }
|
||
if (pSec0->dwTag!=0x0FF0AA55)
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->check IDBlock failed,tag=0x%x"),pSec0->dwTag);
|
||
goto Exit_GetPubicKeyFromExternal;
|
||
}
|
||
if (pSec0->uiRc4Flag==0)
|
||
{
|
||
for(j=0;j<4;j++)
|
||
P_RC4(bData+SECTOR_SIZE*(j+4),SECTOR_SIZE);
|
||
}
|
||
if (pSecureHdr->uiTag!=0x4B415352)
|
||
{
|
||
if (pLog)
|
||
pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->check SecureHeader failed,tag=0x%x"),pSecureHdr->uiTag);
|
||
goto Exit_GetPubicKeyFromExternal;
|
||
}
|
||
nRsaByte = pSecureHdr->usRsaBit/8;
|
||
*((USHORT *)pKey) = pSecureHdr->usRsaBit;
|
||
for(j=0;j<nRsaByte;j++)
|
||
*(pKey+j+2) = pSecureHdr->nFactor[nRsaByte-j-1];
|
||
for(j=0;j<nRsaByte;j++)
|
||
*(pKey+j+2+nRsaByte) = pSecureHdr->eFactor[nRsaByte-j-1];
|
||
nKeySize = nRsaByte*2+2;
|
||
// if (pLog)
|
||
// {
|
||
// pLog->PrintBuffer(strOutput,pKey,nKeySize,16);
|
||
// pLog->Record("INFO:Key\n%s",strOutput.c_str());
|
||
// }
|
||
bSuccess = true;
|
||
Exit_GetPubicKeyFromExternal:
|
||
if (hDev!=-1)
|
||
close(hDev);
|
||
return bSuccess;
|
||
}
|
||
|
||
bool GetPubicKeyFromDevice(CRKLog *pLog,unsigned char *pKey,unsigned int &nKeySize)
|
||
{
|
||
bool bSuccess=false,bRet;
|
||
CRKComm *pComm=NULL;
|
||
CRKAndroidDevice *pDevice=NULL;
|
||
STRUCT_RKDEVICE_DESC device;
|
||
pComm = new CRKUsbComm(pLog);
|
||
if (!pComm)
|
||
{
|
||
pLog->Record("ERROR:GetPubicKeyFromDevice-->new CRKComm failed!");
|
||
goto EXIT_GetPubicKeyFromDevice;
|
||
}
|
||
pDevice = new CRKAndroidDevice(device);
|
||
if (!pDevice)
|
||
{
|
||
pLog->Record("ERROR:GetPubicKeyFromDevice-->new CRKAndroidDevice failed!");
|
||
goto EXIT_GetPubicKeyFromDevice;
|
||
}
|
||
pDevice->SetObject(NULL,pComm,pLog);
|
||
pDevice->m_pCallback = (UpgradeCallbackFunc)NULL;
|
||
pDevice->m_pProcessCallback = (UpgradeProgressCallbackFunc)NULL;
|
||
bRet = pDevice->GetPublicKey(pKey,nKeySize);
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("ERROR:GetPubicKeyFromDevice-->GetPublicKey failed!");
|
||
goto EXIT_GetPubicKeyFromDevice;
|
||
}
|
||
bSuccess = true;
|
||
EXIT_GetPubicKeyFromDevice:
|
||
if (pDevice)
|
||
{
|
||
delete pDevice;
|
||
pDevice = NULL;
|
||
}
|
||
else if (pComm)
|
||
{
|
||
delete pComm;
|
||
pComm = NULL;
|
||
}
|
||
return bSuccess;
|
||
}
|
||
bool UnlockDevice(CRKImage *pImage,CRKLog *pLog,unsigned char *pKey,unsigned int nKeySize)
|
||
{
|
||
PBYTE pMd5,pSignMd5;
|
||
int nSignSize;
|
||
unsigned int nOutput = 0;
|
||
//bool bRet;
|
||
BYTE output[256];
|
||
string strOutput;
|
||
(void)nKeySize;
|
||
printf("in UnlockDevice\n");
|
||
if ((!pImage)||(!pKey))
|
||
return false;
|
||
nSignSize = pImage->GetMd5Data(pMd5,pSignMd5);
|
||
if (nSignSize==0)
|
||
{
|
||
if (pLog)
|
||
pLog->Record("Get signed info failed.");
|
||
return false;
|
||
}
|
||
//bRet= DoRsa(output,&nOutput,pSignMd5,nSignSize,pKey,nKeySize);
|
||
//if (!bRet)
|
||
//{
|
||
// if (pLog)
|
||
// pLog->Record("DoRsa failed.");
|
||
// return false;
|
||
//}
|
||
if(pLog)
|
||
{
|
||
pLog->PrintBuffer(strOutput,pMd5,32,16);
|
||
pLog->Record("INFO:Old Md5\n%s",strOutput.c_str());
|
||
pLog->PrintBuffer(strOutput,output+nOutput-32,32,16);
|
||
pLog->Record("INFO:New Md5\n%s",strOutput.c_str());
|
||
}
|
||
return true;
|
||
if (memcmp(pMd5,output+nOutput-32,32)==0)
|
||
return true;
|
||
else
|
||
return false;
|
||
}
|
||
|
||
bool do_rk_firmware_upgrade(char *szFw,void *pCallback,void *pProgressCallback,char *szBootDev)
|
||
{
|
||
bool bSuccess=false,bRet=false,bLock;
|
||
int iRet;
|
||
CRKImage *pImage=NULL;
|
||
CRKLog *pLog=NULL;
|
||
CRKAndroidDevice *pDevice=NULL;
|
||
CRKComm *pComm=NULL;
|
||
STRUCT_RKDEVICE_DESC device;
|
||
//BYTE key[514];
|
||
//UINT nKeySize=514;
|
||
BYTE uid[RKDEVICE_UID_LEN];
|
||
tstring strFw = szFw;
|
||
tstring strUid;
|
||
(void)szBootDev;
|
||
g_callback = (UpgradeCallbackFunc)pCallback;
|
||
g_progress_callback = (UpgradeProgressCallbackFunc)pProgressCallback;
|
||
if (g_progress_callback)
|
||
g_progress_callback(0.1,10);
|
||
|
||
pLog = new CRKLog();
|
||
if (!pLog)
|
||
goto EXIT_UPGRADE;
|
||
pLog->Record("Start to upgrade firmware...");
|
||
if (g_callback)
|
||
g_callback("Start to upgrade firmware... \n");
|
||
pImage = new CRKImage(strFw,bRet);
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->new CRKImage failed!");
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->new CRKImage failed! \n");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
pComm = new CRKUsbComm(pLog);
|
||
if (!pComm)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->new CRKComm failed!");
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->new CRKComm failed! \n");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
if (IsDeviceLock(pComm,bLock))
|
||
{
|
||
if (bLock)
|
||
{
|
||
bRet = true;
|
||
pImage = new CRKImage(strFw,bRet);
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->new CRKImage with check failed,%s!",szFw);
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->new CRKImage with check failed,%s! \n",szFw);
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
|
||
//bRet = GetPubicKeyFromExternal(szBootDev,pLog,key,nKeySize);
|
||
//if (!bRet)
|
||
//{
|
||
// if (szBootDev)
|
||
// pLog->Record("ERROR:do_rk_firmware_upgrade-->Get PubicKey failed,dev=%s!",szBootDev);
|
||
// else
|
||
// pLog->Record("ERROR:do_rk_firmware_upgrade-->Get PubicKey failed,dev=NULL!");
|
||
// goto EXIT_UPGRADE;
|
||
//}
|
||
//if(access("/res/publicKey.bin",F_OK) == 0){
|
||
// int fd = open("/tmp/publicKey.bin", O_RDONLY, 0);
|
||
// nKeySize = read(fd, key, 514);
|
||
//}else{
|
||
// printf("access /res/publicKey.bin failed!\n");
|
||
// goto EXIT_UPGRADE;
|
||
//}
|
||
//if (!UnlockDevice(pImage,pLog,key,nKeySize))
|
||
//{
|
||
// pLog->Record("ERROR:do_rk_firmware_upgrade-->UnlockDevice failed!");
|
||
// goto EXIT_UPGRADE;
|
||
//}
|
||
// if (pCallback)
|
||
// ((UpgradeCallbackFunc)pCallback)("pause");
|
||
|
||
}
|
||
else
|
||
{
|
||
pImage = new CRKImage(strFw,bRet);
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->new CRKImage failed,%s!",szFw);
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->new CRKImage failed,%s! \n",szFw);
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->IsDeviceLock failed!");
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->IsDeviceLock failed! \n");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
pDevice = new CRKAndroidDevice(device);
|
||
if (!pDevice)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->new CRKAndroidDevice failed!");
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->new CRKAndroidDevice failed! \n");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
pDevice->SetObject(pImage,pComm,pLog);
|
||
if (CreateUid(uid))
|
||
{
|
||
pDevice->Uid = uid;
|
||
pLog->PrintBuffer(strUid,uid,RKDEVICE_UID_LEN);
|
||
pLog->Record("uid:%s",strUid.c_str());
|
||
if (g_callback)
|
||
g_callback("uid:%s \n",strUid.c_str());
|
||
}
|
||
pDevice->m_pCallback = (UpgradeCallbackFunc)pCallback;
|
||
pDevice->m_pProcessCallback = (UpgradeProgressCallbackFunc)pProgressCallback;
|
||
pLog->Record("Get FlashInfo...");
|
||
if (g_callback)
|
||
g_callback("Get FlashInfo... \n");
|
||
bRet = pDevice->GetFlashInfo();
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->GetFlashInfo failed!");
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->GetFlashInfo failed! \n");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
pLog->Record("IDBlock Preparing...");
|
||
if (g_callback)
|
||
g_callback("IDBlock Preparing... \n");
|
||
iRet = pDevice->PrepareIDB();
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->PrepareIDB failed!");
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->PrepareIDB failed! \n");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
pLog->Record("IDBlock Writing...");
|
||
if (g_callback)
|
||
g_callback("IDBlock Writing... \n");
|
||
iRet = pDevice->DownloadIDBlock();
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->DownloadIDBlock failed!");
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->DownloadIDBlock failed! \n");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
|
||
if (strFw.find(_T(".bin"))!=tstring::npos)
|
||
{
|
||
pLog->Record("INFO:do_rk_firmware_upgrade-->Download loader only success!");
|
||
if (g_callback)
|
||
g_callback("INFO:do_rk_firmware_upgrade-->Download loader only success! \n");
|
||
bSuccess = true;
|
||
return bSuccess;
|
||
}
|
||
|
||
if (g_callback)
|
||
g_callback("INFO:do_rk_firmware_upgrade begin DownloadImage... ! \n");
|
||
iRet = pDevice->DownloadImage();
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
pLog->Record("ERROR:do_rk_firmware_upgrade-->DownloadImage failed!");
|
||
if (g_callback)
|
||
g_callback("ERROR:do_rk_firmware_upgrade-->DownloadImage failed! \n");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
|
||
bSuccess = true;
|
||
EXIT_UPGRADE:
|
||
if (bSuccess)
|
||
{
|
||
pLog->Record("Finish to upgrade firmware.");
|
||
if (g_callback)
|
||
g_callback("Finish to upgrade firmware. \n");
|
||
}
|
||
else
|
||
{
|
||
pLog->Record("Fail to upgrade firmware!");
|
||
if (g_callback)
|
||
g_callback("Fail to upgrade firmware! \n");
|
||
}
|
||
if (pLog)
|
||
{
|
||
delete pLog;
|
||
pLog = NULL;
|
||
}
|
||
if (pImage)
|
||
{
|
||
delete pImage;
|
||
pImage = NULL;
|
||
}
|
||
if (pDevice)
|
||
{
|
||
delete pDevice;
|
||
pDevice = NULL;
|
||
}
|
||
else
|
||
{
|
||
if (pComm)
|
||
{
|
||
delete pComm;
|
||
pComm = NULL;
|
||
}
|
||
}
|
||
|
||
return bSuccess;
|
||
}
|
||
bool do_rk_partition_upgrade(char *szFw,void *pCallback,void *pProgressCallback,char nBoot,char *szBootDev)
|
||
{
|
||
#if 0
|
||
bool bSuccess=false,bRet=false,bLock;
|
||
int iRet;
|
||
CRKImage *pImage=NULL;
|
||
CRKLog *pLog=NULL;
|
||
CRKAndroidDevice *pDevice=NULL;
|
||
CRKComm *pComm=NULL;
|
||
STRUCT_RKDEVICE_DESC device;
|
||
BYTE key[514];
|
||
UINT nKeySize=514;
|
||
tstring strFw = szFw;
|
||
vector<int> vecDownloadEntry;
|
||
vecDownloadEntry.clear();
|
||
g_callback = (UpgradeCallbackFunc)pCallback;
|
||
g_progress_callback = (UpgradeProgressCallbackFunc)pProgressCallback;
|
||
if (g_progress_callback)
|
||
g_progress_callback(0.1,5);
|
||
pLog = new CRKLog();
|
||
if (!pLog)
|
||
goto EXIT_DOWNLOAD;
|
||
pLog->Record("Start to upgrade partition...");
|
||
|
||
pComm = new CRKUsbComm(pLog);
|
||
if (!pComm)
|
||
{
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->new CRKComm failed!");
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
if (IsDeviceLock(pComm,bLock))
|
||
{
|
||
if (bLock)
|
||
{
|
||
bRet = true;
|
||
pImage = new CRKImage(strFw,bRet);
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->new CRKImage with check failed,%s!",szFw);
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
if(nBoot==0)//get key from nand or emmc
|
||
bRet = GetPubicKeyFromDevice(pLog,key,nKeySize);
|
||
else if((nBoot==1)||(nBoot==2))//get key from sd or usb disk
|
||
bRet = GetPubicKeyFromExternal(szBootDev,pLog,key,nKeySize);
|
||
else
|
||
bRet = false;
|
||
if (!bRet)
|
||
{
|
||
if (szBootDev)
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->Get PubicKey failed,boot=%d,dev=%s!",nBoot,szBootDev);
|
||
else
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->Get PubicKey failed,boot=%d,dev=NULL!",nBoot);
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
|
||
if (!UnlockDevice(pImage,pLog,key,nKeySize))
|
||
{
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->UnlockDevice failed!");
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
// if (pCallback)
|
||
// ((UpgradeCallbackFunc)pCallback)("pause");
|
||
|
||
}
|
||
else
|
||
{
|
||
pImage = new CRKImage(strFw,bRet);
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->new CRKImage failed,%s!",szFw);
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->IsDeviceLock failed!");
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
pDevice = new CRKAndroidDevice(device);
|
||
if (!pDevice)
|
||
{
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->new CRKAndroidDevice failed!");
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
pDevice->SetObject(pImage,pComm,pLog);
|
||
pDevice->m_pCallback = (UpgradeCallbackFunc)pCallback;
|
||
pDevice->m_pProcessCallback = (UpgradeProgressCallbackFunc)pProgressCallback;
|
||
bRet = pDevice->GetFlashInfo();
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->GetFlashInfo failed!");
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
iRet = pComm->RKU_ShowNandLBADevice();
|
||
pLog->Record("Info:do_rk_partition_upgrade-->RKU_ShowNandLBADevice ret=%d",iRet);
|
||
iRet = pDevice->UpgradePartition();
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
pLog->Record("ERROR:do_rk_partition_upgrade-->DownloadImage failed!");
|
||
goto EXIT_DOWNLOAD;
|
||
}
|
||
|
||
bSuccess = true;
|
||
EXIT_DOWNLOAD:
|
||
if (bSuccess)
|
||
{
|
||
pLog->Record("Finish to upgrade partition.");
|
||
}
|
||
else
|
||
{
|
||
pLog->Record("Fail to upgrade partition!");
|
||
}
|
||
if (pLog)
|
||
{
|
||
delete pLog;
|
||
pLog = NULL;
|
||
}
|
||
if (pImage)
|
||
{
|
||
delete pImage;
|
||
pImage = NULL;
|
||
}
|
||
if (pDevice)
|
||
{
|
||
delete pDevice;
|
||
pDevice = NULL;
|
||
}
|
||
else
|
||
{
|
||
if (pComm)
|
||
{
|
||
delete pComm;
|
||
pComm = NULL;
|
||
}
|
||
}
|
||
|
||
return bSuccess;
|
||
#else
|
||
(void)nBoot;
|
||
return do_rk_firmware_upgrade(szFw,pCallback,pProgressCallback,szBootDev);
|
||
#endif
|
||
}
|
||
|
||
|
||
bool do_rk_backup_recovery(void *pCallback,void *pProgressCallback)
|
||
{
|
||
bool bSuccess=false,bRet;
|
||
int i,iRet;
|
||
CRKLog *pLog=NULL;
|
||
CRKComm *pComm=NULL;
|
||
char *pParam=NULL;
|
||
int nParamSize=-1;
|
||
DWORD dwBackupOffset=0;
|
||
PARAM_ITEM_VECTOR vecParam;
|
||
STRUCT_RKIMAGE_HDR hdr;
|
||
g_callback = (UpgradeCallbackFunc)pCallback;
|
||
g_progress_callback = (UpgradeProgressCallbackFunc)pProgressCallback;
|
||
if (g_progress_callback)
|
||
g_progress_callback(0.1,10);
|
||
pLog = new CRKLog();
|
||
if (!pLog)
|
||
goto EXIT_RECOVERY;
|
||
pLog->Record("Start to recovery from backup...");
|
||
|
||
pComm = new CRKUsbComm(pLog);
|
||
if (!pComm)
|
||
{
|
||
pLog->Record("ERROR:do_rk_backup_recovery-->new CRKComm failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
iRet = pComm->RKU_ShowNandLBADevice();
|
||
pLog->Record("Info:do_rk_backup_recovery-->RKU_ShowNandLBADevice ret=%d",iRet);
|
||
pLog->Record("Start to read parameter...");
|
||
bRet = get_parameter_loader(pComm,pParam,nParamSize);
|
||
if (bRet)
|
||
{
|
||
pParam = new char[nParamSize];
|
||
if (pParam)
|
||
{
|
||
bRet = get_parameter_loader(pComm,pParam,nParamSize);
|
||
}
|
||
}
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("Read parameter failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
pLog->Record("Start to parse parameter...");
|
||
bRet = parse_parameter(pParam,vecParam);
|
||
if (!bRet)
|
||
{
|
||
pLog->Record("Parse parameter failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
for (i=0;i<vecParam.size();i++)
|
||
{
|
||
if (strcmp(vecParam[i].szItemName,PARTNAME_BACKUP)==0)
|
||
{
|
||
dwBackupOffset = vecParam[i].uiItemOffset;
|
||
break;
|
||
}
|
||
}
|
||
if (dwBackupOffset==0)
|
||
{
|
||
pLog->Record("Get backup offset failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
pLog->Record("Start to check firmware...");
|
||
if (!check_fw_header(pComm,dwBackupOffset,&hdr,pLog))
|
||
{
|
||
pLog->Record("Check firmware header failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
|
||
if (!check_fw_crc(pComm,dwBackupOffset,&hdr,pLog))
|
||
{
|
||
pLog->Record("Check firmware crc failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
|
||
pLog->Record("Start to write system...");
|
||
if(!download_backup_image(vecParam,(char*)PARTNAME_SYSTEM,dwBackupOffset,hdr,pComm,pLog))
|
||
{
|
||
pLog->Record("write system failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
|
||
bSuccess = true;
|
||
EXIT_RECOVERY:
|
||
if (bSuccess)
|
||
{
|
||
pLog->Record("Finish to recovery from backup.");
|
||
}
|
||
else
|
||
{
|
||
pLog->Record("Fail to recovery from backup!");
|
||
}
|
||
if (pParam)
|
||
{
|
||
delete []pParam;
|
||
pParam = NULL;
|
||
}
|
||
|
||
if (pLog)
|
||
{
|
||
delete pLog;
|
||
pLog = NULL;
|
||
}
|
||
|
||
if (pComm)
|
||
{
|
||
delete pComm;
|
||
pComm = NULL;
|
||
}
|
||
|
||
return bSuccess;
|
||
|
||
}
|
||
|
||
|
||
bool do_rk_sparse_update(const char *partitionName, const char *src_path){
|
||
bool bSuccess=false, bRet;
|
||
int i, iRet;
|
||
CRKComm *pComm = NULL;
|
||
CRKLog *pLog = NULL;
|
||
PARAM_ITEM_VECTOR vecParam;
|
||
int nParamSize = -1;
|
||
char *pParam = NULL;
|
||
DWORD dwBackupOffset = 0;
|
||
|
||
pLog = new CRKLog();
|
||
if(!pLog)
|
||
goto EXIT_RECOVERY;
|
||
pLog->Record("Start to do_rk_sparse_update ...");
|
||
|
||
pComm = new CRKUsbComm(pLog);
|
||
if(!pComm)
|
||
{
|
||
pLog->Record("ERROR:do_rk_sparse_update-->new CRKComm failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
|
||
iRet = pComm->RKU_ShowNandLBADevice();
|
||
pLog->Record("Info:do_rk_sparse_update-->RKU_ShowNandLBADevice ret=%d",iRet);
|
||
pLog->Record("Start to read parameter...");
|
||
bRet = get_parameter_loader(pComm, pParam, nParamSize);
|
||
|
||
|
||
if(bRet)
|
||
{
|
||
pParam = new char[nParamSize];
|
||
if (pParam)
|
||
{
|
||
bRet = get_parameter_loader(pComm, pParam, nParamSize);
|
||
}
|
||
}
|
||
|
||
if(!bRet)
|
||
{
|
||
pLog->Record("Read parameter failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
|
||
pLog->Record("Start to parse parameter...");
|
||
bRet = parse_parameter(pParam, vecParam);
|
||
if(!bRet)
|
||
{
|
||
pLog->Record("Parse parameter failed!");
|
||
goto EXIT_RECOVERY;
|
||
}
|
||
|
||
|
||
for(i = 0;i < vecParam.size();i++)
|
||
{
|
||
if (strcmp(vecParam[i].szItemName, partitionName) == 0){
|
||
dwBackupOffset = vecParam[i].uiItemOffset;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(dwBackupOffset == 0){
|
||
pLog->Record("Get %s offset failed!", partitionName);
|
||
goto EXIT_RECOVERY;
|
||
}else{
|
||
printf("dwBackupOffset is %d.\n", dwBackupOffset);
|
||
//dwBackupOffset
|
||
RKSparse *sparse = new RKSparse(src_path);
|
||
if(sparse->SparseFile_Download(dwBackupOffset, pComm))
|
||
bSuccess = true;
|
||
delete sparse;
|
||
}
|
||
|
||
|
||
EXIT_RECOVERY:
|
||
if (bSuccess)
|
||
{
|
||
pLog->Record("Finish to recovery from backup.");
|
||
}
|
||
else
|
||
{
|
||
pLog->Record("Fail to recovery from backup!");
|
||
}
|
||
if (pParam)
|
||
{
|
||
delete []pParam;
|
||
pParam = NULL;
|
||
}
|
||
|
||
if (pLog)
|
||
{
|
||
delete pLog;
|
||
pLog = NULL;
|
||
}
|
||
|
||
if (pComm)
|
||
{
|
||
delete pComm;
|
||
pComm = NULL;
|
||
}
|
||
|
||
return bSuccess;
|
||
}
|
||
bool do_rk_gpt_update(char *szFw,void *pCallback,void *pProgressCallback,char *szBootDev){
|
||
bool bSuccess=false, bRet;
|
||
int iRet,iFileSize;
|
||
CRKImage *pImage=NULL;
|
||
CRKLog *pLog=NULL;
|
||
CRKAndroidDevice *pDevice=NULL;
|
||
CRKComm *pComm=NULL;
|
||
PARAM_ITEM_VECTOR vecParam;
|
||
//int nParamSize = -1;
|
||
//char *pParam = NULL;
|
||
//DWORD dwBackupOffset = 0;
|
||
BYTE *m_paramBuffer;
|
||
BYTE *m_gptBuffer = nullptr;
|
||
BYTE *backup_gpt;
|
||
PARAM_ITEM_VECTOR vecItems;
|
||
CONFIG_ITEM_VECTOR vecUuids;
|
||
long long uiFlashSize; //bit
|
||
tstring strFw = szFw;
|
||
// BYTE uid[RKDEVICE_UID_LEN];
|
||
tstring strUid;
|
||
//STRUCT_RKDEVICE_DESC device;
|
||
FILE *m_pFile;
|
||
DWORD uiActualRead;
|
||
(void)pCallback;(void)pProgressCallback;(void)szBootDev;
|
||
pLog->Record("ERROR:strFw======%s",szFw);
|
||
pLog = new CRKLog();
|
||
if (!pLog)
|
||
goto EXIT_UPGRADE;
|
||
pLog->Record("Start to do_rk_gpt_update ...");
|
||
pComm = new CRKUsbComm(pLog);
|
||
if (!pComm)
|
||
{
|
||
pLog->Record("ERROR:do_rk_gpt_update-->new CRKComm failed!");
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
uiFlashSize = pComm->m_FlashSize;
|
||
pLog->Record("uiFlashSize ------------ %lld...",uiFlashSize);
|
||
if (!m_gptBuffer)
|
||
{
|
||
m_gptBuffer = new BYTE[SECTOR_SIZE*67];
|
||
if (!m_gptBuffer)
|
||
{
|
||
if (pLog)
|
||
{
|
||
pLog->Record(_T("ERROR:RKA_Gpt_Download-->new memory failed,err=%d)"),errno);
|
||
}
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
}
|
||
memset(m_gptBuffer,0,SECTOR_SIZE*67);
|
||
//<2F>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
||
m_pFile = fopen(szFw,"rb");
|
||
fseek(m_pFile, 0, SEEK_END);
|
||
iFileSize=ftell(m_pFile);
|
||
m_paramBuffer = new BYTE[iFileSize];
|
||
memset(m_paramBuffer,0,iFileSize);
|
||
pLog->Record(_T("iFileSize is %d"),iFileSize);
|
||
fseek(m_pFile,0,SEEK_SET);
|
||
uiActualRead = fread(m_paramBuffer,1,iFileSize,m_pFile);
|
||
if(uiActualRead != iFileSize)
|
||
{
|
||
pLog->Record(_T("ERROR:RKA_Gpt_Download-->read parameter file fail,read is %d,total is %d!"),uiActualRead,iFileSize);
|
||
}
|
||
bRet = parse_parameter((char *)(m_paramBuffer+8),vecItems);
|
||
if (!bRet)
|
||
{
|
||
if (pLog)
|
||
{
|
||
pLog->Record(_T("ERROR:RKA_Gpt_Download-->parse_parameter failed)"));
|
||
}
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
bRet = get_uuid_from_parameter((char *)(m_paramBuffer+8),vecUuids);
|
||
backup_gpt = m_gptBuffer+34*SECTOR_SIZE;
|
||
create_gpt_buffer(m_gptBuffer,vecItems,vecUuids,uiFlashSize/512);
|
||
memcpy(backup_gpt, m_gptBuffer + 2* SECTOR_SIZE, 32 * SECTOR_SIZE);
|
||
memcpy(backup_gpt + 32 * SECTOR_SIZE, m_gptBuffer + SECTOR_SIZE, SECTOR_SIZE);
|
||
prepare_gpt_backup(m_gptBuffer, backup_gpt, uiFlashSize/512);
|
||
iRet = pComm->RKU_WriteLBA(0,34,m_gptBuffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (pLog)
|
||
{
|
||
pLog->Record(_T("ERROR:RKA_Gpt_Download-->write gpt master failed,RetCode(%d)"),iRet);
|
||
}
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
if (pLog)
|
||
{
|
||
pLog->Record(_T("INFO:RKA_Gpt_Download-->write gpt master successfully!"));
|
||
}
|
||
iRet = pComm->RKU_WriteLBA(uiFlashSize/512-33,33,backup_gpt);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (pLog)
|
||
{
|
||
pLog->Record(_T("ERROR:RKA_Gpt_Download-->write gpt backup failed,RetCode(%d)"),iRet);
|
||
}
|
||
goto EXIT_UPGRADE;
|
||
}
|
||
if (pLog)
|
||
{
|
||
pLog->Record(_T("INFO:RKA_Gpt_Download-->write gpt backup also successfully!"));
|
||
}
|
||
bSuccess = true;
|
||
|
||
EXIT_UPGRADE:
|
||
if (bSuccess)
|
||
{
|
||
pLog->Record("Finish to upgrade parameter.");
|
||
}
|
||
else
|
||
{
|
||
pLog->Record("Fail to upgrade parameter!");
|
||
}
|
||
if (pLog)
|
||
{
|
||
delete pLog;
|
||
pLog = NULL;
|
||
}
|
||
if (pImage)
|
||
{
|
||
delete pImage;
|
||
pImage = NULL;
|
||
}
|
||
if (pDevice)
|
||
{
|
||
delete pDevice;
|
||
pDevice = NULL;
|
||
}
|
||
else
|
||
{
|
||
if (pComm)
|
||
{
|
||
delete pComm;
|
||
pComm = NULL;
|
||
}
|
||
}
|
||
return bSuccess;
|
||
}
|
||
|