4017 lines
100 KiB
C++
Executable File
4017 lines
100 KiB
C++
Executable File
/*
|
||
* Copyright 2019 Rockchip Electronics Co., Ltd
|
||
* Dayao Ji <jdy@rock-chips.com>
|
||
*
|
||
* SPDX-License-Identifier: GPL-2.0+
|
||
*/
|
||
|
||
#include "rkupdate/RKAndroidDevice.h"
|
||
#define tole(x) (x)
|
||
/*factor is 0xedb88320*/
|
||
bool CRKAndroidDevice::bGptFlag = 0;
|
||
unsigned int crc32table_le[] = {
|
||
tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
|
||
tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
|
||
tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
|
||
tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
|
||
tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
|
||
tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
|
||
tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
|
||
tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
|
||
tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
|
||
tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
|
||
tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
|
||
tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
|
||
tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
|
||
tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
|
||
tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
|
||
tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
|
||
tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
|
||
tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
|
||
tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
|
||
tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
|
||
tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
|
||
tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
|
||
tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
|
||
tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
|
||
tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
|
||
tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
|
||
tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
|
||
tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
|
||
tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
|
||
tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
|
||
tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
|
||
tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
|
||
tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
|
||
tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
|
||
tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
|
||
tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
|
||
tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
|
||
tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
|
||
tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
|
||
tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
|
||
tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
|
||
tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
|
||
tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
|
||
tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
|
||
tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
|
||
tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
|
||
tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
|
||
tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
|
||
tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
|
||
tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
|
||
tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
|
||
tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
|
||
tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
|
||
tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
|
||
tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
|
||
tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
|
||
tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
|
||
tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
|
||
tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
|
||
tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
|
||
tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
|
||
tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
|
||
tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
|
||
tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
|
||
};
|
||
|
||
CHAR CRKAndroidDevice::FindIDBlock(char pos,char &IDBlockPos)
|
||
{
|
||
BYTE bData[SECTOR_SIZE*4];
|
||
int iRet = ERR_SUCCESS;
|
||
int i = FindValidBlocks(pos,1);
|
||
if ( i<0 )
|
||
return -1;
|
||
for( ;i<IDBLOCK_TOP;i=FindValidBlocks(i+1,1) )
|
||
{
|
||
if ( i<0 )
|
||
{
|
||
break;
|
||
}
|
||
memset(bData,0,SECTOR_SIZE*4);
|
||
iRet = m_pComm->RKU_ReadSector( i*m_flashInfo.uiSectorPerBlock, 4, bData);
|
||
|
||
if(ERR_SUCCESS!=iRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:FindIDBlock-->RKU_ReadSector %x failed,RetCode(%d)"),i*m_flashInfo.uiSectorPerBlock,iRet);
|
||
}
|
||
return -1;//<2F><><EFBFBD>ݶ<EFBFBD>ȡʧ<C8A1><CAA7>
|
||
}
|
||
RKANDROID_IDB_SEC0 *pSec0;
|
||
pSec0 = (RKANDROID_IDB_SEC0 *)bData;
|
||
P_RC4((BYTE *)pSec0,SECTOR_SIZE);
|
||
// if (bData[514]==0x69)//0x69='i'
|
||
if (pSec0->dwTag==0x0FF0AA55)
|
||
{
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>tag
|
||
RKANDROID_IDB_SEC1 *pSec;
|
||
pSec = (RKANDROID_IDB_SEC1 *)(bData+SECTOR_SIZE);
|
||
if (pSec->uiChipTag==0x38324B52)
|
||
{
|
||
IDBlockPos = i;
|
||
return 0;//<2F>ҵ<EFBFBD>idb
|
||
}
|
||
else
|
||
{
|
||
continue;//tag<61><67><EFBFBD><EFBFBD>
|
||
}
|
||
}
|
||
|
||
}
|
||
return -1;
|
||
}
|
||
char CRKAndroidDevice::FindAllIDB()
|
||
{
|
||
char i,iIndex,iStart=0;
|
||
CHAR iRet;
|
||
m_oldIDBCounts = 0;
|
||
for( i=0; i<5; i++)
|
||
{
|
||
iRet = FindIDBlock( iStart,iIndex );
|
||
if ( iRet<0 )
|
||
{
|
||
return m_oldIDBCounts;
|
||
}
|
||
|
||
m_idBlockOffset[(int)i] = iIndex;
|
||
m_oldIDBCounts++;
|
||
iStart = iIndex+1;
|
||
}
|
||
|
||
return m_oldIDBCounts;
|
||
}
|
||
bool CRKAndroidDevice::ReserveIDBlock(char iBlockIndex,char iIdblockPos)
|
||
{
|
||
char i;
|
||
CHAR iRet;
|
||
for(i=iIdblockPos; i<IDB_BLOCKS; i++)
|
||
{
|
||
iRet = iBlockIndex = FindValidBlocks(iBlockIndex,m_flashInfo.usPhyBlokcPerIDB);
|
||
if( iRet<0 )
|
||
{
|
||
return false;
|
||
}
|
||
m_idBlockOffset[(int)i] = iBlockIndex;
|
||
iBlockIndex += m_flashInfo.usPhyBlokcPerIDB;
|
||
}
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::CalcIDBCount()
|
||
{
|
||
bool bRet;
|
||
UINT uiIdSectorNum;//ID BLOCK<43><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
bRet = GetLoaderSize();
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:CalcIDBCount-->GetLoaderSize failed"));
|
||
}
|
||
return false;
|
||
}
|
||
bRet = GetLoaderDataSize();
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:CalcIDBCount-->GetLoaderDataSize failed"));
|
||
}
|
||
return false;
|
||
}
|
||
if (m_pImage->m_bootObject->IsNewIDBFlag())
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:CalcIDBCount IsNewIDBFlag is true"));
|
||
}
|
||
bRet = GetLoaderHeadSize();
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:CalcIDBCount-->GetLoaderHeadSize failed"));
|
||
}
|
||
return false;
|
||
}
|
||
uiIdSectorNum = m_usFlashHeadSec + m_usFlashDataSec + m_usFlashBootSec;
|
||
} else {
|
||
uiIdSectorNum = 4 + m_usFlashDataSec + m_usFlashBootSec;
|
||
}
|
||
|
||
m_flashInfo.uiSecNumPerIDB = uiIdSectorNum;
|
||
m_flashInfo.usPhyBlokcPerIDB = CALC_UNIT(uiIdSectorNum,m_flashInfo.usValidSecPerBlock);
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::OffsetIDBlock(char pos)
|
||
{
|
||
int iBlockIndex,i;
|
||
for ( i=0;i<m_flashInfo.usPhyBlokcPerIDB;i++)
|
||
{
|
||
m_flashInfo.blockState[m_idBlockOffset[(int)pos]+i]=1;//<2F><><EFBFBD><EFBFBD><EFBFBD>ϻ<EFBFBD><CFBB><EFBFBD>
|
||
}
|
||
iBlockIndex = m_idBlockOffset[(int)pos]+m_flashInfo.usPhyBlokcPerIDB;
|
||
for(i=pos; i<5; i++)
|
||
{
|
||
iBlockIndex = FindValidBlocks(iBlockIndex, m_flashInfo.usPhyBlokcPerIDB);
|
||
if ( iBlockIndex<0 )
|
||
{
|
||
return false;
|
||
}
|
||
m_idBlockOffset[i] = iBlockIndex;
|
||
iBlockIndex += m_flashInfo.usPhyBlokcPerIDB;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::GetLoaderSize()
|
||
{
|
||
if (!m_pImage)
|
||
{
|
||
return false;
|
||
}
|
||
CHAR index;
|
||
bool bRet;
|
||
tchar loaderName[]=_T("FlashBoot");
|
||
index = m_pImage->m_bootObject->GetIndexByName(ENTRYLOADER,loaderName);
|
||
if (index==-1)
|
||
{
|
||
return false;
|
||
}
|
||
DWORD dwDelay;
|
||
bRet = m_pImage->m_bootObject->GetEntryProperty(ENTRYLOADER,index,m_dwLoaderSize,dwDelay);
|
||
if (bRet)
|
||
{
|
||
m_usFlashBootSec = PAGEALIGN(BYTE2SECTOR(m_dwLoaderSize))*4;
|
||
}
|
||
return bRet;
|
||
}
|
||
bool CRKAndroidDevice::GetLoaderDataSize()
|
||
{
|
||
if (!m_pImage)
|
||
{
|
||
return false;
|
||
}
|
||
CHAR index;
|
||
bool bRet;
|
||
tchar loaderName[]=_T("FlashData");
|
||
index = m_pImage->m_bootObject->GetIndexByName(ENTRYLOADER,loaderName);
|
||
if (index==-1)
|
||
{
|
||
return false;
|
||
}
|
||
DWORD dwDelay;
|
||
bRet = m_pImage->m_bootObject->GetEntryProperty(ENTRYLOADER,index,m_dwLoaderDataSize,dwDelay);
|
||
if (bRet)
|
||
{
|
||
m_usFlashDataSec = PAGEALIGN(BYTE2SECTOR(m_dwLoaderDataSize))*4;
|
||
}
|
||
return bRet;
|
||
}
|
||
|
||
bool CRKAndroidDevice::GetLoaderHeadSize()
|
||
{
|
||
if (!m_pImage)
|
||
{
|
||
return false;
|
||
}
|
||
char index;
|
||
bool bRet;
|
||
tchar loaderName[]=_T("FlashHead");
|
||
index = m_pImage->m_bootObject->GetIndexByName(ENTRYLOADER,loaderName);
|
||
if (index==-1)
|
||
{
|
||
return false;
|
||
}
|
||
DWORD dwDelay;
|
||
bRet = m_pImage->m_bootObject->GetEntryProperty(ENTRYLOADER,index,m_dwLoaderHeadSize,dwDelay);
|
||
if (bRet)
|
||
{
|
||
m_usFlashHeadSec = PAGEALIGN(BYTE2SECTOR(m_dwLoaderHeadSize))*4;
|
||
}
|
||
return bRet;
|
||
}
|
||
|
||
CRKAndroidDevice::CRKAndroidDevice(STRUCT_RKDEVICE_DESC &device):CRKDevice(device)
|
||
{
|
||
m_oldSec0 = NULL;
|
||
m_oldSec1 = NULL;
|
||
m_oldSec2 = NULL;
|
||
m_oldSec3 = NULL;
|
||
m_dwLoaderSize = 0;
|
||
m_dwLoaderDataSize = 0;
|
||
m_dwLoaderHeadSize = 0;
|
||
m_oldIDBCounts = 0;
|
||
m_usFlashBootSec = 0;
|
||
m_usFlashDataSec = 0;
|
||
m_usFlashHeadSec = 0;
|
||
m_dwBackupOffset = 0xFFFFFFFF;
|
||
m_paramBuffer = NULL;
|
||
m_pCallback = NULL;
|
||
m_pProcessCallback = NULL;
|
||
}
|
||
CRKAndroidDevice::~CRKAndroidDevice()
|
||
{
|
||
if (m_oldSec0)
|
||
{
|
||
delete m_oldSec0;
|
||
m_oldSec0 = NULL;
|
||
}
|
||
if (m_oldSec1)
|
||
{
|
||
delete m_oldSec1;
|
||
m_oldSec1 = NULL;
|
||
}
|
||
if (m_oldSec2)
|
||
{
|
||
delete m_oldSec2;
|
||
m_oldSec2 = NULL;
|
||
}
|
||
if (m_oldSec3)
|
||
{
|
||
delete m_oldSec3;
|
||
m_oldSec3 = NULL;
|
||
}
|
||
if (m_paramBuffer)
|
||
{
|
||
delete []m_paramBuffer;
|
||
m_paramBuffer = NULL;
|
||
}
|
||
}
|
||
bool CRKAndroidDevice::GetOldSectorData()
|
||
{
|
||
BYTE bData[SECTOR_SIZE*4];
|
||
|
||
if (m_oldIDBCounts<=0)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (!GetWriteBackData(m_oldIDBCounts,bData))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:GetOldSectorData-->GetWriteBackData failed"));
|
||
}
|
||
return false;//<2F><><EFBFBD>ݶ<EFBFBD>ȡʧ<C8A1><CAA7>
|
||
}
|
||
PBYTE pSec;
|
||
if (!m_oldSec0)
|
||
{
|
||
m_oldSec0 = new RKANDROID_IDB_SEC0;
|
||
}
|
||
pSec = (PBYTE)(m_oldSec0);
|
||
memset(pSec,0,SECTOR_SIZE);
|
||
memcpy(pSec,bData,SECTOR_SIZE);
|
||
P_RC4(pSec,SECTOR_SIZE);
|
||
|
||
if (!m_oldSec1)
|
||
{
|
||
m_oldSec1 = new RKANDROID_IDB_SEC1;
|
||
}
|
||
pSec = (PBYTE)(m_oldSec1);
|
||
memset(pSec,0,SECTOR_SIZE);
|
||
memcpy(pSec,bData+512,SECTOR_SIZE);
|
||
|
||
if (!m_oldSec2)
|
||
{
|
||
m_oldSec2 = new RKANDROID_IDB_SEC2;
|
||
}
|
||
pSec = (PBYTE)(m_oldSec2);
|
||
memset(pSec,0,SECTOR_SIZE);
|
||
memcpy(pSec,bData+512*2,SECTOR_SIZE);
|
||
P_RC4(pSec,SECTOR_SIZE);
|
||
|
||
if (!m_oldSec3)
|
||
{
|
||
m_oldSec3 = new RKANDROID_IDB_SEC3;
|
||
}
|
||
pSec = (PBYTE)(m_oldSec3);
|
||
memset(pSec,0,SECTOR_SIZE);
|
||
memcpy(pSec,bData+512*3,SECTOR_SIZE);
|
||
P_RC4(pSec,SECTOR_SIZE);
|
||
|
||
return true;
|
||
|
||
}
|
||
bool CRKAndroidDevice::MakeSector0(PBYTE pSector)
|
||
{
|
||
PRKANDROID_IDB_SEC0 pSec0;
|
||
memset(pSector,0,SECTOR_SIZE);
|
||
pSec0 = (PRKANDROID_IDB_SEC0)pSector;
|
||
|
||
pSec0->dwTag = 0x0FF0AA55;
|
||
if (m_pImage->m_bootObject->Rc4DisableFlag)
|
||
{
|
||
pSec0->uiRc4Flag = 1;
|
||
}
|
||
pSec0->usBootCode1Offset = 0x4;
|
||
pSec0->usBootCode2Offset = 0x4;
|
||
pSec0->usBootDataSize = m_usFlashDataSec;
|
||
pSec0->usBootCodeSize = m_usFlashDataSec + m_usFlashBootSec;
|
||
|
||
// pSec0->usCrc = CRC_16(pSector,SECTOR_SIZE-2);
|
||
return true;
|
||
}
|
||
|
||
void CRKAndroidDevice::MakeSector1(PBYTE pSector)
|
||
{
|
||
PRKANDROID_IDB_SEC1 pSec1;
|
||
memset(pSector,0,SECTOR_SIZE);
|
||
pSec1 = (PRKANDROID_IDB_SEC1)pSector;
|
||
USHORT usSysReserved;
|
||
if ((m_idBlockOffset[4]+1)%12==0)
|
||
{
|
||
usSysReserved=m_idBlockOffset[4]+13;
|
||
}
|
||
else
|
||
{
|
||
usSysReserved =((m_idBlockOffset[4]+1)/12+1)*12;
|
||
}
|
||
if (usSysReserved>IDBLOCK_TOP)
|
||
{
|
||
usSysReserved = IDBLOCK_TOP;
|
||
}
|
||
pSec1->usSysReservedBlock = usSysReserved;
|
||
|
||
|
||
pSec1->usDisk0Size = 0;
|
||
pSec1->usDisk1Size = 0;
|
||
pSec1->usDisk2Size = 0;
|
||
pSec1->usDisk3Size = 0;
|
||
pSec1->uiChipTag = 0x38324B52;
|
||
pSec1->uiMachineId = 0;
|
||
pSec1->usLoaderYear = UshortToBCD(((STRUCT_RKTIME)m_pImage->m_bootObject->ReleaseTime).usYear);
|
||
pSec1->usLoaderDate = ByteToBCD(((STRUCT_RKTIME)m_pImage->m_bootObject->ReleaseTime).ucMonth);
|
||
pSec1->usLoaderDate = (pSec1->usLoaderDate<<8)|ByteToBCD(((STRUCT_RKTIME)m_pImage->m_bootObject->ReleaseTime).ucDay);
|
||
pSec1->usLoaderVer = m_pImage->m_bootObject->Version;
|
||
if (m_oldSec1)
|
||
{
|
||
pSec1->usLastLoaderVer = m_oldSec1->usLoaderVer;
|
||
pSec1->usReadWriteTimes = m_oldSec1->usReadWriteTimes+1;
|
||
}
|
||
else
|
||
{
|
||
pSec1->usLastLoaderVer = 0;
|
||
pSec1->usReadWriteTimes = 1;
|
||
}
|
||
pSec1->uiFlashSize = m_flashInfo.uiFlashSize*2*1024;
|
||
pSec1->usBlockSize = m_flashInfo.usBlockSize*2;
|
||
pSec1->bPageSize = m_flashInfo.uiPageSize*2;
|
||
pSec1->bECCBits = m_flashInfo.bECCBits;
|
||
pSec1->bAccessTime = m_flashInfo.bAccessTime;
|
||
|
||
pSec1->usFlashInfoLen = 0;
|
||
pSec1->usFlashInfoOffset = 0;
|
||
|
||
|
||
pSec1->usIdBlock0 = m_idBlockOffset[0];
|
||
pSec1->usIdBlock1 = m_idBlockOffset[1];
|
||
pSec1->usIdBlock2 = m_idBlockOffset[2];
|
||
pSec1->usIdBlock3 = m_idBlockOffset[3];
|
||
pSec1->usIdBlock4 = m_idBlockOffset[4];
|
||
}
|
||
bool CRKAndroidDevice::MakeSector2(PBYTE pSector)
|
||
{
|
||
PRKANDROID_IDB_SEC2 pSec2;
|
||
pSec2 = (PRKANDROID_IDB_SEC2)pSector;
|
||
|
||
pSec2->usInfoSize = 0;
|
||
memset(pSec2->bChipInfo,0,CHIPINFO_LEN);
|
||
|
||
if (m_oldSec2)
|
||
{
|
||
memcpy(pSec2->reserved,m_oldSec2->reserved,RKANDROID_SEC2_RESERVED_LEN);
|
||
pSec2->usSec3CustomDataOffset = m_oldSec2->usSec3CustomDataOffset;
|
||
pSec2->usSec3CustomDataSize = m_oldSec2->usSec3CustomDataSize;
|
||
}
|
||
else
|
||
{
|
||
memset(pSec2->reserved,0,RKANDROID_SEC2_RESERVED_LEN);
|
||
pSec2->usSec3CustomDataOffset = m_usWriteBackCustomDataOffset;
|
||
pSec2->usSec3CustomDataSize = m_usWriteBackCustomDataSize;
|
||
}
|
||
|
||
strcpy(pSec2->szVcTag,"VC");
|
||
strcpy(pSec2->szCrcTag,"CRC");
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::MakeSector3(PBYTE pSector)
|
||
{
|
||
PRKANDROID_IDB_SEC3 pSec3;
|
||
memset(pSector,0,SECTOR_SIZE);
|
||
pSec3 = (PRKANDROID_IDB_SEC3)pSector;
|
||
|
||
if (m_oldSec3)
|
||
{
|
||
memcpy(pSector,(PBYTE)m_oldSec3,SECTOR_SIZE);
|
||
}
|
||
else
|
||
{
|
||
//if (m_backupBuffer)
|
||
//{
|
||
memcpy(pSector,(PBYTE)m_backupBuffer,SECTOR_SIZE);
|
||
//}
|
||
}
|
||
|
||
|
||
if (m_uid)
|
||
{
|
||
//if ((m_oldSec3)||(m_backupBuffer))
|
||
if ((m_oldSec3))
|
||
{
|
||
if (!CheckUid(pSec3->uidSize,pSec3->uid))
|
||
{
|
||
pSec3->uidSize = RKDEVICE_UID_LEN;
|
||
memcpy(pSec3->uid,m_uid,RKDEVICE_UID_LEN);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
pSec3->uidSize = RKDEVICE_UID_LEN;
|
||
memcpy(pSec3->uid,m_uid,RKDEVICE_UID_LEN);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
int CRKAndroidDevice::MakeIDBlockData(PBYTE lpIDBlock)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:MakeIDBlockData in"));
|
||
}
|
||
RKANDROID_IDB_SEC0 sector0Info;
|
||
RKANDROID_IDB_SEC1 sector1Info;
|
||
RKANDROID_IDB_SEC2 sector2Info;
|
||
RKANDROID_IDB_SEC3 sector3Info;
|
||
|
||
if (!m_pImage)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeIDBlockData-->Image is invalid"));
|
||
}
|
||
return -1;
|
||
}
|
||
CHAR index;
|
||
tchar loaderCodeName[]=_T("FlashBoot");
|
||
index = m_pImage->m_bootObject->GetIndexByName(ENTRYLOADER,loaderCodeName);
|
||
if (index==-1)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeIDBlockData-->Get LoaderCode Entry failed"));
|
||
}
|
||
return -2;
|
||
}
|
||
PBYTE loaderCodeBuffer;
|
||
loaderCodeBuffer = new BYTE[m_dwLoaderSize];
|
||
memset(loaderCodeBuffer,0,m_dwLoaderSize);
|
||
if ( !m_pImage->m_bootObject->GetEntryData(ENTRYLOADER,index,loaderCodeBuffer) )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeIDBlockData-->Get LoaderCode Data failed"));
|
||
}
|
||
delete []loaderCodeBuffer;
|
||
return -3;
|
||
}
|
||
|
||
tchar loaderDataName[]=_T("FlashData");
|
||
index = m_pImage->m_bootObject->GetIndexByName(ENTRYLOADER,loaderDataName);
|
||
if (index==-1)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeIDBlockData-->Get LoaderData Entry failed"));
|
||
}
|
||
delete []loaderCodeBuffer;
|
||
return -4;
|
||
}
|
||
PBYTE loaderDataBuffer;
|
||
loaderDataBuffer = new BYTE[m_dwLoaderDataSize];
|
||
memset(loaderDataBuffer,0,m_dwLoaderDataSize);
|
||
if ( !m_pImage->m_bootObject->GetEntryData(ENTRYLOADER,index,loaderDataBuffer) )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeIDBlockData-->Get LoaderData Data failed"));
|
||
}
|
||
delete []loaderDataBuffer;
|
||
delete []loaderCodeBuffer;
|
||
return -5;
|
||
}
|
||
|
||
////////////// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ////////////////////////////////////////////
|
||
UINT i;
|
||
MakeSector0((PBYTE)§or0Info);
|
||
MakeSector1((PBYTE)§or1Info);
|
||
if (!MakeSector2((PBYTE)§or2Info))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeIDBlockData-->MakeSector2 failed"));
|
||
}
|
||
return -6;
|
||
}
|
||
if (!MakeSector3((PBYTE)§or3Info))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeIDBlockData-->MakeSector3 failed"));
|
||
}
|
||
return -7;
|
||
}
|
||
sector2Info.usSec0Crc = CRC_16((PBYTE)§or0Info,SECTOR_SIZE);
|
||
sector2Info.usSec1Crc = CRC_16((PBYTE)§or1Info,SECTOR_SIZE);
|
||
sector2Info.usSec3Crc = CRC_16((PBYTE)§or3Info,SECTOR_SIZE);
|
||
|
||
memcpy(lpIDBlock, §or0Info, SECTOR_SIZE);
|
||
memcpy(lpIDBlock+SECTOR_SIZE, §or1Info, SECTOR_SIZE);
|
||
// memcpy(lpIDBlock+SECTOR_SIZE*2, §or2Info, SECTOR_SIZE);
|
||
memcpy(lpIDBlock+SECTOR_SIZE*3, §or3Info, SECTOR_SIZE);
|
||
|
||
if (sector0Info.uiRc4Flag)
|
||
{//close rc4 encryption
|
||
for (i=0;i<m_dwLoaderDataSize/SECTOR_SIZE;i++)
|
||
{
|
||
P_RC4(loaderDataBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
|
||
}
|
||
for (i=0;i<m_dwLoaderSize/SECTOR_SIZE;i++)
|
||
{
|
||
P_RC4(loaderCodeBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
|
||
}
|
||
}
|
||
|
||
memcpy(lpIDBlock+SECTOR_SIZE*4, loaderDataBuffer, m_dwLoaderDataSize);
|
||
memcpy(lpIDBlock+SECTOR_SIZE*(4+m_usFlashDataSec), loaderCodeBuffer, m_dwLoaderSize);
|
||
|
||
sector2Info.uiBootCodeCrc = CRC_32((PBYTE)(lpIDBlock+SECTOR_SIZE*4),sector0Info.usBootCodeSize*SECTOR_SIZE);
|
||
memcpy(lpIDBlock+SECTOR_SIZE*2, §or2Info, SECTOR_SIZE);
|
||
|
||
for(i=0; i<4; i++)
|
||
{
|
||
if(i == 1)
|
||
{
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
P_RC4(lpIDBlock+SECTOR_SIZE*i, SECTOR_SIZE);
|
||
}
|
||
}
|
||
|
||
delete []loaderDataBuffer;
|
||
delete []loaderCodeBuffer;
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:MakeIDBlockData out"));
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int CRKAndroidDevice::MakeNewIDBlockData(PBYTE lpIDBlock)
|
||
{
|
||
int i;
|
||
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:MakeNewIDBlockData in"));
|
||
}
|
||
|
||
if (!m_pImage)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeNewIDBlockData-->Image is invalid"));
|
||
}
|
||
return -1;
|
||
}
|
||
char index;
|
||
tchar loaderCodeName[]=_T("FlashBoot");
|
||
index = m_pImage->m_bootObject->GetIndexByName(ENTRYLOADER,loaderCodeName);
|
||
if (index==-1)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeNewIDBlockData-->Get LoaderCode Entry failed"));
|
||
}
|
||
return -2;
|
||
}
|
||
PBYTE loaderCodeBuffer;
|
||
loaderCodeBuffer = new BYTE[m_dwLoaderSize];
|
||
memset(loaderCodeBuffer,0,m_dwLoaderSize);
|
||
if ( !m_pImage->m_bootObject->GetEntryData(ENTRYLOADER,index,loaderCodeBuffer) )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeNewIDBlockData-->Get LoaderCode Data failed"));
|
||
}
|
||
delete []loaderCodeBuffer;
|
||
return -3;
|
||
}
|
||
|
||
tchar loaderDataName[]=_T("FlashData");
|
||
index = m_pImage->m_bootObject->GetIndexByName(ENTRYLOADER,loaderDataName);
|
||
if (index==-1)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeNewIDBlockData-->Get LoaderData Entry failed"));
|
||
}
|
||
delete []loaderCodeBuffer;
|
||
return -4;
|
||
}
|
||
PBYTE loaderDataBuffer;
|
||
loaderDataBuffer = new BYTE[m_dwLoaderDataSize];
|
||
memset(loaderDataBuffer,0,m_dwLoaderDataSize);
|
||
if ( !m_pImage->m_bootObject->GetEntryData(ENTRYLOADER,index,loaderDataBuffer) )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeNewIDBlockData-->Get LoaderData Data failed"));
|
||
}
|
||
delete []loaderDataBuffer;
|
||
delete []loaderCodeBuffer;
|
||
return -5;
|
||
}
|
||
|
||
tchar loaderHeadName[]=_T("FlashHead");
|
||
index = m_pImage->m_bootObject->GetIndexByName(ENTRYLOADER,loaderHeadName);
|
||
if (index==-1)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeNewIDBlockData-->Get LoaderHead Entry failed"));
|
||
}
|
||
delete []loaderDataBuffer;
|
||
delete []loaderCodeBuffer;
|
||
return -6;
|
||
}
|
||
PBYTE loaderHeadBuffer;
|
||
loaderHeadBuffer = new BYTE[m_dwLoaderHeadSize];
|
||
memset(loaderHeadBuffer,0,m_dwLoaderHeadSize);
|
||
if ( !m_pImage->m_bootObject->GetEntryData(ENTRYLOADER,index,loaderHeadBuffer) )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeNewIDBlockData-->Get LoaderHead Data failed"));
|
||
}
|
||
delete []loaderDataBuffer;
|
||
delete []loaderCodeBuffer;
|
||
delete []loaderHeadBuffer;
|
||
return -7;
|
||
}
|
||
|
||
if (m_pImage->m_bootObject->Rc4DisableFlag)
|
||
{//close rc4 encryption
|
||
for (i=0;i<m_dwLoaderHeadSize/SECTOR_SIZE;i++)
|
||
{
|
||
P_RC4(loaderHeadBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
|
||
}
|
||
for (i=0;i<m_dwLoaderDataSize/SECTOR_SIZE;i++)
|
||
{
|
||
P_RC4(loaderDataBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
|
||
}
|
||
for (i=0;i<m_dwLoaderSize/SECTOR_SIZE;i++)
|
||
{
|
||
P_RC4(loaderCodeBuffer+SECTOR_SIZE*i,SECTOR_SIZE);
|
||
}
|
||
}
|
||
memcpy(lpIDBlock, loaderHeadBuffer, m_dwLoaderHeadSize);
|
||
memcpy(lpIDBlock+SECTOR_SIZE*m_usFlashHeadSec, loaderDataBuffer, m_dwLoaderDataSize);
|
||
memcpy(lpIDBlock+SECTOR_SIZE*(m_usFlashHeadSec+m_usFlashDataSec), loaderCodeBuffer, m_dwLoaderSize);
|
||
|
||
|
||
delete []loaderDataBuffer;
|
||
delete []loaderCodeBuffer;
|
||
delete []loaderHeadBuffer;
|
||
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:MakeNewIDBlockData out"));
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
bool CRKAndroidDevice::MakeSpareData(PBYTE lpIDBlock,DWORD dwSectorNum,PBYTE lpSpareBuffer)
|
||
{
|
||
int i = 0;
|
||
BYTE bchOutBuf[512+3+13];
|
||
BYTE bchInBuf[512+3];
|
||
|
||
for (i=0; i<dwSectorNum; i++)
|
||
{
|
||
memcpy(bchInBuf, lpIDBlock+512*i, 512);
|
||
bchInBuf[514] = ((i==0) ? 'i' : 0xff);
|
||
bchInBuf[512] = 0xff;
|
||
bchInBuf[513] = 0xff;
|
||
//<2F><>bchInBuf<75><66><EFBFBD><EFBFBD>BCH<43><48><EFBFBD>루<EFBFBD><EBA3A8><EFBFBD><EFBFBD>13<31><33><EFBFBD>ֽڵı<DAB5><C4B1>룩<EFBFBD><EBA3A9><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>bchOutBuf(528 Bytes)
|
||
//<2F><>bchInBuf(515 Bytes)<29><>BCH<43><48><EFBFBD><EFBFBD>(13 Bytes)<29><><EFBFBD><EFBFBD>
|
||
bch_encode(bchInBuf, bchOutBuf);
|
||
memcpy(lpSpareBuffer+i*16+3, bchOutBuf+515, 13);
|
||
}
|
||
lpSpareBuffer[2] = 'i';
|
||
return true;
|
||
}
|
||
|
||
int CRKAndroidDevice::WriteIDBlock(PBYTE lpIDBlock,DWORD dwSectorNum,bool bErase)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:WriteIDBlock in"));
|
||
}
|
||
(void)bErase;
|
||
//STRUCT_END_WRITE_SECTOR end_write_sector_data;
|
||
//BYTE writeBuf[16*1024];
|
||
UINT uiOffset,uiTotal,uiBegin;
|
||
//UINT uiBufferSize=16*1024;
|
||
int iRet,i;
|
||
uiTotal = dwSectorNum*SECTOR_SIZE;
|
||
uiOffset = 0;
|
||
uiBegin = 0;
|
||
for(i=0;i<=4;i++)
|
||
{
|
||
iRet = m_pComm->RKU_WriteLBALoader(64+i*1024,dwSectorNum,lpIDBlock);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
m_pLog->Record(_T("ERROR:WriteIDBlock-->RKU_WriteLBA failed!"));
|
||
return -1;
|
||
}
|
||
}
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:WriteIDBlock out"));
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int CRKAndroidDevice::
|
||
PrepareIDB()
|
||
{
|
||
int i;
|
||
generate_gf();
|
||
gen_poly();
|
||
string strInfo="";
|
||
char szTmp[32];
|
||
bool bFirstCS=false;
|
||
for(i=0; i<8; i++)
|
||
{
|
||
if( m_flashInfo.bFlashCS&(1<<i) )
|
||
{
|
||
if (i==0)
|
||
{
|
||
bFirstCS = true;
|
||
}
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:CS(%d)\t\t(%dMB)\t\t(%s)"),i+1,m_flashInfo.uiFlashSize,m_flashInfo.szManufacturerName);
|
||
}
|
||
}
|
||
}
|
||
if (!bFirstCS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->No Found 1st Flash CS"));
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
if ( !BuildBlockStateMap(0) )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->BuildBlockStateMap failed"));
|
||
}
|
||
return -2;
|
||
}
|
||
|
||
FindAllIDB();
|
||
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->IDblock count=%d."),m_oldIDBCounts);
|
||
}
|
||
|
||
|
||
|
||
memset(m_backupBuffer,0,SECTOR_SIZE);
|
||
|
||
if (m_oldIDBCounts>0)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
strInfo = "";
|
||
for (i=0;i<m_oldIDBCounts;i++)
|
||
{
|
||
sprintf(szTmp,"%d ",m_idBlockOffset[i]);
|
||
strInfo += szTmp;
|
||
}
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->IDblock offset=%s."),strInfo.c_str());
|
||
}
|
||
BYTE buffer[4*SECTOR_SIZE];
|
||
PRKANDROID_IDB_SEC3 pSec;
|
||
PRKANDROID_IDB_SEC2 pSec2;
|
||
pSec2 = (PRKANDROID_IDB_SEC2)(buffer+2*SECTOR_SIZE);
|
||
pSec = (PRKANDROID_IDB_SEC3)(buffer+3*SECTOR_SIZE);
|
||
|
||
if (!GetWriteBackData(m_oldIDBCounts,buffer))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->GetWriteBackData failed"));
|
||
}
|
||
return -3;
|
||
}
|
||
P_RC4((PBYTE)pSec2,SECTOR_SIZE);
|
||
P_RC4((PBYTE)pSec,SECTOR_SIZE);
|
||
IsExistSector3Crc(pSec2);
|
||
|
||
m_usWriteBackCrc = CRC_16((PBYTE)pSec,SECTOR_SIZE);
|
||
if (m_bExistSector3Crc)
|
||
{
|
||
m_usWriteBackCustomDataOffset = pSec2->usSec3CustomDataOffset;
|
||
m_usWriteBackCustomDataSize = pSec2->usSec3CustomDataSize;
|
||
if (m_usSector3Crc!=m_usWriteBackCrc)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->Check sector3 crc failed"));
|
||
}
|
||
}
|
||
}
|
||
memcpy(m_backupBuffer,pSec,SECTOR_SIZE);
|
||
}
|
||
else
|
||
{
|
||
FindBackupBuffer();
|
||
}
|
||
|
||
if (m_oldIDBCounts>0)
|
||
{
|
||
if ( !GetOldSectorData() )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->GetOldSectorData failed"));
|
||
}
|
||
return -4;
|
||
}
|
||
}
|
||
if ( !CalcIDBCount() )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->CalcIDBCount failed"));
|
||
}
|
||
return -5;
|
||
}
|
||
if ( !ReserveIDBlock() )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->ReserveIDBlock failed"));
|
||
}
|
||
return -6;
|
||
}
|
||
if (m_pLog)
|
||
{
|
||
strInfo = "";
|
||
for (i=0;i<5;i++)
|
||
{
|
||
sprintf(szTmp,"%d ",m_idBlockOffset[i]);
|
||
strInfo += szTmp;
|
||
}
|
||
m_pLog->Record(_T("ERROR:PrepareIDB-->New IDblock offset=%s."),strInfo.c_str());
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int CRKAndroidDevice::DownloadIDBlock()
|
||
{
|
||
DWORD dwSectorNum;
|
||
dwSectorNum = m_flashInfo.uiSecNumPerIDB;
|
||
|
||
PBYTE pIDBData=NULL;
|
||
pIDBData = new BYTE[dwSectorNum*SECTOR_SIZE];
|
||
if (!pIDBData)
|
||
return -1;
|
||
|
||
int iRet=0;
|
||
memset(pIDBData,0,dwSectorNum*SECTOR_SIZE);
|
||
|
||
if (m_pImage->m_bootObject->IsNewIDBFlag())
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:DownloadIDBlock-->IsNewIDBFlag is true"),iRet);
|
||
}
|
||
iRet = MakeNewIDBlockData(pIDBData);
|
||
}
|
||
else {
|
||
iRet = MakeIDBlockData(pIDBData);
|
||
}
|
||
if ( iRet!=0 )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadIDBlock-->MakeIDBlockData failed,RetCode(%d)"),iRet);
|
||
}
|
||
return -2;
|
||
}
|
||
|
||
iRet = WriteIDBlock(pIDBData,dwSectorNum,false);
|
||
delete []pIDBData;
|
||
if (iRet==0)
|
||
{
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadIDBlock-->WriteIDBlock failed,RetCode(%d)"),iRet);
|
||
}
|
||
//BufferWriteBack();
|
||
return -3;
|
||
}
|
||
|
||
}
|
||
int CRKAndroidDevice::DownloadImage()
|
||
{
|
||
long long dwFwOffset;
|
||
bool bRet;
|
||
dwFwOffset = m_pImage->FWOffset;
|
||
STRUCT_RKIMAGE_HDR rkImageHead;
|
||
STRUCT_RKIMAGE_ITEM *pDownloadItem;
|
||
u_int8 headerData[64*1024];
|
||
u_int8* pHeaderData=headerData;
|
||
int iHeadSize,iHeadMetaSize;
|
||
iHeadSize = sizeof(STRUCT_RKIMAGE_HDR);
|
||
char szPrompt[100];
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback(0.1,5);
|
||
bRet = m_pImage->GetData(dwFwOffset,iHeadSize,(PBYTE)&rkImageHead);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->GetData failed"));
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
if ((rkImageHead.manufacturer[56]==0x55)&&(rkImageHead.manufacturer[57]==0x66))
|
||
{
|
||
u_int16 *pItemRemain;
|
||
pItemRemain = (u_int16 *)(&rkImageHead.manufacturer[58]);
|
||
rkImageHead.item_count += *pItemRemain;
|
||
}
|
||
iHeadMetaSize = iHeadSize = sizeof(STRUCT_RKIMAGE_HDR)-sizeof(STRUCT_RKIMAGE_ITEM)*MAX_PACKAGE_FILES;
|
||
iHeadSize += rkImageHead.item_count*sizeof(STRUCT_RKIMAGE_ITEM);
|
||
iHeadSize = CALC_UNIT(iHeadSize, RK_PAGE_SIZE)*RK_PAGE_SIZE;
|
||
|
||
bRet = m_pImage->GetData(dwFwOffset,iHeadSize,(u_int8*)pHeaderData);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record("ERROR:DownloadImage-->GetData for header failed");
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
printf("DownloadImage rkImageHead.item_count=%d \n", rkImageHead.item_count);
|
||
if ( rkImageHead.item_count<=0 )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->No Found item"));
|
||
}
|
||
return -2;
|
||
}
|
||
|
||
|
||
m_dwBackupOffset = 0xFFFFFFFF;
|
||
int i;
|
||
bool bFound=false,bFoundSystem=false,bFoundUserData=false;
|
||
int iParamPos=-1;
|
||
long long uiTotalSize=0;
|
||
long long ulItemSize;
|
||
UINT uiSparseFlag = 0;
|
||
for ( i=0;i<rkImageHead.item_count;i++ )
|
||
{
|
||
pDownloadItem = (STRUCT_RKIMAGE_ITEM *)(pHeaderData+iHeadMetaSize+i*sizeof(STRUCT_RKIMAGE_ITEM));
|
||
if ( pDownloadItem->flash_offset!=0xFFFFFFFF )
|
||
{
|
||
if ( strcmp(pDownloadItem->name,PARTNAME_PARAMETER)==0)
|
||
{
|
||
bFound = true;
|
||
iParamPos = i;
|
||
}
|
||
else
|
||
{
|
||
if (strcmp(pDownloadItem->name,PARTNAME_SYSTEM)==0)
|
||
{
|
||
bFoundSystem = true;
|
||
}
|
||
if (strcmp(pDownloadItem->name,PARTNAME_USERDATA)==0)
|
||
{
|
||
bFoundUserData = true;
|
||
}
|
||
if (strcmp(pDownloadItem->name,PARTNAME_BACKUP)==0)
|
||
{
|
||
m_dwBackupOffset = pDownloadItem->flash_offset;
|
||
}
|
||
if (pDownloadItem->file[55]=='H')
|
||
{
|
||
ulItemSize = *((DWORD *)(&pDownloadItem->file[56]));
|
||
ulItemSize <<= 32;
|
||
ulItemSize += pDownloadItem->size;
|
||
}
|
||
if (IsSparseImage(*pDownloadItem))
|
||
{
|
||
uiSparseFlag += (1<<i);
|
||
ulItemSize = GetSparseImageSize(*pDownloadItem);
|
||
if (ulItemSize==(long long)-1)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->get sparse size failed,file=%s"),pDownloadItem->name);
|
||
}
|
||
return -14;
|
||
}
|
||
}
|
||
else
|
||
ulItemSize = pDownloadItem->size;
|
||
uiTotalSize += ulItemSize;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
if ( !bFound )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->No Found Parameter file"));
|
||
}
|
||
return -3;
|
||
}
|
||
|
||
pDownloadItem = (STRUCT_RKIMAGE_ITEM *)(pHeaderData+iHeadMetaSize+iParamPos*sizeof(STRUCT_RKIMAGE_ITEM));
|
||
if (!MakeParamFileBuffer(*pDownloadItem))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->MakeParamFileBuffer failed"));
|
||
}
|
||
return -12;
|
||
}
|
||
|
||
GptFlag = GetParameterGptFlag(*pDownloadItem);
|
||
bGptFlag = GptFlag;
|
||
if (!GptFlag)
|
||
{
|
||
if (!CheckParamPartSize(pHeaderData+iHeadMetaSize,iParamPos,rkImageHead.item_count))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->CheckParamPartSize failed"));
|
||
}
|
||
return -13;
|
||
}
|
||
uiTotalSize += (8*m_uiParamFileSize);
|
||
}
|
||
else
|
||
uiTotalSize += (SECTOR_SIZE*67);
|
||
|
||
|
||
m_uiLBATimes = 1;
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback(0.4,60);
|
||
long long uiCurrentByte=0;
|
||
for ( i=0;i<rkImageHead.item_count;i++ )
|
||
{
|
||
pDownloadItem = (STRUCT_RKIMAGE_ITEM *)(pHeaderData+iHeadMetaSize+i*sizeof(STRUCT_RKIMAGE_ITEM));
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback((double)uiCurrentByte/(double)uiTotalSize,0);
|
||
if ( pDownloadItem->flash_offset==0xFFFFFFFF )
|
||
{
|
||
continue;
|
||
}
|
||
if (i==iParamPos)
|
||
{
|
||
if (m_pCallback)
|
||
{
|
||
sprintf(szPrompt,"%s writing... \n",pDownloadItem->name);
|
||
m_pCallback(szPrompt);
|
||
}
|
||
if (GptFlag)
|
||
{
|
||
bRet = RKA_Gpt_Download(*pDownloadItem,uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->RKA_Gpt_Download failed"));
|
||
m_pCallback("ERROR:DownloadImage-->RKA_Gpt_Download failed \n");
|
||
}
|
||
return -4;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bRet = RKA_Param_Download(*pDownloadItem,uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:DownloadImage-->RKA_Param_Download failed"));
|
||
m_pCallback("ERROR:DownloadImage-->RKA_Param_Download failed \n");
|
||
}
|
||
// if(m_pCallback)
|
||
// {
|
||
// sprintf(szPrompt,"%s writing... failed",rkImageHead.item[i].name);
|
||
// m_pCallback(szPrompt);
|
||
// }
|
||
return -4;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (pDownloadItem->file[55]=='H')
|
||
{
|
||
ulItemSize = *((DWORD *)(&pDownloadItem->file[56]));
|
||
ulItemSize <<= 32;
|
||
ulItemSize += pDownloadItem->size;
|
||
}
|
||
else
|
||
ulItemSize = pDownloadItem->size;
|
||
|
||
if (ulItemSize>0)
|
||
{
|
||
if (m_pCallback)
|
||
{
|
||
sprintf(szPrompt,"%s writing... \n",pDownloadItem->name);
|
||
m_pCallback(szPrompt);
|
||
}
|
||
if (uiSparseFlag & (1<<i))
|
||
{
|
||
bRet = RKA_SparseFile_Download(*pDownloadItem,uiCurrentByte,uiTotalSize);
|
||
}
|
||
else
|
||
bRet = RKA_File_Download(*pDownloadItem,uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->RKA_File_Download failed(%s)"),pDownloadItem->name);
|
||
}
|
||
m_pCallback("ERROR:DownloadImage-->RKA_File_Download failed(%s) \n",pDownloadItem->name);
|
||
return -5;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
m_pComm->RKU_ReopenLBAHandle();
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback(1,0);
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback(0.4,60);
|
||
uiCurrentByte = 0;
|
||
for ( i=0;i<rkImageHead.item_count;i++ )
|
||
{
|
||
pDownloadItem = (STRUCT_RKIMAGE_ITEM *)(pHeaderData+iHeadMetaSize+i*sizeof(STRUCT_RKIMAGE_ITEM));
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback((double)uiCurrentByte/(double)uiTotalSize,0);
|
||
if ( pDownloadItem->flash_offset==0xFFFFFFFF )
|
||
{
|
||
continue;
|
||
}
|
||
if (i==iParamPos)
|
||
{
|
||
if (m_pCallback)
|
||
{
|
||
sprintf(szPrompt,"%s checking... \n",pDownloadItem->name);
|
||
m_pCallback(szPrompt);
|
||
}
|
||
if (GptFlag)
|
||
{
|
||
bRet = RKA_Gpt_Check(*pDownloadItem,uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->RKA_Gpt_Check failed"));
|
||
}
|
||
m_pCallback("ERROR:DownloadImage-->RKA_Gpt_Check failed \n");
|
||
return -6;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bRet = RKA_Param_Check(*pDownloadItem,uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->RKA_Param_Check failed"));
|
||
}
|
||
m_pCallback("ERROR:DownloadImage-->RKA_Param_Check failed \n");
|
||
return -6;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (pDownloadItem->file[55]=='H')
|
||
{
|
||
ulItemSize = *((DWORD *)(&pDownloadItem->file[56]));
|
||
ulItemSize <<= 32;
|
||
ulItemSize += pDownloadItem->size;
|
||
}
|
||
else
|
||
ulItemSize = pDownloadItem->size;
|
||
if (ulItemSize>0)
|
||
{
|
||
if (m_pCallback)
|
||
{
|
||
sprintf(szPrompt,"%s checking... \n",pDownloadItem->name);
|
||
m_pCallback(szPrompt);
|
||
}
|
||
if (uiSparseFlag & (1<<i))
|
||
{
|
||
bRet = RKA_SparseFile_Check(*pDownloadItem,uiCurrentByte,uiTotalSize);
|
||
}
|
||
else
|
||
bRet = RKA_File_Check(*pDownloadItem,uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:DownloadImage-->RKA_File_Check failed(%s)"),pDownloadItem->name);
|
||
}
|
||
m_pCallback("ERROR:DownloadImage-->RKA_File_Check failed(%s) \n",pDownloadItem->name);
|
||
return -7;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback(1,0);
|
||
return 0;
|
||
}
|
||
bool CRKAndroidDevice::write_partition_upgrade_flag(DWORD dwOffset,BYTE *pMd5,UINT uiFlag)
|
||
{
|
||
BYTE flagSector[SECTOR_SIZE];
|
||
int iRet;
|
||
memset(flagSector,0,SECTOR_SIZE);
|
||
memcpy(flagSector,pMd5,32);
|
||
memcpy(flagSector+32,(BYTE *)(&uiFlag),4);
|
||
iRet = m_pComm->RKU_WriteLBA(dwOffset,1,flagSector);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record("ERROR:write_partition_upgrade_flag-->RKU_WriteLBA failed,err=%d",iRet);
|
||
}
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::read_partition_upgrade_flag(DWORD dwOffset,BYTE *pMd5,UINT *uiFlag)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record("INFO:read_partition_upgrade_flag in");
|
||
}
|
||
BYTE flagSector[SECTOR_SIZE];
|
||
int iRet;
|
||
iRet = m_pComm->RKU_ReadLBA(dwOffset,1,flagSector);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record("ERROR:read_partition_upgrade_flag-->RKU_ReadLBA failed,err=%d",iRet);
|
||
}
|
||
return false;
|
||
}
|
||
memcpy(pMd5,flagSector,32);
|
||
(*uiFlag) = *((UINT *)(flagSector+32));
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record("INFO:read_partition_upgrade_flag out,flag=0x%x",*uiFlag);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
int CRKAndroidDevice::UpgradePartition()
|
||
{
|
||
#if 0
|
||
long long dwFwOffset;
|
||
bool bRet,bSameFw=false;
|
||
BYTE localMd5[32];
|
||
BYTE *fwMd5,*fwSignMd5;
|
||
UINT uiFlag;
|
||
DWORD dwFlagSector=0;
|
||
dwFwOffset = m_pImage->FWOffset;
|
||
STRUCT_RKIMAGE_HDR rkImageHead;
|
||
vector<int> vecUpgradePartition;
|
||
vecUpgradePartition.clear();
|
||
char szPrompt[100];
|
||
int iHeadSize;
|
||
iHeadSize = sizeof(STRUCT_RKIMAGE_HDR);
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback(0.1,5);
|
||
|
||
bRet = m_pImage->GetData(dwFwOffset,iHeadSize,(PBYTE)&rkImageHead);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:UpgradePartition-->GetData failed"));
|
||
}
|
||
return -1;
|
||
}
|
||
if ( rkImageHead.item_count<=0 )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:UpgradePartition-->No Found item"));
|
||
}
|
||
return -2;
|
||
}
|
||
|
||
m_dwBackupOffset = 0xFFFFFFFF;
|
||
int i;
|
||
vector<int>::iterator iter;
|
||
bool bFound=false,bFoundSystem=false,bFoundUserData=false;
|
||
int iParamPos=-1;
|
||
long long uiTotalSize=0;
|
||
long long ulItemSize;
|
||
for ( i=0;i<rkImageHead.item_count;i++ )
|
||
{
|
||
if ( rkImageHead.item[i].flash_offset!=0xFFFFFFFF )
|
||
{
|
||
for (iter=vecUpgradePartition.begin();iter!=vecUpgradePartition.end();iter++)
|
||
{
|
||
if (rkImageHead.item[*iter].flash_offset>rkImageHead.item[i].flash_offset)
|
||
{
|
||
iter = vecUpgradePartition.insert(iter,i);
|
||
break;
|
||
}
|
||
}
|
||
if (iter==vecUpgradePartition.end())
|
||
{
|
||
vecUpgradePartition.push_back(i);
|
||
}
|
||
if ( strcmp(rkImageHead.item[i].name,PARTNAME_PARAMETER)==0)
|
||
{
|
||
bFound = true;
|
||
iParamPos = i;
|
||
}
|
||
else
|
||
{
|
||
if (strcmp(rkImageHead.item[i].name,PARTNAME_SYSTEM)==0)
|
||
{
|
||
bFoundSystem = true;
|
||
}
|
||
if (strcmp(rkImageHead.item[i].name,PARTNAME_MISC)==0)
|
||
{
|
||
dwFlagSector = rkImageHead.item[i].flash_offset + rkImageHead.item[i].part_size -4;
|
||
}
|
||
if (strcmp(rkImageHead.item[i].name,PARTNAME_USERDATA)==0)
|
||
{
|
||
bFoundUserData = true;
|
||
}
|
||
if (strcmp(rkImageHead.item[i].name,PARTNAME_BACKUP)==0)
|
||
{
|
||
m_dwBackupOffset = rkImageHead.item[i].flash_offset;
|
||
}
|
||
if (rkImageHead.item[i].file[55]=='H')
|
||
{
|
||
ulItemSize = *((DWORD *)(&rkImageHead.item[i].file[56]));
|
||
ulItemSize <<= 32;
|
||
ulItemSize += rkImageHead.item[i].size;
|
||
}
|
||
else
|
||
ulItemSize = rkImageHead.item[i].size;
|
||
uiTotalSize += ulItemSize;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
if ( !bFound )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:UpgradePartition-->No Found Parameter file"));
|
||
}
|
||
return -3;
|
||
}
|
||
|
||
if (!MakeParamFileBuffer(rkImageHead.item[iParamPos]))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:UpgradePartition-->MakeParamFileBuffer failed"));
|
||
}
|
||
return -12;
|
||
}
|
||
|
||
if (!CheckParamPartSize(rkImageHead,iParamPos))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:UpgradePartition-->CheckParamPartSize failed"));
|
||
}
|
||
return -13;
|
||
}
|
||
uiTotalSize += (8*m_uiParamFileSize);//<2F><><EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>Ҫ<EFBFBD>Ĵ<EFBFBD>С
|
||
m_uiLBATimes = 1;
|
||
m_pImage->GetMd5Data(fwMd5,fwSignMd5);
|
||
if (dwFlagSector!=0)
|
||
{
|
||
if (read_partition_upgrade_flag(dwFlagSector,localMd5,&uiFlag))
|
||
{
|
||
if (memcmp(localMd5,fwMd5,32)==0)
|
||
bSameFw = true;
|
||
}
|
||
}
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback(0.8,90);
|
||
long long uiCurrentByte=0;
|
||
for ( i=0;i<vecUpgradePartition.size();i++ )
|
||
{
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback((double)uiCurrentByte/(double)uiTotalSize,0);
|
||
if (vecUpgradePartition[i]==iParamPos)
|
||
{
|
||
if ((bSameFw)&&(uiFlag>=rkImageHead.item[vecUpgradePartition[i]].flash_offset))
|
||
{
|
||
uiCurrentByte += (8*m_uiParamFileSize);
|
||
continue;
|
||
}
|
||
if (m_pCallback)
|
||
{
|
||
sprintf(szPrompt,"%s writing...\n",rkImageHead.item[vecUpgradePartition[i]].name);
|
||
m_pCallback(szPrompt);
|
||
}
|
||
bRet = RKA_Param_Download(rkImageHead.item[vecUpgradePartition[i]],uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:UpgradePartition-->RKA_Param_Download failed"));
|
||
}
|
||
return -4;
|
||
}
|
||
m_pComm->RKU_ReopenLBAHandle();
|
||
if (m_pCallback)
|
||
{
|
||
sprintf(szPrompt,"%s checking...\n",rkImageHead.item[vecUpgradePartition[i]].name);
|
||
m_pCallback(szPrompt);
|
||
}
|
||
uiCurrentByte -= (8*m_uiParamFileSize);
|
||
bRet = RKA_Param_Check(rkImageHead.item[vecUpgradePartition[i]],uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:UpgradePartition-->RKA_Param_Check failed"));
|
||
}
|
||
return -6;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
if (rkImageHead.item[vecUpgradePartition[i]].file[55]=='H')
|
||
{
|
||
ulItemSize = *((DWORD *)(&rkImageHead.item[vecUpgradePartition[i]].file[56]));
|
||
ulItemSize <<= 32;
|
||
ulItemSize += rkImageHead.item[vecUpgradePartition[i]].size;
|
||
}
|
||
else
|
||
ulItemSize = rkImageHead.item[vecUpgradePartition[i]].size;
|
||
if ((bSameFw)&&(uiFlag>=rkImageHead.item[vecUpgradePartition[i]].flash_offset))
|
||
{
|
||
uiCurrentByte += ulItemSize;
|
||
continue;
|
||
}
|
||
|
||
if (ulItemSize>0)
|
||
{
|
||
if (m_pCallback)
|
||
{
|
||
sprintf(szPrompt,"%s writing...\n",rkImageHead.item[vecUpgradePartition[i]].name);
|
||
m_pCallback(szPrompt);
|
||
}
|
||
bRet = RKA_File_Download(rkImageHead.item[vecUpgradePartition[i]],uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:UpgradePartition-->RKA_File_Download failed(%s)"),rkImageHead.item[vecUpgradePartition[i]].name);
|
||
}
|
||
return -5;
|
||
}
|
||
m_pComm->RKU_ReopenLBAHandle();
|
||
if (m_pCallback)
|
||
{
|
||
sprintf(szPrompt,"%s checking...\n",rkImageHead.item[vecUpgradePartition[i]].name);
|
||
m_pCallback(szPrompt);
|
||
}
|
||
uiCurrentByte -= ulItemSize;
|
||
bRet = RKA_File_Check(rkImageHead.item[vecUpgradePartition[i]],uiCurrentByte,uiTotalSize);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:UpgradePartition-->RKA_File_Check failed(%s)"),rkImageHead.item[vecUpgradePartition[i]].name);
|
||
}
|
||
return -7;
|
||
}
|
||
}
|
||
else
|
||
continue;
|
||
}
|
||
if (dwFlagSector!=0)
|
||
{
|
||
write_partition_upgrade_flag(dwFlagSector,fwMd5,rkImageHead.item[vecUpgradePartition[i]].flash_offset);
|
||
}
|
||
}
|
||
if (m_pProcessCallback)
|
||
m_pProcessCallback(1,0);
|
||
return 0;
|
||
#else
|
||
return 0;
|
||
#endif
|
||
}
|
||
int CRKAndroidDevice::EraseIDB()
|
||
{
|
||
DWORD dwEraseCounts;
|
||
if ( m_oldIDBCounts>0 )
|
||
{
|
||
dwEraseCounts = m_oldSec1->usSysReservedBlock;
|
||
}
|
||
else
|
||
{
|
||
dwEraseCounts = IDBLOCK_TOP;
|
||
}
|
||
if (m_bEmmc)
|
||
{
|
||
if(EraseEmmcBlock(0,0,dwEraseCounts)!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:EraseIDB-->EraseEmmcBlock failed"));
|
||
}
|
||
return -1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( !EraseMutilBlock(0,0,dwEraseCounts,false) )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:EraseIDB-->EraseMutilBlock failed"));
|
||
}
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
int CRKAndroidDevice::EraseAllBlocks()
|
||
{
|
||
int i;
|
||
UINT uiBlockCount;
|
||
int iRet=ERR_SUCCESS,iErasePos=0,iEraseBlockNum=0,iEraseTimes=0,iCSIndex=0;
|
||
BYTE bCSCount=0;
|
||
for (i=0;i<8;i++)
|
||
{
|
||
if ( m_flashInfo.bFlashCS & (1<<i) )
|
||
{
|
||
bCSCount++;
|
||
}
|
||
}
|
||
|
||
for (i=0;i<8;i++)
|
||
{
|
||
if ( m_flashInfo.bFlashCS & (1<<i) )
|
||
{
|
||
uiBlockCount = m_flashInfo.uiBlockNum;
|
||
iErasePos=0;iEraseTimes=0;
|
||
while (uiBlockCount>0)
|
||
{
|
||
iEraseBlockNum = (uiBlockCount<MAX_ERASE_BLOCKS)?uiBlockCount:MAX_ERASE_BLOCKS;
|
||
if (m_bEmmc)
|
||
{
|
||
iRet = EraseEmmcBlock(i,iErasePos,iEraseBlockNum);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:EraseAllBlocks-->EraseEmmcBlock failed,RetCode(%d)"),iRet);
|
||
}
|
||
return -1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
iRet = m_pComm->RKU_EraseBlock(i,iErasePos,iEraseBlockNum,ERASE_FORCE);
|
||
if ((iRet!=ERR_SUCCESS)&&(iRet!=ERR_FOUND_BAD_BLOCK))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)"),iRet);
|
||
}
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
iErasePos += iEraseBlockNum;
|
||
uiBlockCount -= iEraseBlockNum;
|
||
iEraseTimes++;
|
||
}
|
||
iCSIndex++;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
bool CRKAndroidDevice::BufferWriteBack()
|
||
{
|
||
FindAllIDB();
|
||
if (m_oldIDBCounts>0)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:BufferWriteBack-->Found IDB"));
|
||
}
|
||
return true;
|
||
}
|
||
if (m_usWriteBackCrc==0)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:BufferWriteBack-->Crc is zero"));
|
||
}
|
||
return true;
|
||
}
|
||
BYTE pWriteBackBuffer[2*SECTOR_SIZE];
|
||
|
||
char *pszTag = (char *)pWriteBackBuffer;
|
||
USHORT *pValue = (USHORT *)(pWriteBackBuffer+4);
|
||
|
||
memset(pWriteBackBuffer,0,2*SECTOR_SIZE);
|
||
|
||
|
||
strcpy(pszTag,"CRC");
|
||
*pValue = m_usWriteBackCrc;
|
||
pValue++;
|
||
*pValue = m_usWriteBackCustomDataOffset;
|
||
pValue++;
|
||
*pValue = m_usWriteBackCustomDataSize;
|
||
memcpy(pWriteBackBuffer+SECTOR_SIZE,m_backupBuffer,SECTOR_SIZE);
|
||
|
||
STRUCT_END_WRITE_SECTOR end_write_sector_data;
|
||
BYTE writeBuf[8*SECTOR_SIZE];
|
||
UINT uiOffset,uiTotal,uiWriteByte,uiCrc;
|
||
int iRet,i,nTryCount=3;
|
||
uiTotal = 2*SECTOR_SIZE;
|
||
uiCrc = CRC_32(pWriteBackBuffer,uiTotal);
|
||
end_write_sector_data.uiSize = uiTotal;
|
||
end_write_sector_data.uiCrc = uiCrc;
|
||
for(i=WBBUFFER_BOTTOM;i<WBBUFFER_TOP;i++)
|
||
end_write_sector_data.uiBlock[i] = i;
|
||
while (nTryCount>0)
|
||
{
|
||
uiOffset = 0;
|
||
uiTotal = 2 * SECTOR_SIZE;
|
||
while (uiTotal>0)
|
||
{
|
||
if (uiTotal>=2048)
|
||
uiWriteByte = 2048;
|
||
else
|
||
uiWriteByte = uiTotal;
|
||
|
||
memcpy(writeBuf+8,pWriteBackBuffer+uiOffset,uiWriteByte);
|
||
iRet = m_pComm->RKU_WriteLBA(64+uiOffset,uiWriteByte,writeBuf);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
m_pLog->Record(_T("ERROR:BufferWriteBack-->RKU_WriteSector failed!"));
|
||
return false;
|
||
}
|
||
uiOffset += uiWriteByte;
|
||
uiTotal -= uiWriteByte;
|
||
}
|
||
//iRet = m_pComm->RKU_EndWriteSector((BYTE*)&end_write_sector_data);
|
||
if (iRet==ERR_SUCCESS)
|
||
break;
|
||
nTryCount--;
|
||
}
|
||
if (nTryCount<=0)
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::FindBackupBuffer()
|
||
{
|
||
int i,iRet;
|
||
bool bRet;
|
||
BYTE buffer[2*SECTOR_SIZE];
|
||
for (i=WBBUFFER_BOTTOM;i<WBBUFFER_TOP;i++)
|
||
{
|
||
memset(buffer,0,2*SECTOR_SIZE);
|
||
iRet = m_pComm->RKU_ReadSector(i*m_flashInfo.uiSectorPerBlock,2,buffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:FindBackupBuffer-->RKU_ReadSector failed,RetCode(%d)"),iRet);
|
||
}
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
PSTRUCT_RKANDROID_WBBUFFER pWriteBack;
|
||
pWriteBack = (PSTRUCT_RKANDROID_WBBUFFER)buffer;
|
||
char *pszCrcTag = (char *)buffer;
|
||
if (pWriteBack->dwTag==0x38324B52)
|
||
{
|
||
bRet = CheckCrc16(buffer,SECTOR_SIZE-2,pWriteBack->usCrc);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:FindBackupBuffer-->Check Crc Failed"));
|
||
}
|
||
// continue;
|
||
}
|
||
PRKANDROID_IDB_SEC3 pSec = (PRKANDROID_IDB_SEC3)m_backupBuffer;
|
||
pSec->usSNSize = pWriteBack->usSnSize;
|
||
memcpy(pSec->sn,pWriteBack->btSnData,RKDEVICE_SN_LEN);
|
||
memset(pSec->reserved,0,RKANDROID_SEC3_RESERVED_LEN);
|
||
memcpy(pSec->reserved+6,pWriteBack->btReserve,RKANDROID_SEC3_RESERVED_LEN-6);
|
||
pSec->imeiSize = pWriteBack->btImeiSize;
|
||
memcpy(pSec->imei,pWriteBack->btImeiData,RKDEVICE_IMEI_LEN);
|
||
pSec->uidSize = pWriteBack->btUidSize;
|
||
memcpy(pSec->uid,pWriteBack->btUidData,RKDEVICE_UID_LEN);
|
||
pSec->blueToothSize = pWriteBack->btBlueToothSize;
|
||
memcpy(pSec->blueToothAddr,pWriteBack->btBlueToothData,RKDEVICE_BT_LEN);
|
||
pSec->macSize = pWriteBack->btMacSize;
|
||
memcpy(pSec->macAddr,pWriteBack->btMacData,RKDEVICE_MAC_LEN);
|
||
m_usWriteBackCrc = CRC_16(m_backupBuffer,SECTOR_SIZE);
|
||
}
|
||
else if (strcmp(pszCrcTag,"CRC")==0)
|
||
{
|
||
m_usWriteBackCrc = *((USHORT *)(buffer+4));
|
||
m_usWriteBackCustomDataOffset = *((USHORT *)(buffer+6));
|
||
m_usWriteBackCustomDataSize = *((USHORT *)(buffer+8));
|
||
bRet = CheckCrc16(buffer+SECTOR_SIZE,SECTOR_SIZE,m_usWriteBackCrc);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:FindBackupBuffer-->Check Crc Failed"));
|
||
}
|
||
m_usWriteBackCrc = CRC_16(buffer+SECTOR_SIZE+SPARE_SIZE,SECTOR_SIZE);
|
||
// continue;
|
||
}
|
||
memcpy(m_backupBuffer,buffer+SECTOR_SIZE,SECTOR_SIZE);
|
||
}
|
||
else
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:FindBackupBuffer-->No Found Tag"));
|
||
}
|
||
continue;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
if ( i<WBBUFFER_TOP )
|
||
{
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
bool CRKAndroidDevice::RKA_File_Download(STRUCT_RKIMAGE_ITEM &entry,long long ¤tByte,long long totalByte)
|
||
{
|
||
UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet;
|
||
bool bRet;
|
||
UINT uiBufferSize=uiLBATransferSize;
|
||
long long uifileBufferSize;
|
||
long long ulEntryStartOffset;
|
||
DWORD dwFWOffset;
|
||
(void)totalByte;
|
||
|
||
m_pCallback("RKA_File_Download entry.name=%s \n", entry.name);
|
||
dwFWOffset = m_pImage->FWOffset;
|
||
if (entry.file[50]=='H')
|
||
{
|
||
ulEntryStartOffset = *((DWORD *)(&entry.file[51]));
|
||
ulEntryStartOffset <<= 32;
|
||
ulEntryStartOffset += entry.offset;
|
||
ulEntryStartOffset += m_pImage->FWOffset;
|
||
}
|
||
else
|
||
{
|
||
ulEntryStartOffset = m_pImage->FWOffset;
|
||
ulEntryStartOffset += entry.offset;
|
||
}
|
||
if (entry.file[55]=='H')
|
||
{
|
||
uifileBufferSize = *((DWORD *)(&entry.file[56]));
|
||
uifileBufferSize <<= 32;
|
||
uifileBufferSize += entry.size;
|
||
}
|
||
else
|
||
uifileBufferSize = entry.size;
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" INFO:Start to download %s,offset=0x%x,size=%llu"),entry.name,entry.flash_offset,uifileBufferSize);
|
||
}
|
||
|
||
BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
if (entry.flash_offset>m_dwBackupOffset)
|
||
{
|
||
byRWMethod = RWMETHOD_LBA;
|
||
}
|
||
|
||
PBYTE pBuffer=NULL;
|
||
pBuffer = new BYTE[uiBufferSize];
|
||
if (!pBuffer)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Download-->New memory failed"));
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool bUser=false;
|
||
// if (strcmp(entry.name,PARTNAME_MISC)==0)
|
||
// {
|
||
// currentByte += uifileBufferSize;
|
||
// return true;
|
||
// }
|
||
if (strcmp(entry.name,PARTNAME_USER)==0)
|
||
{
|
||
bUser = true;
|
||
}
|
||
|
||
UINT uiBegin,uiLen,uiWriteByte;
|
||
long long uiEntryOffset;
|
||
uiBegin = entry.flash_offset;
|
||
uiLen = 0;uiWriteByte = 0;uiEntryOffset=0;
|
||
while ( uifileBufferSize>0 )
|
||
{
|
||
memset(pBuffer,0,uiBufferSize);
|
||
if ( uifileBufferSize<uiBufferSize )
|
||
{
|
||
uiWriteByte = uifileBufferSize;
|
||
uiLen = ( (uiWriteByte%SECTOR_SIZE==0) ? (uiWriteByte/SECTOR_SIZE) : (uiWriteByte/SECTOR_SIZE+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiBufferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
bRet = m_pImage->GetData(dwFWOffset+entry.offset+uiEntryOffset,uiWriteByte,pBuffer);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Download-->GetFileData failed"));
|
||
}
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
if (bUser)
|
||
{
|
||
if ((pBuffer[0]==0xEB)&&(pBuffer[1]==0x58)&&(pBuffer[2]==0x90))
|
||
{//fat user image
|
||
iRet = m_pComm->RKU_TestDeviceReady((DWORD *)&m_uiUserSectors,NULL,TU_GETUSERSECTOR_SUBCODE);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Download-->Get user sectors failed,RetCode(%d)"),iRet);
|
||
}
|
||
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
if ((m_uiUserSectors==0)||(m_uiUserSectors==(DWORD)-1))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Download-->User size is wrong,value=0x%x"),m_uiUserSectors);
|
||
}
|
||
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
if (m_uiUserSectors<=uiBegin)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Download-->Available total is smaller than user offset"));
|
||
}
|
||
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
m_uiUserSectors -= uiBegin;
|
||
|
||
PBYTE pDbr,pCopyDbr;
|
||
pDbr = pBuffer;
|
||
pCopyDbr = pBuffer + SECTOR_SIZE*6;
|
||
if (*(UINT *)(pDbr+32)<m_uiUserSectors)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Download-->Original size is smaller than current user size"));
|
||
}
|
||
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
|
||
(*(UINT *)(pDbr+32)) = m_uiUserSectors;
|
||
(*(UINT *)(pCopyDbr+32)) = m_uiUserSectors;
|
||
}
|
||
|
||
bUser = false;
|
||
}
|
||
|
||
iRet = m_pComm->RKU_WriteLBA(uiBegin,uiLen,pBuffer,byRWMethod);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Download-->RKU_WriteLBA failed,Written(%d),RetCode(%d)"),uiEntryOffset,iRet);
|
||
}
|
||
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uifileBufferSize -= uiWriteByte;
|
||
uiEntryOffset += uiWriteByte;
|
||
uiBegin += uiLen;
|
||
currentByte += uiWriteByte;
|
||
|
||
}
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
m_pCallback("RKA_File_Download entry.name=%s DONE! \n", entry.name);
|
||
return true;
|
||
}
|
||
|
||
bool CRKAndroidDevice::RKA_File_Check(STRUCT_RKIMAGE_ITEM &entry,long long ¤tByte,long long totalByte)
|
||
{
|
||
UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet;
|
||
bool bRet;
|
||
UINT uiBufferSize=uiLBATransferSize;
|
||
long long uifileBufferSize;
|
||
long long ulEntryStartOffset;
|
||
DWORD dwFWOffset;
|
||
(void)totalByte;
|
||
m_pCallback("RKA_File_Check entry.name=%s \n", entry.name);
|
||
dwFWOffset = m_pImage->FWOffset;
|
||
if (entry.file[50]=='H')
|
||
{
|
||
ulEntryStartOffset = *((DWORD *)(&entry.file[51]));
|
||
ulEntryStartOffset <<= 32;
|
||
ulEntryStartOffset += entry.offset;
|
||
ulEntryStartOffset += m_pImage->FWOffset;
|
||
}
|
||
else
|
||
{
|
||
ulEntryStartOffset = m_pImage->FWOffset;
|
||
ulEntryStartOffset += entry.offset;
|
||
}
|
||
if (entry.file[55]=='H')
|
||
{
|
||
uifileBufferSize = *((DWORD *)(&entry.file[56]));
|
||
uifileBufferSize <<= 32;
|
||
uifileBufferSize += entry.size;
|
||
}
|
||
else
|
||
uifileBufferSize = entry.size;
|
||
|
||
BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
if (entry.flash_offset>m_dwBackupOffset)
|
||
{
|
||
byRWMethod = RWMETHOD_LBA;
|
||
}
|
||
|
||
PBYTE pBufferFromFile=NULL;
|
||
pBufferFromFile = new BYTE[uiBufferSize];
|
||
if (!pBufferFromFile)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Check-->New memory failed"));
|
||
}
|
||
return false;
|
||
}
|
||
PBYTE pBufferFromFlash=NULL;
|
||
pBufferFromFlash = new BYTE[uiBufferSize];
|
||
if (!pBufferFromFlash)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Check-->New memory failed"));
|
||
}
|
||
delete []pBufferFromFile;
|
||
return false;
|
||
}
|
||
bool bUser=false;
|
||
// if (strcmp(entry.name,PARTNAME_MISC)==0)
|
||
// {
|
||
// currentByte += uifileBufferSize;
|
||
// return true;
|
||
// }
|
||
if (strcmp(entry.name,PARTNAME_USER)==0)
|
||
{
|
||
bUser = true;
|
||
if ((entry.name[PART_NAME-2]=='N')&&(entry.name[PART_NAME-1]=='C'))
|
||
{//no check user
|
||
currentByte += uifileBufferSize;
|
||
return true;
|
||
}
|
||
}
|
||
|
||
UINT uiBegin,uiLen,uiWriteByte;
|
||
long long uiEntryOffset;
|
||
uiBegin = entry.flash_offset;
|
||
uiLen = 0;uiWriteByte = 0;uiEntryOffset=0;
|
||
while ( uifileBufferSize>0 )
|
||
{
|
||
if ( uifileBufferSize<uiBufferSize )
|
||
{
|
||
uiWriteByte = uifileBufferSize;
|
||
uiLen = ( (uiWriteByte%SECTOR_SIZE==0) ? (uiWriteByte/SECTOR_SIZE) : (uiWriteByte/SECTOR_SIZE+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiBufferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
|
||
|
||
memset(pBufferFromFile,0,uiBufferSize);
|
||
memset(pBufferFromFlash,0,uiBufferSize);
|
||
|
||
iRet = m_pComm->RKU_ReadLBA(uiBegin,uiLen,pBufferFromFlash,byRWMethod);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Check-->RKU_ReadLBA failed,Read(%d),RetCode(%d)"),uiEntryOffset,iRet);
|
||
}
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
bRet = m_pImage->GetData(dwFWOffset+entry.offset+uiEntryOffset,uiWriteByte,pBufferFromFile);
|
||
if ( !bRet )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Check-->GetFileData failed"));
|
||
}
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
if (bUser)
|
||
{
|
||
if ((pBufferFromFile[0]==0xEB)&&(pBufferFromFile[1]==0x58)&&(pBufferFromFile[2]==0x90))
|
||
{//fat user image
|
||
PBYTE pDbr,pCopyDbr;
|
||
pDbr = pBufferFromFile;
|
||
pCopyDbr = pBufferFromFile + SECTOR_SIZE*6;
|
||
|
||
(*(UINT *)(pDbr+32)) = m_uiUserSectors;
|
||
(*(UINT *)(pCopyDbr+32)) = m_uiUserSectors;
|
||
}
|
||
|
||
bUser = false;
|
||
}
|
||
|
||
if ( memcmp(pBufferFromFile,pBufferFromFlash,uiWriteByte)!=0 )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_File_Check-->Memcmp failed,Read(%d)"),uiEntryOffset);
|
||
tchar szDateTime[100];
|
||
tstring strFile;
|
||
time_t now;
|
||
struct tm timeNow;
|
||
time(&now);
|
||
localtime_r(&now,&timeNow);
|
||
_stprintf(szDateTime,_T("%02d-%02d-%02d"),timeNow.tm_hour,timeNow.tm_min,timeNow.tm_sec);
|
||
|
||
strFile = szDateTime;
|
||
strFile += _T("/tmp/file.bin");
|
||
m_pLog->SaveBuffer( strFile,pBufferFromFile,uiWriteByte );
|
||
|
||
strFile = szDateTime;
|
||
strFile += _T("/tmp/flash.bin");
|
||
m_pLog->SaveBuffer( strFile,pBufferFromFlash,uiWriteByte );
|
||
}
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
// if (uiBegin == entry.flash_offset)
|
||
// {
|
||
// tstring strFile;
|
||
// strFile = "/tmp/";
|
||
// strFile += entry.name;
|
||
// strFile += ".img";
|
||
// m_pLog->SaveBuffer( strFile,pBufferFromFlash,uiWriteByte );
|
||
// m_pLog->Record("%s=%x %x %x %x",entry.name,pBufferFromFlash[0],pBufferFromFlash[1],pBufferFromFlash[2],pBufferFromFlash[3]);
|
||
// }
|
||
|
||
currentByte += uiWriteByte;
|
||
uiEntryOffset += uiWriteByte;
|
||
uifileBufferSize -= uiWriteByte;
|
||
uiBegin += uiLen;
|
||
|
||
}
|
||
|
||
m_pCallback("RKA_File_Check entry.name=%s DONE! \n", entry.name);
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return true;
|
||
}
|
||
|
||
bool CRKAndroidDevice::RKA_Param_Download(STRUCT_RKIMAGE_ITEM &entry,long long ¤tByte,long long totalByte)
|
||
{//д5<D0B4>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||
UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet,i;
|
||
BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
(void)totalByte;
|
||
if (entry.flash_offset>m_dwBackupOffset)
|
||
{
|
||
byRWMethod = RWMETHOD_LBA;
|
||
}
|
||
|
||
UINT uiTransfer;
|
||
UINT uiStepSec=entry.part_size/8;
|
||
// if (m_pLog)
|
||
// {
|
||
// m_pLog->Record(_T("INFO:RKA_Param_Download-->step=%d"),uiStepSec);
|
||
// }
|
||
|
||
UINT uiLen,uiWriteByte,uiFileSize;
|
||
UINT uiBegin;
|
||
for ( i=0;i<8;i++ )
|
||
{
|
||
uiFileSize = m_uiParamFileSize;
|
||
uiBegin = entry.flash_offset+uiStepSec*i;
|
||
uiLen = 0;
|
||
uiWriteByte = 0;
|
||
uiTransfer = 0;
|
||
// if (m_pLog)
|
||
// {
|
||
// m_pLog->Record(_T("INFO:RKA_Param_Download-->no %d,offset=%d"),i+1,uiBegin);
|
||
// }
|
||
while (uiFileSize>0)
|
||
{
|
||
if ( uiFileSize<uiLBATransferSize )
|
||
{
|
||
uiWriteByte = uiFileSize;
|
||
uiLen = ( (uiWriteByte%512==0) ? (uiWriteByte/512) : (uiWriteByte/512+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiLBATransferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
iRet = m_pComm->RKU_WriteLBA(uiBegin,uiLen,m_paramBuffer+uiTransfer,byRWMethod);//ÿ<>ζ<EFBFBD>Ҫд32<33><32><EFBFBD><EFBFBD>,<2C><>page<67><65><EFBFBD><EFBFBD>
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Param_Download-->RKU_WriteLBA failed,Written(%d),RetCode(%d)"),uiTransfer,iRet);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
uiTransfer += uiWriteByte;
|
||
currentByte += uiWriteByte;
|
||
uiBegin += uiLen;
|
||
uiFileSize -= uiWriteByte;
|
||
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::RKA_Param_Check(STRUCT_RKIMAGE_ITEM &entry,long long ¤tByte,long long totalByte)
|
||
{
|
||
UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet,i;
|
||
UINT uiReadBufferSize=uiLBATransferSize;
|
||
BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
(void)totalByte;
|
||
if (entry.flash_offset>m_dwBackupOffset)
|
||
{
|
||
byRWMethod = RWMETHOD_LBA;
|
||
}
|
||
|
||
PBYTE pRead=NULL;
|
||
pRead = new BYTE[uiReadBufferSize];
|
||
if (!pRead)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Param_Check-->New ReadBuffer failed"));
|
||
}
|
||
return false;
|
||
}
|
||
|
||
UINT uiTransfer;
|
||
UINT uiStepSec=entry.part_size/8;
|
||
|
||
UINT uiLen,uiWriteByte,uiFileSize;
|
||
UINT uiBegin;
|
||
for ( i=0;i<8;i++ )
|
||
{
|
||
uiFileSize = m_uiParamFileSize;
|
||
uiBegin = entry.flash_offset+uiStepSec*i;
|
||
uiLen = 0;
|
||
uiWriteByte = 0;
|
||
uiTransfer = 0;
|
||
// if (m_pLog)
|
||
// {
|
||
// m_pLog->Record(_T("INFO:RKA_Param_Check-->no %d,offset=%d"),i+1,uiBegin);
|
||
// }
|
||
while (uiFileSize>0)
|
||
{
|
||
memset(pRead,0,uiReadBufferSize);
|
||
if ( uiFileSize<uiLBATransferSize )
|
||
{
|
||
uiWriteByte = uiFileSize;
|
||
uiLen = ( (uiWriteByte%512==0) ? (uiWriteByte/512) : (uiWriteByte/512+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiLBATransferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
iRet = m_pComm->RKU_ReadLBA(uiBegin,uiLen,pRead,byRWMethod);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Param_Check-->RKU_ReadLBA failed,Read(%d),RetCode(%d)"),uiTransfer,iRet);
|
||
}
|
||
delete []pRead;
|
||
return false;
|
||
}
|
||
if ( memcmp(pRead,m_paramBuffer+uiTransfer,uiWriteByte)!=0 )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Param_Check-->Memcmp failed,Read(%d)"),uiTransfer);
|
||
tchar szDateTime[100];
|
||
tstring strFile;
|
||
time_t now;
|
||
struct tm timeNow;
|
||
time(&now);
|
||
localtime_r(&now,&timeNow);
|
||
_stprintf(szDateTime,_T("%02d-%02d-%02d"),timeNow.tm_hour+1,timeNow.tm_min+1,timeNow.tm_sec+1);
|
||
|
||
strFile = szDateTime;
|
||
strFile += _T("/tmp/file.bin");
|
||
m_pLog->SaveBuffer( strFile,m_paramBuffer+uiTransfer,uiWriteByte );
|
||
|
||
strFile = szDateTime;
|
||
strFile += _T("/tmp/flash.bin");
|
||
m_pLog->SaveBuffer( strFile,pRead,uiWriteByte );
|
||
}
|
||
|
||
delete []pRead;
|
||
return false;
|
||
|
||
}
|
||
// if (m_pLog)
|
||
// {
|
||
// string strSrc,strDst;
|
||
// if (uiWriteByte>16)
|
||
// {
|
||
// m_pLog->PrintBuffer(strSrc,pRead,16);
|
||
// m_pLog->PrintBuffer(strDst,m_paramBuffer+uiTransfer,16);
|
||
// }
|
||
// else
|
||
// {
|
||
// m_pLog->PrintBuffer(strSrc,pRead,uiWriteByte);
|
||
// m_pLog->PrintBuffer(strDst,m_paramBuffer+uiTransfer,uiWriteByte);
|
||
// }
|
||
// m_pLog->Record("Read:%s",strSrc.c_str());
|
||
// m_pLog->Record("Compare:%s",strDst.c_str());
|
||
// }
|
||
uiTransfer += uiWriteByte;
|
||
currentByte += uiWriteByte;
|
||
uiBegin += uiLen;
|
||
uiFileSize -= uiWriteByte;
|
||
|
||
}
|
||
}
|
||
|
||
delete []pRead;
|
||
return true;
|
||
}
|
||
|
||
bool CRKAndroidDevice::RKA_Gpt_Download(STRUCT_RKIMAGE_ITEM &entry,long long ¤tByte,long long totalByte)
|
||
{
|
||
//UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
//UINT uiLBALoopLimit=(LBA_LOOP_SIZE)/uiLBATransferSize;
|
||
//UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet;
|
||
bool bRet;
|
||
PARAM_ITEM_VECTOR vecItems;
|
||
CONFIG_ITEM_VECTOR vecUuids;
|
||
//BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
BYTE *backup_gpt;
|
||
(void)entry; (void)totalByte;
|
||
if (!m_gptBuffer)
|
||
{
|
||
m_gptBuffer = new BYTE[SECTOR_SIZE*67];
|
||
if (!m_gptBuffer)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->new memory failed,err=%d)"),errno);
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
memset(m_gptBuffer,0,SECTOR_SIZE*67);
|
||
bRet = parse_parameter((char *)(m_paramBuffer+8),vecItems);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->parse_parameter failed)"));
|
||
}
|
||
return false;
|
||
}
|
||
bRet = get_uuid_from_parameter((char *)(m_paramBuffer+8),vecUuids);
|
||
backup_gpt = m_gptBuffer+34*SECTOR_SIZE;
|
||
create_gpt_buffer(m_gptBuffer,vecItems,vecUuids,m_flashInfo.uiFlashSize*2048);
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:RKA_Gpt_Download-->disk_sector=%u \n)"),m_flashInfo.uiFlashSize*2048);
|
||
}
|
||
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_paramBuffer, backup_gpt, m_flashInfo.uiFlashSize*2048);
|
||
|
||
iRet = m_pComm->RKU_WriteLBA(0,34,m_gptBuffer);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->write gpt master failed,RetCode(%d)"),iRet);
|
||
}
|
||
return false;
|
||
}
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->write gpt master successfully!"));
|
||
}
|
||
iRet = m_pComm->RKU_WriteLBA(m_flashInfo.uiFlashSize*2048-33,33,backup_gpt);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->write gpt backup failed,RetCode(%d)"),iRet);
|
||
}
|
||
return false;
|
||
}
|
||
currentByte += (SECTOR_SIZE*67);
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->write gpt backup also successfully!"));
|
||
}
|
||
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::RKA_Gpt_Check(STRUCT_RKIMAGE_ITEM &entry,long long ¤tByte,long long totalByte)
|
||
{
|
||
//UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
//UINT uiLBALoopLimit=(LBA_LOOP_SIZE)/uiLBATransferSize;
|
||
//UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet;
|
||
//BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
(void)entry; (void)totalByte;
|
||
PBYTE pRead=NULL;
|
||
pRead = new BYTE[34*SECTOR_SIZE];
|
||
if (!pRead)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Check-->New ReadBuffer failed,err=%d"),errno);
|
||
}
|
||
return false;
|
||
}
|
||
iRet = m_pComm->RKU_ReadLBA(0,34,pRead);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->read gpt master failed,RetCode(%d)"),iRet);
|
||
}
|
||
delete []pRead;
|
||
return false;
|
||
}
|
||
if (memcmp(m_gptBuffer,pRead,34*SECTOR_SIZE)!=0)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->compare gpt master failed"));
|
||
}
|
||
tchar szDateTime[100];
|
||
tstring strFile;
|
||
time_t now;
|
||
struct tm timeNow;
|
||
time(&now);
|
||
localtime_r(&now,&timeNow);
|
||
_stprintf(szDateTime,_T("%02d-%02d-%02d"),timeNow.tm_hour+1,timeNow.tm_min+1,timeNow.tm_sec+1);
|
||
strFile = m_pLog->LogSavePath;
|
||
strFile += szDateTime;
|
||
strFile += _T("file.bin");
|
||
m_pLog->SaveBuffer( strFile,m_gptBuffer,34*SECTOR_SIZE );
|
||
strFile = m_pLog->LogSavePath;
|
||
strFile += szDateTime;
|
||
strFile += _T("flash.bin");
|
||
m_pLog->SaveBuffer( strFile,pRead,34*SECTOR_SIZE );
|
||
}
|
||
delete []pRead;
|
||
return false;
|
||
}
|
||
iRet = m_pComm->RKU_ReadLBA(m_flashInfo.uiFlashSize*2048-33,33,pRead);
|
||
if (iRet!=ERR_SUCCESS)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->read gpt backup failed,RetCode(%d)"),iRet);
|
||
}
|
||
delete []pRead;
|
||
return false;
|
||
}
|
||
if (memcmp(m_gptBuffer+34*SECTOR_SIZE,pRead,33*SECTOR_SIZE)!=0)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_Gpt_Download-->compare gpt backup failed"));
|
||
}
|
||
tchar szDateTime[100];
|
||
tstring strFile;
|
||
time_t now;
|
||
struct tm timeNow;
|
||
time(&now);
|
||
localtime_r(&now,&timeNow);
|
||
_stprintf(szDateTime,_T("%02d-%02d-%02d"),timeNow.tm_hour+1,timeNow.tm_min+1,timeNow.tm_sec+1);
|
||
strFile = m_pLog->LogSavePath;
|
||
strFile += szDateTime;
|
||
strFile += _T("file.bin");
|
||
m_pLog->SaveBuffer( strFile,m_gptBuffer+34*SECTOR_SIZE,33*SECTOR_SIZE );
|
||
strFile = m_pLog->LogSavePath;
|
||
strFile += szDateTime;
|
||
strFile += _T("flash.bin");
|
||
m_pLog->SaveBuffer( strFile,pRead,33*SECTOR_SIZE );
|
||
}
|
||
delete []pRead;
|
||
return false;
|
||
}
|
||
currentByte += (SECTOR_SIZE*67);
|
||
|
||
delete []pRead;
|
||
return true;
|
||
}
|
||
|
||
bool CRKAndroidDevice::MakeParamFileBuffer(STRUCT_RKIMAGE_ITEM &entry)
|
||
{
|
||
bool bRet;
|
||
UINT uiFileBufferSize;
|
||
DWORD dwFWOffset;
|
||
|
||
dwFWOffset = m_pImage->FWOffset;
|
||
uiFileBufferSize = 2*entry.size;
|
||
m_uiParamFileSize = entry.size;
|
||
PBYTE pBuffer=NULL;
|
||
pBuffer = new BYTE[uiFileBufferSize];
|
||
if (!pBuffer)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeParamFileBuffer-->New memory failed"));
|
||
}
|
||
return false;
|
||
}
|
||
memset(pBuffer,0,uiFileBufferSize);
|
||
bRet = m_pImage->GetData(dwFWOffset+entry.offset,entry.size,pBuffer);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeParamFileBuffer-->GetFileData failed"));
|
||
}
|
||
delete[] pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
//<2F>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ҫ<EFBFBD><EFBFBD>Paramter<65>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>,<2C>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>paramter<65>ļ<EFBFBD><C4BC>е<EFBFBD>partition<6F><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸij<DDB8><C4B3><EFBFBD><EFBFBD>ֽ<EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
|
||
|
||
UINT uiParamSec;
|
||
if (m_uiParamFileSize%512==0)
|
||
{
|
||
uiParamSec = m_uiParamFileSize/512;
|
||
}
|
||
else
|
||
uiParamSec = (m_uiParamFileSize+512)/512;
|
||
|
||
if (m_paramBuffer)
|
||
{
|
||
delete []m_paramBuffer;
|
||
m_paramBuffer = NULL;
|
||
}
|
||
m_paramBuffer = new BYTE[uiParamSec*512];
|
||
if (!m_paramBuffer)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:MakeParamFileBuffer-->new memory failed"));
|
||
}
|
||
delete []pBuffer;
|
||
return false;
|
||
}
|
||
memset(m_paramBuffer,0,uiParamSec*512);
|
||
memcpy(m_paramBuffer,pBuffer,m_uiParamFileSize);
|
||
delete []pBuffer;
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::CheckParamPartSize(u_int8* pItemBuffer,int iParamPos,int iItemCount)
|
||
{
|
||
#if 0
|
||
// UINT uiParamPartSize;
|
||
// int i;
|
||
// uiParamPartSize = 0xFFFFFFFF;
|
||
// for (i=0;i<rkImageHead.item_count;i++)
|
||
// {
|
||
// if (i!=iParamPos)
|
||
// {
|
||
// if (rkImageHead.item[i].flash_offset<uiParamPartSize)
|
||
// {
|
||
// uiParamPartSize = rkImageHead.item[i].flash_offset;
|
||
// }
|
||
// }
|
||
// }
|
||
if (!GetParameterPartSize(rkImageHead.item[iParamPos]))
|
||
{
|
||
return false;
|
||
}
|
||
if (m_uiParamFileSize>rkImageHead.item[iParamPos].part_size/8*512)//<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8<EFBFBD><38>
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
#else
|
||
u_int32 uiParamPartSize;
|
||
STRUCT_RKIMAGE_ITEM *pItem;
|
||
int i;
|
||
uiParamPartSize = 0xFFFFFFFF;
|
||
for (i=0;i<iItemCount;i++)
|
||
{
|
||
pItem = (STRUCT_RKIMAGE_ITEM *)(pItemBuffer + i*sizeof(STRUCT_RKIMAGE_ITEM));
|
||
if (i!=iParamPos)
|
||
{
|
||
if (pItem->flash_offset<uiParamPartSize)
|
||
{
|
||
uiParamPartSize = pItem->flash_offset;
|
||
}
|
||
}
|
||
}
|
||
pItem = (STRUCT_RKIMAGE_ITEM *)(pItemBuffer + iParamPos*sizeof(STRUCT_RKIMAGE_ITEM));
|
||
if (!GetParameterPartSize(*pItem))
|
||
return false;
|
||
if (m_uiParamFileSize > pItem->part_size/8*512)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
|
||
#endif
|
||
}
|
||
bool CRKAndroidDevice::IsExistSector3Crc(PRKANDROID_IDB_SEC2 pSec)
|
||
{
|
||
if (!pSec)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (strcmp(pSec->szCrcTag,"CRC")==0)
|
||
{
|
||
m_bExistSector3Crc = true;
|
||
m_usSector3Crc = pSec->usSec3Crc;
|
||
}
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::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(" "));
|
||
strLen.erase(strLen.find_last_not_of(" ")+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(" "));
|
||
strOffset.erase(strOffset.find_last_not_of(" ")+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(" "));
|
||
strName.erase(strName.find_last_not_of(" ")+1);
|
||
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::GetParameterPartSize(STRUCT_RKIMAGE_ITEM ¶mItem)
|
||
{
|
||
PBYTE pParamBuf=NULL;
|
||
pParamBuf = new BYTE[paramItem.size-12+1];
|
||
if (!pParamBuf)
|
||
{
|
||
return false;
|
||
}
|
||
memset(pParamBuf,0,paramItem.size-12+1);
|
||
bool bRet;
|
||
bRet = m_pImage->GetData(m_pImage->FWOffset+paramItem.offset+8,paramItem.size-12,pParamBuf);
|
||
if (!bRet)
|
||
{
|
||
delete []pParamBuf;
|
||
return false;
|
||
}
|
||
string strParamFile = (char *)pParamBuf;
|
||
stringstream paramStream(strParamFile);
|
||
delete []pParamBuf;
|
||
|
||
string strLine,strPartition,strPartInfo,strPartName;
|
||
string::size_type line_size,pos,posColon,posComma;
|
||
UINT uiPartOffset,uiPartSize;
|
||
while (!paramStream.eof())
|
||
{
|
||
getline(paramStream,strLine);
|
||
line_size = strLine.size();
|
||
if (line_size<=0)
|
||
{
|
||
continue;
|
||
}
|
||
if (strLine[line_size-1]=='\r')
|
||
{
|
||
strLine = strLine.substr(0,line_size-1);
|
||
}
|
||
if (strLine.size()<=0)
|
||
{
|
||
continue;
|
||
}
|
||
if (strLine[0]=='#')
|
||
{
|
||
continue;
|
||
}
|
||
pos = strLine.find("mtdparts");
|
||
if (pos==string::npos)
|
||
{
|
||
continue;
|
||
}
|
||
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)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:GetParameterPartSize-->ParsePartitionInfo failed"));
|
||
}
|
||
return false;
|
||
}
|
||
paramItem.part_size = uiPartOffset;
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool CRKAndroidDevice::GetPublicKey(unsigned char *pKey,unsigned int &nKeySize)
|
||
{
|
||
int i,j,iRet,nRsaByte;
|
||
bool bRet;
|
||
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;
|
||
bRet = GetFlashInfo();
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:GetPublicKey-->GetFlashInfo failed"));
|
||
}
|
||
return false;
|
||
}
|
||
if ( !BuildBlockStateMap(0) )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:GetPublicKey-->BuildBlockStateMap failed"));
|
||
}
|
||
return false;
|
||
}
|
||
|
||
FindAllIDB();
|
||
// sleep(1);
|
||
// if (m_pLog)
|
||
// {
|
||
// m_pLog->Record(_T("INFO:GetPublicKey-->IDblock count=%d."),m_oldIDBCounts);
|
||
// }
|
||
if (m_oldIDBCounts<=0)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:GetPublicKey-->IDblock count=%d."),m_oldIDBCounts);
|
||
}
|
||
return false;
|
||
}
|
||
for(i=0;i<m_oldIDBCounts;i++)
|
||
{
|
||
iRet = m_pComm->RKU_ReadSector(m_idBlockOffset[i]*m_flashInfo.uiSectorPerBlock, 8,bData);
|
||
// sleep(1);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:GetPublicKey-->RKU_ReadSector failed,RetCode(%d)"),iRet);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
P_RC4(bData,SECTOR_SIZE);
|
||
|
||
if (pSec0->uiRc4Flag==0)
|
||
{
|
||
// if (m_pLog)
|
||
// {
|
||
// m_pLog->PrintBuffer(strOutput,bData+4*512,512,16);
|
||
// m_pLog->Record("INFO:secure header\n%s",strOutput.c_str());
|
||
// }
|
||
for(j=0;j<4;j++)
|
||
P_RC4(bData+SECTOR_SIZE*(j+4),SECTOR_SIZE);
|
||
// if (m_pLog)
|
||
// {
|
||
// m_pLog->PrintBuffer(strOutput,bData+4*512,512,16);
|
||
// m_pLog->Record("INFO:secure header rc4\n%s",strOutput.c_str());
|
||
// }
|
||
}
|
||
// if (m_pLog)
|
||
// {
|
||
// m_pLog->Record("INFO:secure header tag=0x%x",pSecureHdr->uiTag);
|
||
// }
|
||
if (pSecureHdr->uiTag==0x4B415352)
|
||
{
|
||
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 (m_pLog)
|
||
// {
|
||
// m_pLog->PrintBuffer(strOutput,pKey,nKeySize,16);
|
||
// m_pLog->Record("INFO:Key\n%s",strOutput.c_str());
|
||
// }
|
||
return true;
|
||
}
|
||
|
||
}
|
||
|
||
return false;
|
||
}
|
||
long long CRKAndroidDevice::GetSparseImageSize(STRUCT_RKIMAGE_ITEM &entry)
|
||
{
|
||
bool bRet;
|
||
sparse_header header;
|
||
DWORD dwFWOffset;
|
||
long long ulEntryStartOffset;
|
||
dwFWOffset = m_pImage->FWOffset;
|
||
if (entry.file[50]=='H')
|
||
{
|
||
ulEntryStartOffset = *((DWORD *)(&entry.file[51]));
|
||
ulEntryStartOffset <<= 32;
|
||
ulEntryStartOffset += entry.offset;
|
||
ulEntryStartOffset += m_pImage->FWOffset;
|
||
}
|
||
else
|
||
{
|
||
ulEntryStartOffset = m_pImage->FWOffset;
|
||
ulEntryStartOffset += entry.offset;
|
||
}
|
||
bRet = m_pImage->GetData(ulEntryStartOffset,sizeof(header),(PBYTE)&header);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:IsSparseImage-->getdata failed"));
|
||
}
|
||
return -1;
|
||
}
|
||
return header.blk_sz * header.total_blks;
|
||
|
||
}
|
||
bool CRKAndroidDevice::IsSparseImage(STRUCT_RKIMAGE_ITEM &entry)
|
||
{
|
||
bool bRet;
|
||
sparse_header header;
|
||
DWORD dwFWOffset;
|
||
long long ulEntryStartOffset;
|
||
dwFWOffset = m_pImage->FWOffset;
|
||
if (entry.file[50]=='H')
|
||
{
|
||
ulEntryStartOffset = *((DWORD *)(&entry.file[51]));
|
||
ulEntryStartOffset <<= 32;
|
||
ulEntryStartOffset += entry.offset;
|
||
ulEntryStartOffset += m_pImage->FWOffset;
|
||
}
|
||
else
|
||
{
|
||
ulEntryStartOffset = m_pImage->FWOffset;
|
||
ulEntryStartOffset += entry.offset;
|
||
}
|
||
bRet = m_pImage->GetData(ulEntryStartOffset,sizeof(header),(PBYTE)&header);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:IsSparseImage-->getdata failed"));
|
||
}
|
||
return false;
|
||
}
|
||
if (header.magic!=SPARSE_HEADER_MAGIC)
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
int CRKAndroidDevice:: getEmmc() {
|
||
char bootmode[256];
|
||
int result = 0;
|
||
|
||
property_get("ro.boot.mode", bootmode, "unknown");
|
||
printf("bootmode = %s \n", bootmode);
|
||
|
||
if(!strcmp(bootmode, "nvme")) {
|
||
result = 2;
|
||
} else if(!strcmp(bootmode, "emmc")) {
|
||
result = 1;
|
||
}else {
|
||
result = 0;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
bool CRKAndroidDevice::ErasePartition_discard(STRUCT_RKIMAGE_ITEM &entry)
|
||
{
|
||
u64 uifileBufferSize;
|
||
int iRet;
|
||
|
||
uifileBufferSize = entry.part_size * SECTOR_SIZE;
|
||
m_pCallback("INFO:ErasePartition %s,offset=0x%x,size=%llu, part_size=0x%x \n",
|
||
entry.name, entry.flash_offset, uifileBufferSize, entry.part_size);
|
||
|
||
iRet = m_pComm->RKU_EraseBlock_discard(entry.flash_offset, entry.part_size);
|
||
|
||
if( iRet!=ERR_SUCCESS ){
|
||
printf("erase block fail\n");
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool CRKAndroidDevice::ErasePartition(STRUCT_RKIMAGE_ITEM &entry)
|
||
{
|
||
UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet;
|
||
UINT uiBufferSize=uiLBATransferSize;
|
||
u64 uifileBufferSize;
|
||
BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
|
||
uifileBufferSize = entry.part_size * SECTOR_SIZE;
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" INFO:ErasePartition %s,offset=0x%x,size=%llu, part_size=0x%x"),entry.name,entry.flash_offset,uifileBufferSize, entry.part_size);
|
||
}
|
||
m_pCallback("INFO:ErasePartition %s,offset=0x%x,size=%llu, part_size=0x%x \n",entry.name,entry.flash_offset,uifileBufferSize, entry.part_size);
|
||
|
||
PBYTE pBuffer=NULL;
|
||
pBuffer = new BYTE[uiBufferSize];
|
||
if (!pBuffer)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:ErasePartition-->New memory failed"));
|
||
}
|
||
m_pCallback("ERROR:ErasePartition-->New memory failed \n");
|
||
return false;
|
||
}
|
||
|
||
UINT uiBegin,uiLen,uiWriteByte;
|
||
long long uiEntryOffset;
|
||
uiBegin = entry.flash_offset;
|
||
uiLen = 0;uiWriteByte = 0;uiEntryOffset=0;
|
||
while ( uifileBufferSize>0 )
|
||
{
|
||
memset(pBuffer,0,uiBufferSize);
|
||
if ( uifileBufferSize<uiBufferSize )
|
||
{
|
||
uiWriteByte = uifileBufferSize;
|
||
uiLen = ( (uiWriteByte%SECTOR_SIZE==0) ? (uiWriteByte/SECTOR_SIZE) : (uiWriteByte/SECTOR_SIZE+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiBufferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
|
||
iRet = m_pComm->RKU_WriteLBA(uiBegin,uiLen,pBuffer,byRWMethod);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:ErasePartition-->RKU_WriteLBA failed,Written(%d),RetCode(%d)"),uiEntryOffset,iRet);
|
||
}
|
||
m_pCallback("ERROR:ErasePartition-->RKU_WriteLBA failed,Written(%d),RetCode(%d) \n",uiEntryOffset,iRet);
|
||
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uifileBufferSize -= uiWriteByte;
|
||
uiEntryOffset += uiWriteByte;
|
||
uiBegin += uiLen;
|
||
}
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return true;
|
||
}
|
||
|
||
bool CRKAndroidDevice::EraseSparseRegion(const char* volume,const char* directory)
|
||
{
|
||
#if 0
|
||
//bool bSuccess = true;
|
||
//if volume is system.then set volume is "",because system as root
|
||
if(strcmp("/system", volume) == 0)
|
||
volume = "/";
|
||
printf("EraseSparseRegion volume is %s\n",volume);
|
||
if(format_volume(volume, directory) == 0){
|
||
printf("EraseSparseRegion format_volume is ok!!!\n");
|
||
return true;
|
||
}else{
|
||
printf("EraseSparseRegion format_volume is failed!!!\n");
|
||
return false;
|
||
}
|
||
#else
|
||
(void)volume;
|
||
(void)directory;
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" INFO:EraseSparseRegion is deprecated, shall not be here! \n"));
|
||
}
|
||
m_pCallback("INFO:EraseSparseRegion is deprecated, shall not be here! \n");
|
||
|
||
return false;
|
||
#endif
|
||
}
|
||
bool CRKAndroidDevice::RKA_SparseFile_Download(STRUCT_RKIMAGE_ITEM &entry,long long ¤tByte,long long totalByte)
|
||
{
|
||
UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
//UINT uiLBALoopLimit=(LBA_LOOP_SIZE)/uiLBATransferSize;
|
||
UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet,i;
|
||
bool bRet;
|
||
UINT uiBufferSize=uiLBATransferSize;
|
||
long long uifileBufferSize;
|
||
DWORD dwFWOffset;
|
||
long long ulEntryStartOffset;
|
||
sparse_header header;
|
||
chunk_header chunk;
|
||
//dwLayerID = GetLayerID();
|
||
(void)totalByte;
|
||
|
||
m_pCallback("RKA_SparseFile_Download entry.name=%s \n", entry.name);
|
||
dwFWOffset = m_pImage->FWOffset;
|
||
if (entry.file[50]=='H')
|
||
{
|
||
ulEntryStartOffset = *((DWORD *)(&entry.file[51]));
|
||
ulEntryStartOffset <<= 32;
|
||
ulEntryStartOffset += entry.offset;
|
||
ulEntryStartOffset += m_pImage->FWOffset;
|
||
}
|
||
else
|
||
{
|
||
ulEntryStartOffset = m_pImage->FWOffset;
|
||
ulEntryStartOffset += entry.offset;
|
||
}
|
||
if (entry.file[55]=='H')
|
||
{
|
||
uifileBufferSize = *((DWORD *)(&entry.file[56]));
|
||
uifileBufferSize <<= 32;
|
||
uifileBufferSize += entry.size;
|
||
}
|
||
else
|
||
uifileBufferSize = entry.size;
|
||
|
||
//get sparse header
|
||
bRet = m_pImage->GetData(ulEntryStartOffset,sizeof(header),(PBYTE)&header);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_SparseFile_Download-->get sparse header failed,partition=%s"),entry.name);
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->get sparse header failed,partition=%s \n",entry.name);
|
||
}
|
||
return false;
|
||
}
|
||
uifileBufferSize = header.blk_sz * header.total_blks;
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:Start to download %s,offset=0x%x,size=%llu"),entry.name,entry.flash_offset,uifileBufferSize);
|
||
m_pCallback("INFO:Start to download %s,offset=0x%x,size=%llu \n",entry.name,entry.flash_offset,uifileBufferSize);
|
||
}
|
||
//erase system partition
|
||
#if 0
|
||
if ( !strcmp(entry.name, "system") && !EraseSparseRegion("/system",NULL))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Download-->EraseSparseRegion failed"));
|
||
}
|
||
return false;
|
||
}
|
||
#else
|
||
if(m_pComm->m_bEmmc == 1) {
|
||
if(!ErasePartition_discard(entry)) {
|
||
if (m_pLog) {
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Download-->ErasePartition_discard failed"));
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->ErasePartition_discard failed \n");
|
||
return false;
|
||
}
|
||
} else {
|
||
if(!ErasePartition(entry)) {
|
||
if (m_pLog) {
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Download-->ErasePartition failed"));
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->ErasePartition failed \n");
|
||
return false;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
|
||
if (entry.flash_offset>m_dwBackupOffset)
|
||
{
|
||
byRWMethod = RWMETHOD_LBA;
|
||
}
|
||
PBYTE pBuffer=NULL;
|
||
pBuffer = new BYTE[uiBufferSize];
|
||
if (!pBuffer)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Download-->New memory failed"));
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->New memory failed \n");
|
||
return false;
|
||
}
|
||
|
||
UINT uiBegin,uiLen,uiWriteByte,uiCurChunk,uiChunkDataSize,uiFillByte,uiCrc;
|
||
long long uiEntryOffset;
|
||
uiCurChunk = 0;
|
||
uiBegin = entry.flash_offset;
|
||
uiLen = 0;uiWriteByte = 0;uiEntryOffset=sizeof(header);
|
||
m_pCallback("INFO:RKA_SparseFile_Download-->total_chunks=%u \n", header.total_chunks);
|
||
while ( uiCurChunk<header.total_chunks)
|
||
{
|
||
memset(&chunk, 0x0, sizeof(chunk));
|
||
bRet = m_pImage->GetData(ulEntryStartOffset+uiEntryOffset,sizeof(chunk),(PBYTE)&chunk);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Download-->get sparse chunk failed"));
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->get sparse chunk failed \n");
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uiCurChunk++;
|
||
uiEntryOffset += sizeof(chunk);
|
||
switch (chunk.chunk_type)
|
||
{
|
||
case CHUNK_TYPE_RAW:
|
||
uiChunkDataSize = chunk.total_sz - sizeof(chunk_header);
|
||
while (uiChunkDataSize)
|
||
{
|
||
memset(pBuffer,0,uiBufferSize);
|
||
if ( uiChunkDataSize<uiBufferSize )
|
||
{
|
||
uiWriteByte = uiChunkDataSize;
|
||
uiLen = ( (uiWriteByte%SECTOR_SIZE==0) ? (uiWriteByte/SECTOR_SIZE) : (uiWriteByte/SECTOR_SIZE+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiBufferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
if (!m_pImage->GetData(ulEntryStartOffset+uiEntryOffset,uiWriteByte,pBuffer))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_SparseFile_Download-->get chunk data failed,chunk=%d"),uiCurChunk);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->get chunk data failed,chunk=%d \n",uiCurChunk);
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uiEntryOffset += uiWriteByte;
|
||
iRet = m_pComm->RKU_WriteLBA(uiBegin,uiLen,pBuffer,byRWMethod);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_SparseFile_Download-->RKU_WriteLBA failed,RetCode(%d),chunk=%d"),iRet,uiCurChunk);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->RKU_WriteLBA failed,RetCode(%d),chunk=%d \n",iRet,uiCurChunk);
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uiBegin += uiLen;
|
||
currentByte += uiWriteByte;
|
||
uiChunkDataSize -= uiWriteByte;
|
||
|
||
}
|
||
break;
|
||
case CHUNK_TYPE_FILL:
|
||
uiChunkDataSize = chunk.chunk_sz * header.blk_sz;
|
||
if (!m_pImage->GetData(ulEntryStartOffset+uiEntryOffset,4,(PBYTE)&uiFillByte))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_SparseFile_Download-->get fill byte failed,chunk=%d"),uiCurChunk);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->get fill byte failed,chunk=%d \n",uiCurChunk);
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uiEntryOffset += 4;
|
||
while (uiChunkDataSize)
|
||
{
|
||
memset(pBuffer,0,uiBufferSize);
|
||
if ( uiChunkDataSize<uiBufferSize )
|
||
{
|
||
uiWriteByte = uiChunkDataSize;
|
||
uiLen = ( (uiWriteByte%SECTOR_SIZE==0) ? (uiWriteByte/SECTOR_SIZE) : (uiWriteByte/SECTOR_SIZE+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiBufferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
for (i=0;i<uiWriteByte/4;i++)
|
||
{
|
||
*(UINT *)(pBuffer + i*4) = uiFillByte;
|
||
}
|
||
|
||
iRet = m_pComm->RKU_WriteLBA(uiBegin,uiLen,pBuffer,byRWMethod);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Download-->RKU_WriteLBA failed,RetCode(%d),chunk=%d"),iRet,uiCurChunk);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Download-->RKU_WriteLBA failed,RetCode(%d),chunk=%d \n",iRet,uiCurChunk);
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uiBegin += uiLen;
|
||
currentByte += uiWriteByte;
|
||
uiChunkDataSize -= uiWriteByte;
|
||
|
||
}
|
||
break;
|
||
case CHUNK_TYPE_DONT_CARE:
|
||
uiChunkDataSize = chunk.chunk_sz * header.blk_sz;
|
||
currentByte += uiChunkDataSize;
|
||
uiLen = ( (uiChunkDataSize%SECTOR_SIZE==0) ? (uiChunkDataSize/SECTOR_SIZE) : (uiChunkDataSize/SECTOR_SIZE+1) );
|
||
uiBegin += uiLen;
|
||
|
||
break;
|
||
case CHUNK_TYPE_CRC32:
|
||
bRet = m_pImage->GetData(ulEntryStartOffset+uiEntryOffset,4,(PBYTE)&uiCrc);
|
||
uiEntryOffset += 4;
|
||
break;
|
||
}
|
||
}
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
|
||
m_pCallback("RKA_SparseFile_Download entry.name=%s DONE! \n", entry.name);
|
||
return true;
|
||
}
|
||
bool CRKAndroidDevice::RKA_SparseFile_Check(STRUCT_RKIMAGE_ITEM &entry,long long ¤tByte,long long totalByte)
|
||
{
|
||
UINT uiLBATransferSize=(LBA_TRANSFER_SIZE)*m_uiLBATimes;
|
||
//UINT uiLBALoopLimit=(LBA_LOOP_SIZE)/uiLBATransferSize;
|
||
UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
int iRet,i;
|
||
bool bRet;
|
||
UINT uiBufferSize=uiLBATransferSize;
|
||
long long uifileBufferSize;
|
||
DWORD dwFWOffset;
|
||
long long ulEntryStartOffset;
|
||
sparse_header header;
|
||
chunk_header chunk;
|
||
(void)totalByte;
|
||
m_pCallback("RKA_SparseFile_Check entry.name=%s \n", entry.name);
|
||
|
||
dwFWOffset = m_pImage->FWOffset;
|
||
if (entry.file[50]=='H')
|
||
{
|
||
ulEntryStartOffset = *((DWORD *)(&entry.file[51]));
|
||
ulEntryStartOffset <<= 32;
|
||
ulEntryStartOffset += entry.offset;
|
||
ulEntryStartOffset += m_pImage->FWOffset;
|
||
}
|
||
else
|
||
{
|
||
ulEntryStartOffset = m_pImage->FWOffset;
|
||
ulEntryStartOffset += entry.offset;
|
||
}
|
||
if (entry.file[55]=='H')
|
||
{
|
||
uifileBufferSize = *((DWORD *)(&entry.file[56]));
|
||
uifileBufferSize <<= 32;
|
||
uifileBufferSize += entry.size;
|
||
}
|
||
else
|
||
uifileBufferSize = entry.size;
|
||
//get sparse header
|
||
bRet = m_pImage->GetData(ulEntryStartOffset,sizeof(header),(PBYTE)&header);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Check-->get sparse header failed,partition=%s"),entry.name);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->get sparse header failed,partition=%s \n",entry.name);
|
||
return false;
|
||
}
|
||
uifileBufferSize = header.blk_sz * header.total_blks;
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("INFO:Start to check %s,offset=0x%x,size=%I64u"),entry.name,entry.flash_offset,uifileBufferSize);
|
||
}
|
||
m_pCallback("INFO:Start to check %s,offset=0x%x,size=%I64u \n",entry.name,entry.flash_offset,uifileBufferSize);
|
||
|
||
BYTE byRWMethod=RWMETHOD_IMAGE;
|
||
if (entry.flash_offset>m_dwBackupOffset)
|
||
{
|
||
byRWMethod = RWMETHOD_LBA;
|
||
}
|
||
|
||
PBYTE pBufferFromFile=NULL;
|
||
pBufferFromFile = new BYTE[uiBufferSize];
|
||
if (!pBufferFromFile)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Check-->New memory failed"));
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->New memory failed \n");
|
||
return false;
|
||
}
|
||
PBYTE pBufferFromFlash=NULL;
|
||
pBufferFromFlash = new BYTE[uiBufferSize];
|
||
if (!pBufferFromFlash)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_SparseFile_Check-->New memory failed"));
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->New memory failed \n");
|
||
delete []pBufferFromFile;
|
||
return false;
|
||
}
|
||
|
||
UINT uiBegin,uiLen,uiWriteByte,uiCurChunk,uiChunkDataSize,uiFillByte,uiCrc;
|
||
long long uiEntryOffset;
|
||
uiBegin = entry.flash_offset;
|
||
uiCurChunk = 0;
|
||
uiLen = 0;uiWriteByte = 0;uiEntryOffset=sizeof(header);
|
||
while ( uiCurChunk<header.total_chunks)
|
||
{
|
||
memset(&chunk, 0x0, sizeof(chunk));
|
||
bRet = m_pImage->GetData(ulEntryStartOffset+uiEntryOffset,sizeof(chunk),(PBYTE)&chunk);
|
||
if (!bRet)
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_SparseFile_Check-->get sparse chunk failed"));
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->get sparse chunk failed \n");
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
uiCurChunk++;
|
||
uiEntryOffset += sizeof(chunk);
|
||
switch (chunk.chunk_type)
|
||
{
|
||
case CHUNK_TYPE_RAW:
|
||
uiChunkDataSize = chunk.total_sz - sizeof(chunk_header);
|
||
while (uiChunkDataSize)
|
||
{
|
||
if ( uiChunkDataSize<uiBufferSize )
|
||
{
|
||
uiWriteByte = uiChunkDataSize;
|
||
uiLen = ( (uiWriteByte%SECTOR_SIZE==0) ? (uiWriteByte/SECTOR_SIZE) : (uiWriteByte/SECTOR_SIZE+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiBufferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
memset(pBufferFromFile,0,uiBufferSize);
|
||
memset(pBufferFromFlash,0,uiBufferSize);
|
||
if (!m_pImage->GetData(ulEntryStartOffset+uiEntryOffset,uiWriteByte,pBufferFromFile))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T("ERROR:RKA_SparseFile_Check-->get chunk data failed,chunk=%d"),uiCurChunk);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->get chunk data failed,chunk=%d \n",uiCurChunk);
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
uiEntryOffset += uiWriteByte;
|
||
iRet = m_pComm->RKU_ReadLBA(uiBegin,uiLen,pBufferFromFlash,byRWMethod);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Check-->RKU_ReadLBA failed,RetCode(%d),chunk=%d"),iRet,uiCurChunk);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->RKU_ReadLBA failed,RetCode(%d),chunk=%d \n",iRet,uiCurChunk);
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
if ( memcmp(pBufferFromFile,pBufferFromFlash,uiWriteByte)!=0 )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Check-->Memcmp failed,chunk=%d uiBegin=0x%x \n"),uiCurChunk, uiBegin);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->Memcmp failed,chunk=%d uiBegin=0x%x\n",uiCurChunk, uiBegin);
|
||
if (m_pLog)
|
||
{
|
||
tchar szDateTime[100];
|
||
tstring strFile;
|
||
time_t now;
|
||
struct tm timeNow;
|
||
time(&now);
|
||
localtime_r(&now,&timeNow);
|
||
_stprintf(szDateTime,_T("%02d-%02d-%02d"),timeNow.tm_hour,timeNow.tm_min,timeNow.tm_sec);
|
||
//strFile = m_pLog->LogSavePath;
|
||
strFile += szDateTime;
|
||
strFile += _T("file.bin");
|
||
m_pLog->SaveBuffer( strFile,pBufferFromFile,uiWriteByte );
|
||
//strFile = m_pLog->LogSavePath;
|
||
strFile += szDateTime;
|
||
strFile += _T("flash.bin");
|
||
m_pLog->SaveBuffer( strFile,pBufferFromFlash,uiWriteByte );
|
||
}
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
currentByte += uiWriteByte;
|
||
uiChunkDataSize -= uiWriteByte;
|
||
uiBegin += uiLen;
|
||
}
|
||
break;
|
||
case CHUNK_TYPE_FILL:
|
||
uiChunkDataSize = chunk.chunk_sz * header.blk_sz;
|
||
if (!m_pImage->GetData(ulEntryStartOffset+uiEntryOffset,4,(PBYTE)&uiFillByte))
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Check-->get fill byte failed,chunk=%d"),uiCurChunk);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->get fill byte failed,chunk=%d \n",uiCurChunk);
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
uiEntryOffset += 4;
|
||
while (uiChunkDataSize)
|
||
{
|
||
if ( uiChunkDataSize<uiBufferSize )
|
||
{
|
||
uiWriteByte = uiChunkDataSize;
|
||
uiLen = ( (uiWriteByte%SECTOR_SIZE==0) ? (uiWriteByte/SECTOR_SIZE) : (uiWriteByte/SECTOR_SIZE+1) );
|
||
}
|
||
else
|
||
{
|
||
uiWriteByte = uiBufferSize;
|
||
uiLen = uiLBASector;
|
||
}
|
||
memset(pBufferFromFile,0,uiBufferSize);
|
||
memset(pBufferFromFlash,0,uiBufferSize);
|
||
for (i=0;i<uiWriteByte/4;i++)
|
||
{
|
||
*(UINT *)(pBufferFromFile + i*4) = uiFillByte;
|
||
}
|
||
iRet = m_pComm->RKU_ReadLBA(uiBegin,uiLen,pBufferFromFlash,byRWMethod);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Check-->RKU_ReadLBA failed,RetCode(%d),chunk=%d"),iRet,uiCurChunk);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->RKU_ReadLBA failed,RetCode(%d),chunk=%d \n",iRet,uiCurChunk);
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
if ( memcmp(pBufferFromFile,pBufferFromFlash,uiWriteByte)!=0 )
|
||
{
|
||
if (m_pLog)
|
||
{
|
||
m_pLog->Record(_T(" ERROR:RKA_SparseFile_Check-->Memcmp failed,chunk=%d uiBegin=%0x%x"),uiCurChunk, uiBegin);
|
||
}
|
||
m_pCallback("ERROR:RKA_SparseFile_Check-->Memcmp failed,chunk=%d uiBegin=%0x%x",uiCurChunk, uiBegin);
|
||
if (m_pLog)
|
||
{
|
||
tchar szDateTime[100];
|
||
tstring strFile;
|
||
time_t now;
|
||
struct tm timeNow;
|
||
time(&now);
|
||
localtime_r(&now,&timeNow);
|
||
_stprintf(szDateTime,_T("%02d-%02d-%02d"),timeNow.tm_hour,timeNow.tm_min,timeNow.tm_sec);
|
||
//strFile = m_pLog->LogSavePath;
|
||
strFile += szDateTime;
|
||
strFile += _T("file.bin");
|
||
m_pLog->SaveBuffer( strFile,pBufferFromFile,uiWriteByte );
|
||
//strFile = m_pLog->LogSavePath;
|
||
strFile += szDateTime;
|
||
strFile += _T("flash.bin");
|
||
m_pLog->SaveBuffer( strFile,pBufferFromFlash,uiWriteByte );
|
||
}
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
return false;
|
||
}
|
||
currentByte += uiWriteByte;
|
||
uiChunkDataSize -= uiWriteByte;
|
||
uiBegin += uiLen;
|
||
|
||
}
|
||
break;
|
||
case CHUNK_TYPE_DONT_CARE:
|
||
uiChunkDataSize = chunk.chunk_sz * header.blk_sz;
|
||
currentByte += uiChunkDataSize;
|
||
uiLen = ( (uiChunkDataSize%SECTOR_SIZE==0) ? (uiChunkDataSize/SECTOR_SIZE) : (uiChunkDataSize/SECTOR_SIZE+1) );
|
||
uiBegin += uiLen;
|
||
break;
|
||
case CHUNK_TYPE_CRC32:
|
||
bRet = m_pImage->GetData(ulEntryStartOffset+uiEntryOffset,4,(PBYTE)&uiCrc);
|
||
uiEntryOffset += 4;
|
||
break;
|
||
}
|
||
}
|
||
|
||
delete []pBufferFromFile;
|
||
delete []pBufferFromFlash;
|
||
m_pCallback("RKA_SparseFile_Check entry.name=%s Done! \n", entry.name);
|
||
return true;
|
||
}
|
||
|
||
bool CRKAndroidDevice::GetParameterGptFlag(STRUCT_RKIMAGE_ITEM ¶mItem)
|
||
{
|
||
PBYTE pParamBuf=NULL;
|
||
bool bGpt = false;
|
||
pParamBuf = new BYTE[paramItem.size-12+1];
|
||
if (!pParamBuf)
|
||
{
|
||
return false;
|
||
}
|
||
memset(pParamBuf,0,paramItem.size-12+1);
|
||
bool bRet;
|
||
bRet = m_pImage->GetData(m_pImage->FWOffset+paramItem.offset+8,paramItem.size-12,pParamBuf);
|
||
if (!bRet)
|
||
{
|
||
delete []pParamBuf;
|
||
return false;
|
||
}
|
||
string strParamFile = (char *)pParamBuf;
|
||
stringstream paramStream(strParamFile);
|
||
delete []pParamBuf;
|
||
|
||
|
||
string strLine;
|
||
string::size_type pos,line_size;
|
||
while (!paramStream.eof())
|
||
{
|
||
getline(paramStream,strLine);
|
||
line_size = strLine.size();
|
||
if (line_size<=0)
|
||
{
|
||
continue;
|
||
}
|
||
if (strLine[line_size-1]=='\r')
|
||
{
|
||
strLine = strLine.substr(0,line_size-1);
|
||
}
|
||
if (strLine.size()<=0)
|
||
{
|
||
continue;
|
||
}
|
||
if (strLine[0]=='#')
|
||
{
|
||
continue;
|
||
}
|
||
transform(strLine.begin(),strLine.end(),strLine.begin(),(int(*)(int))toupper);
|
||
pos = strLine.find("TYPE");
|
||
if (pos==string::npos)
|
||
{
|
||
continue;
|
||
}
|
||
if ((pos = strLine.find("GPT"))!=string::npos)
|
||
{
|
||
bGpt = true;
|
||
break;
|
||
}
|
||
else
|
||
continue;
|
||
}
|
||
return bGpt;
|
||
}
|
||
#define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
|
||
unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len)
|
||
{
|
||
unsigned int *b =(unsigned int *)p;
|
||
unsigned int *tab = crc32table_le;
|
||
crc = crc ^ 0xFFFFFFFF;
|
||
if((((long)b)&3 && len)){
|
||
do {
|
||
unsigned char *p = (unsigned char *)b;
|
||
DO_CRC(*p++);
|
||
b = (unsigned int *)p;
|
||
} while ((--len) && ((long)b)&3 );
|
||
}
|
||
if((len >= 4)){
|
||
unsigned int save_len = len & 3;
|
||
len = len >> 2;
|
||
--b;
|
||
do {
|
||
crc ^= *++b;
|
||
DO_CRC(0);
|
||
DO_CRC(0);
|
||
DO_CRC(0);
|
||
DO_CRC(0);
|
||
} while (--len);
|
||
b++;
|
||
len = save_len;
|
||
}
|
||
if(len){
|
||
do {
|
||
unsigned char *p = (unsigned char *)b;
|
||
DO_CRC(*p++);
|
||
b = (unsigned int *)p;
|
||
} while (--len);
|
||
}
|
||
crc = crc ^ 0xFFFFFFFF;
|
||
return crc;
|
||
|
||
}
|
||
void prepare_gpt_backup(u8 *master, u8 *backup, u64 diskSectors)
|
||
{
|
||
gpt_header *gptBackupHead = (gpt_header *)(backup + 32 * SECTOR_SIZE);
|
||
u32 calc_crc32;
|
||
(void)master;
|
||
|
||
/* recalculate the values for the Backup GPT Header */
|
||
gptBackupHead->my_lba = cpu_to_le64(diskSectors - 1);
|
||
gptBackupHead->alternate_lba = cpu_to_le64(1);
|
||
gptBackupHead->partition_entry_lba = cpu_to_le64(diskSectors - 34 + 1);
|
||
gptBackupHead->header_crc32 = 0;
|
||
|
||
calc_crc32 = crc32_le(0, (unsigned char *)gptBackupHead, le32_to_cpu(gptBackupHead->header_size));
|
||
gptBackupHead->header_crc32 = cpu_to_le32(calc_crc32);
|
||
}
|
||
void gen_rand_uuid(unsigned char *uuid_bin)
|
||
{
|
||
efi_guid_t id;
|
||
unsigned int *ptr = (unsigned int *)&id;
|
||
unsigned int i;
|
||
|
||
/* Set all fields randomly */
|
||
for (i = 0; i < sizeof(id) / sizeof(*ptr); i++)
|
||
*(ptr + i) = cpu_to_be32(rand());
|
||
|
||
id.uuid.time_hi_and_version = (id.uuid.time_hi_and_version & 0x0FFF) | 0x4000;
|
||
id.uuid.clock_seq_hi_and_reserved = id.uuid.clock_seq_hi_and_reserved | 0x80;
|
||
|
||
memcpy(uuid_bin, id.raw, sizeof(id));
|
||
}
|
||
void create_gpt_buffer(u8 *gpt, PARAM_ITEM_VECTOR &vecParts, CONFIG_ITEM_VECTOR &vecUuid, u64 diskSectors)
|
||
{
|
||
legacy_mbr *mbr = (legacy_mbr *)gpt;
|
||
gpt_header *gptHead = (gpt_header *)(gpt + SECTOR_SIZE);
|
||
gpt_entry *gptEntry = (gpt_entry *)(gpt + 2 * SECTOR_SIZE);
|
||
u32 i,j;
|
||
int pos,backup_gpt_secs;
|
||
tstring strPartName;
|
||
string::size_type iPos;
|
||
if (diskSectors>=0x800000)
|
||
{
|
||
backup_gpt_secs = 64;
|
||
}
|
||
else{
|
||
backup_gpt_secs = 33;
|
||
}
|
||
printf("create_gpt_buffer backup_gpt_secs=%d\n", backup_gpt_secs);
|
||
/*1.protective mbr*/
|
||
memset(gpt, 0, SECTOR_SIZE);
|
||
mbr->signature = MSDOS_MBR_SIGNATURE;
|
||
mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
|
||
mbr->partition_record[0].start_sect = 1;
|
||
mbr->partition_record[0].nr_sects = (u32)-1;
|
||
/*2.gpt header*/
|
||
memset(gpt + SECTOR_SIZE, 0, SECTOR_SIZE);
|
||
gptHead->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
|
||
gptHead->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
|
||
gptHead->header_size = cpu_to_le32(sizeof(gpt_header));
|
||
gptHead->my_lba = cpu_to_le64(1);
|
||
gptHead->alternate_lba = cpu_to_le64(diskSectors - 1);
|
||
gptHead->first_usable_lba = cpu_to_le64(34);
|
||
gptHead->last_usable_lba = cpu_to_le64(diskSectors - 34);
|
||
gptHead->partition_entry_lba = cpu_to_le64(2);
|
||
gptHead->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
|
||
gptHead->sizeof_partition_entry = cpu_to_le32(GPT_ENTRY_SIZE);
|
||
gptHead->header_crc32 = 0;
|
||
gptHead->partition_entry_array_crc32 = 0;
|
||
gen_rand_uuid(gptHead->disk_guid.raw);
|
||
|
||
/*3.gpt partition entry*/
|
||
memset(gpt + 2 * SECTOR_SIZE, 0, 32 * SECTOR_SIZE);
|
||
for (i = 0; i < vecParts.size(); i++) {
|
||
gen_rand_uuid(gptEntry->partition_type_guid.raw);
|
||
gen_rand_uuid(gptEntry->unique_partition_guid.raw);
|
||
gptEntry->starting_lba = cpu_to_le64(vecParts[i].uiItemOffset);
|
||
gptEntry->ending_lba = cpu_to_le64(gptEntry->starting_lba + vecParts[i].uiItemSize - 1);
|
||
gptEntry->attributes.raw = 0;
|
||
strPartName = vecParts[i].szItemName;
|
||
iPos = strPartName.find(_T(':'));
|
||
if (iPos != tstring::npos) {
|
||
transform(strPartName.begin(),strPartName.end(),strPartName.begin(),(int(*)(int))tolower);
|
||
if (strPartName.find(_T("bootable")) != tstring::npos)
|
||
gptEntry->attributes.raw = PART_PROPERTY_BOOTABLE;
|
||
if (strPartName.find(_T("grow")) != tstring::npos)
|
||
gptEntry->ending_lba = cpu_to_le64(diskSectors - backup_gpt_secs -1);
|
||
strPartName = strPartName.substr(0,iPos);
|
||
vecParts[i].szItemName[strPartName.size()] = 0;
|
||
}
|
||
for (j = 0; j < _tcslen(vecParts[i].szItemName); j++)
|
||
gptEntry->partition_name[j] = vecParts[i].szItemName[j];
|
||
if ((pos = find_uuid_item(vecUuid, vecParts[i].szItemName)) != -1)
|
||
memcpy(gptEntry->unique_partition_guid.raw, vecUuid[pos].szItemValue, 16);
|
||
gptEntry++;
|
||
}
|
||
|
||
gptHead->partition_entry_array_crc32 = cpu_to_le32(crc32_le(0, gpt + 2 * SECTOR_SIZE, GPT_ENTRY_SIZE * GPT_ENTRY_NUMBERS));
|
||
gptHead->header_crc32 = cpu_to_le32(crc32_le(0, gpt + SECTOR_SIZE, sizeof(gpt_header)));
|
||
|
||
}
|
||
bool ParseUuidInfo(string &strUuidInfo, string &strName, string &strUUid)
|
||
{
|
||
string::size_type pos(0);
|
||
|
||
if (strUuidInfo.size() <= 0) {
|
||
return false;
|
||
}
|
||
pos = strUuidInfo.find('=');
|
||
if (pos == string::npos) {
|
||
return false;
|
||
}
|
||
strName = strUuidInfo.substr(0, pos);
|
||
strName.erase(0, strName.find_first_not_of(" "));
|
||
strName.erase(strName.find_last_not_of(" ") + 1);
|
||
|
||
strUUid = strUuidInfo.substr(pos+1);
|
||
strUUid.erase(0, strUUid.find_first_not_of(" "));
|
||
strUUid.erase(strUUid.find_last_not_of(" ") + 1);
|
||
|
||
while(true) {
|
||
pos = 0;
|
||
if( (pos = strUUid.find("-")) != string::npos)
|
||
strUUid.replace(pos,1,"");
|
||
else
|
||
break;
|
||
}
|
||
if (strUUid.size() != 32)
|
||
return false;
|
||
return true;
|
||
}
|
||
void string_to_uuid(string strUUid, char *uuid)
|
||
{
|
||
unsigned int i;
|
||
char value;
|
||
memset(uuid, 0, 16);
|
||
for (i =0; i < strUUid.size(); i++) {
|
||
value = 0;
|
||
if ((strUUid[i] >= '0')&&(strUUid[i] <= '9'))
|
||
value = strUUid[i] - '0';
|
||
if ((strUUid[i] >= 'a')&&(strUUid[i] <= 'f'))
|
||
value = strUUid[i] - 'a' + 10;
|
||
if ((strUUid[i] >= 'A')&&(strUUid[i] <= 'F'))
|
||
value = strUUid[i] - 'A' + 10;
|
||
if ((i % 2) == 0)
|
||
uuid[i / 2] += (value << 4);
|
||
else
|
||
uuid[i / 2] += value;
|
||
}
|
||
unsigned int *p32;
|
||
unsigned short *p16;
|
||
p32 = (unsigned int*)uuid;
|
||
*p32 = cpu_to_be32(*p32);
|
||
p16 = (unsigned short *)(uuid + 4);
|
||
*p16 = cpu_to_be16(*p16);
|
||
p16 = (unsigned short *)(uuid + 6);
|
||
*p16 = cpu_to_be16(*p16);
|
||
}
|
||
bool get_uuid_from_parameter(char *pParameter,CONFIG_ITEM_VECTOR &vecItem)
|
||
{
|
||
stringstream paramStream(pParameter);
|
||
bool bRet;
|
||
string strLine,strUUid,strPartInfo,strPartName;
|
||
string::size_type line_size,pos;
|
||
STRUCT_CONFIG_ITEM uuid_item;
|
||
vecItem.clear();
|
||
while (!paramStream.eof())
|
||
{
|
||
getline(paramStream,strLine);
|
||
line_size = strLine.size();
|
||
if (line_size==0)
|
||
continue;
|
||
if (strLine[line_size-1]=='\r')
|
||
{
|
||
strLine = strLine.substr(0,line_size-1);
|
||
}
|
||
pos = strLine.find("uuid:");
|
||
if (pos != string::npos) {
|
||
strPartInfo = strLine.substr(pos+5);
|
||
bRet = ParseUuidInfo(strPartInfo, strPartName, strUUid);
|
||
if (bRet) {
|
||
strcpy(uuid_item.szItemName, strPartName.c_str());
|
||
string_to_uuid(strUUid,uuid_item.szItemValue);
|
||
vecItem.push_back(uuid_item);
|
||
}
|
||
}
|
||
}
|
||
return (vecItem.size()>0);
|
||
}
|
||
int find_uuid_item(CONFIG_ITEM_VECTOR &vecItems, char *pszName)
|
||
{
|
||
unsigned int i;
|
||
for(i = 0; i < vecItems.size(); i++){
|
||
if (strcasecmp(pszName, vecItems[i].szItemName) == 0){
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|