214 lines
6.4 KiB
C++
Executable File
214 lines
6.4 KiB
C++
Executable File
/*
|
||
* Copyright 2019 Rockchip Electronics Co., Ltd
|
||
* Dayao Ji <jdy@rock-chips.com>
|
||
*
|
||
* SPDX-License-Identifier: GPL-2.0+
|
||
*/
|
||
#include <iostream>
|
||
#include "rkupdate/RKSparse.h"
|
||
#include "rkupdate/RKDevice.h"
|
||
using namespace std;
|
||
|
||
RKSparse::RKSparse(const char* filePath){
|
||
// 1. 打开文件
|
||
m_pFile = fopen(filePath, "rb");
|
||
fileName = filePath;
|
||
// 2. 设置m_header
|
||
readfile(0, sizeof(m_header), (PBYTE)&m_header);
|
||
// 3. 设置m_chunk
|
||
readfile(0 + sizeof(m_header), sizeof(m_chunk), (PBYTE)&m_chunk);
|
||
};
|
||
|
||
RKSparse::~RKSparse(){
|
||
if(m_pFile != NULL){
|
||
fclose(m_pFile);
|
||
}
|
||
remove(fileName);
|
||
sync();
|
||
}
|
||
bool RKSparse::IsSparseImage(){
|
||
if(m_header.magic != SPARSE_HEADER_MAGIC)
|
||
{
|
||
printf("Image isn't Sparse.\n");
|
||
return false;
|
||
}else{
|
||
printf("Image is Sparse.\n");
|
||
return true;
|
||
}
|
||
}
|
||
|
||
long long RKSparse::GetSparseImageSize(){
|
||
return m_header.blk_sz * m_header.total_blks;
|
||
}
|
||
|
||
bool RKSparse::SparseFile_Download(DWORD dwPos, CRKComm *pComm){
|
||
UINT uiLBATransferSize = (LBA_TRANSFER_SIZE) * 1;
|
||
UINT uiBufferSize = uiLBATransferSize; // buffer 的长度
|
||
UINT uiLBASector = uiLBATransferSize/SECTOR_SIZE;
|
||
UINT uiCurChunk; //当前块的计数
|
||
UINT uiChunkDataSize, uiWriteByte, uiLen, uiBegin, uiFillByte, uiCrc;
|
||
int iRet, i;
|
||
long long uiEntryOffset; //数据的偏移量
|
||
chunk_header chunk;
|
||
PBYTE pBuffer = NULL;
|
||
|
||
uiEntryOffset = sizeof(m_header);
|
||
uiCurChunk = 0;
|
||
uiLen = 0;
|
||
uiWriteByte = 0;
|
||
uiBegin = dwPos;
|
||
|
||
//申请buffer,用来放置要写入的数据
|
||
pBuffer = new BYTE[uiBufferSize];
|
||
if(pBuffer == NULL){
|
||
printf("Failed ==== new Buffer %s:%d.\n", __func__, __LINE__);
|
||
return false;
|
||
}
|
||
|
||
while(uiCurChunk < m_header.total_chunks){
|
||
bool bRet = false;
|
||
bRet = readfile(uiEntryOffset, sizeof(chunk), (PBYTE)&chunk);
|
||
if(!bRet){
|
||
printf("Failed ==== readfile %s:%d.\n", __func__, __LINE__);
|
||
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); //当前chunk 数据长度
|
||
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 (!readfile(uiEntryOffset, uiWriteByte, pBuffer))
|
||
{
|
||
printf("ERROR:get chunk data failed,chunk=%d, %s:%d",uiCurChunk, __func__, __LINE__);
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
|
||
uiEntryOffset += uiWriteByte;
|
||
iRet = pComm->RKU_WriteLBA(uiBegin, uiLen, pBuffer, 0);
|
||
if( iRet!=ERR_SUCCESS )
|
||
{
|
||
printf("ERROR:RKA_SparseFile_Download-->RKU_WriteLBA failed,RetCode(%d),chunk=%d", iRet, uiCurChunk);
|
||
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uiBegin += uiLen;
|
||
//currentByte += uiWriteByte;
|
||
uiChunkDataSize -= uiWriteByte;
|
||
|
||
}
|
||
break;
|
||
case CHUNK_TYPE_FILL:
|
||
uiChunkDataSize = chunk.chunk_sz * m_header.blk_sz;
|
||
if (readfile(uiEntryOffset, 4, (PBYTE)&uiFillByte))
|
||
{
|
||
printf("ERROR:RKA_SparseFile_Download-->get fill byte failed,chunk=%d", 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;
|
||
}
|
||
|
||
uiEntryOffset += uiWriteByte;
|
||
iRet = pComm->RKU_WriteLBA(uiBegin, uiLen, pBuffer, 0);
|
||
|
||
if(iRet != ERR_SUCCESS)
|
||
{
|
||
printf(" ERROR:RKA_SparseFile_Download-->RKU_WriteLBA failed,RetCode(%d),chunk=%d", iRet, uiCurChunk);
|
||
|
||
delete []pBuffer;
|
||
pBuffer = NULL;
|
||
return false;
|
||
}
|
||
uiBegin += uiLen;
|
||
//currentByte += uiWriteByte;
|
||
uiChunkDataSize -= uiWriteByte;
|
||
|
||
}
|
||
break;
|
||
|
||
case CHUNK_TYPE_DONT_CARE:
|
||
uiChunkDataSize = chunk.chunk_sz * m_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 = readfile(uiEntryOffset, 4, (PBYTE)&uiCrc);
|
||
uiEntryOffset += 4;
|
||
break;
|
||
}
|
||
}
|
||
printf("======%s:%d====== success.\n", __func__, __LINE__);
|
||
return true;
|
||
}
|
||
|
||
bool RKSparse::readfile(long long dwOffset, DWORD dwSize, PBYTE lpBuffer){
|
||
|
||
if (dwOffset < 0 || dwSize == 0)
|
||
{
|
||
return false;
|
||
}
|
||
//if ( dwOffset + dwSize > m_fileSize)
|
||
//{
|
||
// return false;
|
||
//}
|
||
|
||
fseeko(m_pFile, dwOffset, SEEK_SET);
|
||
UINT uiActualRead;
|
||
uiActualRead = fread(lpBuffer, 1, dwSize, m_pFile);
|
||
|
||
if (dwSize!=uiActualRead)
|
||
{
|
||
printf("readfile failed.\n");
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void RKSparse::display(){
|
||
printf("in RKSparse display.\n");
|
||
printf("m_header->magic is %x.\n", m_header.magic);
|
||
}
|
||
|