Example #1
0
//Get the item header info
//If the @imgVersion is V2, the item header already stored in @pImgHead, if @imgVersion is V2 or old, also read it into 64K size pImgHead
static const AmlResItemHead_t* _img_unpack_get_item_header(const int imgVersion, const AmlResImgHead_t* pImgHead, int itemIndex, FILE* fdResImg)
{
        const AmlResItemHead_t* pItemNext = NULL;
        AmlResItemHead_t*       tmpItem   = NULL;

        tmpItem  = (AmlResItemHead_t*)(pImgHead + 1);
        tmpItem += itemIndex;

        switch(imgVersion) {
                case AML_RES_IMG_VERSION_V2:
                        pItemNext = tmpItem;
                        break;

                case AML_RES_IMG_VERSION_V1:
                case 0:
                        {
                                const unsigned readSz = fread(tmpItem, 1, ITEM_HEAD_SZ, fdResImg);
                                if(ITEM_HEAD_SZ != readSz){
                                        errorP("Fail to read item head\n");
                                        return NULL;
                                }
                                pItemNext = tmpItem;
                        }
                        break;
                default:
                        break;
        }

        if(IH_MAGIC != pItemNext->magic){
                errorP("Item magic error.\n");
                return NULL;
        }

        return pItemNext;
}
Example #2
0
static int _img_unpack_check_img_header(const AmlResImgHead_t* pImgHead, int* imgVersion, unsigned* imgHeadSz)
{
        int rc = 0;

        rc = memcmp(pImgHead->magic, AML_RES_IMG_V1_MAGIC, AML_RES_IMG_V1_MAGIC_LEN);
        if(rc) {
                const AmlResItemHead_t* pItemHead = (AmlResItemHead_t*)pImgHead;
                if(IH_MAGIC != pItemHead->magic){
                        errorP("magic of oldest img not item header!\n");
                        return __LINE__;
                }
                *imgVersion = 0;
                *imgHeadSz = 0;
        }
        else {
                if(AML_RES_IMG_VERSION_V2 < pImgHead->version){
                        errorP("res-img ver %d not supported\n", pImgHead->version);
                        return __LINE__;
                }
                *imgVersion = pImgHead->version;
                *imgHeadSz      = sizeof(AmlResImgHead_t);
                /*
                 *if(AML_RES_IMG_VERSION_V2 == pImgHead->version){
                 *        *imgHeadSz += pImgHead->imgItemNum * sizeof(AmlResItemHead_t);
                 *}
                 */
        }

        return 0;
}
Example #3
0
/*
 * duplicated item like this, which source is the same file 'boot.PARTITION' but sub_type.main_type are different
 *file="boot.PARTITION"		main_type="PARTITION"		sub_type="boot"
 *file="boot.PARTITION"		main_type="PARTITION"		sub_type="bootbak"
 */
static const ItemInfo* previous_duplicated_item_id(const FileList* headFileList, const FileList* const curFileList, 
        const ItemInfo* headItemInfo, const ItemInfo* curItemInfo)
{
    int itemId = -1;
    int i = 0;

    for(;headFileList != curFileList && headFileList->next; headFileList = headFileList->next)
    {
        int rc = strcmp(curFileList->name, headFileList->name);
        if(!rc)//the file of headFileList is duplicated
        {
            for(; headItemInfo < curItemInfo; headItemInfo++)
            {
                if(!strcmp(headItemInfo->itemMainType, headFileList->main_type) 
                        && !strcmp(headItemInfo->itemSubType, headFileList->sub_type))
                {
                    return headItemInfo;
                }
            }
            errorP("find duplicated file(%s) but previous item not found\n", curFileList->name);
            return NULL;
        }
    }

    return NULL;
}
Example #4
0
static int image_get_next_item(HIMAGE hImage,unsigned int iItem, char* maintype, char* subtype)
{
	FILE* fp = (FILE*)hImage;
	unsigned int nItem = 0;
	if(ImageDecoder->AmlFirmwareImg->crc==0){
		memset(ImageDecoder->AmlFirmwareImg,0,sizeof(AmlFirmwareImg_t));
		fseeko(fp,0,SEEK_SET);
		if(fread(ImageDecoder->AmlFirmwareImg,1, sizeof(AmlFirmwareImg_t),fp) != sizeof(AmlFirmwareImg_t)) {
			fprintf(stderr,"cannot read %u bytes", (unsigned)sizeof(AmlFirmwareImg_t));
			return -1;
		}
	}

	if(iItem >= ImageDecoder->AmlFirmwareImg->itemNum){
        errorP("Item index %u > max %u\n", iItem, ImageDecoder->AmlFirmwareImg->itemNum - 1);
		return -1;
    }
		
	fseeko(fp,sizeof(AmlFirmwareImg_t)+iItem*sizeof(ItemInfo),SEEK_SET);	
	
	ItemInfo AmlItem;
	memset(&AmlItem,0,sizeof(ItemInfo));
	if(fread(&AmlItem,sizeof(ItemInfo), 1,fp) != 1) {
		fprintf(stderr,"image_get_next_item:Read Err [%s]", strerror(errno));
		return -1;
	}

	strncpy(maintype,AmlItem.itemMainType,32);
	strncpy(subtype,AmlItem.itemSubType,32);
    /*debugP("[%s, %s] verify = %d\n", maintype, subtype, AmlItem.verify);*/
	return 0;
}
Example #5
0
static __hdle _find_first_file(const char* const dirPath, WIN32_FIND_DATA& findFileData)
{
    HANDLE hdle = INVALID_HANDLE_VALUE;
    TCHAR szDir[MAX_PATH];
    size_t length_of_arg;
    // Check that the input path plus 3 is not longer than MAX_PATH.
    // Three characters are for the "\*" plus NULL appended below.
    StringCchLength(dirPath, MAX_PATH, &length_of_arg);

    if (length_of_arg > (MAX_PATH - 3))
    {
        _tprintf(TEXT("\nDirectory path is too long.\n"));
        return NULL;
    }

    _tprintf(TEXT("\nTarget directory is %s\n\n"), dirPath);

    // Prepare string for use with FindFile functions.  First, copy the
    // string to a buffer, then append '\*' to the directory name.

    StringCchCopy(szDir, MAX_PATH, dirPath);
    StringCchCat(szDir, MAX_PATH, TEXT("\\*"));

    hdle = FindFirstFile(szDir, &findFileData);
    if(INVALID_HANDLE_VALUE == hdle){
        errorP("Fail to open dir\n");
        return NULL;
    }

    return hdle;
}
Example #6
0
int traverse_dir(const char** const dirPath, __hdle *hdle, char* filePath)
{
    DIR* hDir = (DIR*)*hdle;
    const char* fileName = NULL;

    if(!hDir)
    {
        hDir = opendir(*dirPath);
        if(!hDir){
            errorP("Fail to open dir(%s), strerror(%s)\n", *dirPath, strerror(errno));
            return __LINE__;
        }
        *hdle = hDir;
    }

    do{
        struct dirent* dirEntry = NULL;

        dirEntry = readdir(hDir);
        if(!dirEntry){
            debugP("travese end.\n");
            closedir(hDir);
            return __LINE__;
        }
        fileName = dirEntry->d_name;
    }while(!strcmp(".", fileName) || !strcmp("..", fileName));

    sprintf(filePath, "%s/%s", *dirPath, fileName);
    return 0;
}
Example #7
0
int get_dir_filenums(const char * const dirPath)
{
    WIN32_FIND_DATA findFileData;
    HANDLE hdle = INVALID_HANDLE_VALUE;
    int fileNum = 0;
    int ret = 0;
    TCHAR szDir[MAX_PATH];
    size_t length_of_arg;

    hdle = _find_first_file(dirPath, findFileData);
    if(INVALID_HANDLE_VALUE == hdle){
        errorP("Fail to open dir %s\n", szDir);
        return __LINE__;
    }

    do {
        if(strcmp(findFileData.cFileName, ".") && strcmp(findFileData.cFileName, ".."))
        {
          ++fileNum;
        }
    } while (FindNextFile(hdle, &findFileData));

_ok: 
    if(INVALID_HANDLE_VALUE != hdle)FindClose(hdle);
    return fileNum;
}
Example #8
0
static int do_unpackimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
        void *addr;
        __u32 pos = 0;
        const AmlResItemHead_t *pack_header_p = NULL;
        char env_name[IH_NMLEN*2];
        char env_data[IH_NMLEN*2];
        AmlResImgHead_t* pImgHead = NULL;
        int rc = 0;
        int imgVersion = -1;

        if (argc < 2) {
                cmd_usage(cmdtp);
                return __LINE__;
        }
        addr = (void *)simple_strtoul (argv[1], NULL, 16);

        pImgHead = (AmlResImgHead_t*)addr;
        rc = _img_unpack_check_img_header(pImgHead, &imgVersion, &pos);
        if(rc){
                errorP("Err res header.\n");
                return __LINE__;
        }
        MsgP("ver=%d\n", imgVersion);

        do{
                pack_header_p = (AmlResItemHead_t*)(addr + pos);
                if(IH_MAGIC != pack_header_p->magic){
                        errorP("Item magic error.\n");
                        return __LINE__;
                }

                sprintf(env_name, "%s_offset", pack_header_p->name);
                sprintf(env_data, "0x%x", (unsigned int)(addr+pack_header_p->start));
                setenv(env_name, env_data);

                sprintf(env_name, "%s_size", pack_header_p->name);
                sprintf(env_data, "0x%x", pack_header_p->size);
                setenv(env_name, env_data);

        }while(pos = pack_header_p->next);

        return 0;
}
Example #9
0
//is the item source is duplicated with other item
//i.e, item data is empty
//return value: 0/1 is ok, <0 is failed
static int is_item_backup_for_other_item(HIMAGEITEM hItem, int* backItemId)
{
	ItemInfo *item = (ItemInfo*)hItem;
    if(!hItem){
        errorP("NULL item handle\n");
        return -1;
    }
    *backItemId = item->backUpItemId;
    return item->isBackUpItem;
}
Example #10
0
//@imgVersion: if success, then 0--> oldest version; 1-->img header + n * (item header + item body); 2 --> img header + n * item header + n * item body
static int _img_unpack_check_img_header(FILE* fdResImg, const char* const path_src, 
                int needCheckCrc, AmlResImgHead_t* pImgHead, int* imgVersion)
{
        int ret = 0;
        const unsigned ImgFileSz = get_filesize(path_src);

        if(ImgFileSz <= IMG_HEAD_SZ){
                errorP("file size 0x%x too small\n", ImgFileSz);
                return __LINE__;
        }

        unsigned thisReadSz = ITEM_READ_BUF_SZ > ImgFileSz ? ImgFileSz : ITEM_READ_BUF_SZ;
        unsigned actualReadSz = 0;

        actualReadSz = fread(pImgHead, 1, thisReadSz, fdResImg);
        if(actualReadSz != thisReadSz){
                errorP("Want to read 0x%x, but only read 0x%x\n", thisReadSz, actualReadSz);
                return __LINE__;
        }

        if(!strncmp(AML_RES_IMG_V1_MAGIC, (char*)pImgHead->magic, AML_RES_IMG_V1_MAGIC_LEN))
        {//new version magic matched
                if(ImgFileSz != pImgHead->imgSz){
                        errorP("error, image size in head 0x%x != fileSz 0x%x\n", pImgHead->imgSz, ImgFileSz);
                        return __LINE__;
                }
                if(AML_RES_IMG_VERSION_V2 < pImgHead->version){
                        errorP("Error, version 0x%x not supported\n", pImgHead->version);
                        return __LINE__;
                }
                *imgVersion = pImgHead->version;

                if(needCheckCrc)
                {
                        ret = check_img_crc(fdResImg, 4, pImgHead->crc);
                        if(ret){
                                errorP("Error when check crc\n");
                                return __LINE__;
                        }
                }
                unsigned ImgHeadSz = IMG_HEAD_SZ;
                if(AML_RES_IMG_VERSION_V2 == pImgHead->version) ImgHeadSz += pImgHead->imgItemNum * ITEM_HEAD_SZ;
                fseek(fdResImg, ImgHeadSz, SEEK_SET);//seek escape the image header to prepare for reading item header
        }
        else
        {
                AmlResItemHead_t* pItemHeadInfo = (AmlResItemHead_t*)pImgHead;
                debugP("magic error, try old version image.\n");
                if(IH_MAGIC != pItemHeadInfo->magic){
                        errorP("magic err, old version image header not item header!\n");
                        return __LINE__;
                }
                *imgVersion = 0;
                fseek(fdResImg, 0, SEEK_SET);//seek escape the image header to prepare for reading item header
        }

        debugP("res-img ver is 0x%x\n", *imgVersion);
        return 0;
}
Example #11
0
int traverse_dir(const char** const dirPath, __hdle *hDir, char* filePath)
{
  WIN32_FIND_DATA findFileData;
  HANDLE hdle = INVALID_HANDLE_VALUE;
  int ret = 0;

  if (!*hDir)//not open yet!
  {
      hdle = _find_first_file(*dirPath, findFileData);
      if(INVALID_HANDLE_VALUE == hdle){
          errorP("Fail to find first file in dir(%s)\n", *dirPath);
          return __LINE__;
      }
      *hDir = hdle;
      if(strcmp(".", findFileData.cFileName) && strcmp("..", findFileData.cFileName))goto _ok;
  }

  hdle = *hDir;
  do 
  {
    ret = !FindNextFile(hdle, &findFileData);
    if(ret){
      debugP("Find end.\n");
      FindClose(hdle);
      return __LINE__;
    }
  } while(!strcmp(".", findFileData.cFileName) || !strcmp("..", findFileData.cFileName) );
  
_ok: 
  //debugP("file %s\n", findFileData.cFileName);
  if(MAX_PATH < strlen(findFileData.cFileName)){
    errorP("Buffer samll\n");
    FindClose(hdle);
    return __LINE__;
  }
  sprintf(filePath, "%s\\%s", *dirPath, findFileData.cFileName);
  return ret;
}
Example #12
0
EXPORT
#endif

int image_unpack(const char* imagefile,const char *outpath)
{
	int ret = 0;
	unsigned int itemCountTotal = 0;
	unsigned int nItem = 0;
	unsigned int write_bytes = 0;
	char main_type[32] = {0};
	char sub_type[32] = {0};
	char outfile[512] = {0};
	char cfgfile[128] = {0};
	char buff[256] = {0};
	
	#ifdef BUILD_DLL
	if(ImageDecoder->AmlFirmwareImg == NULL){
		ImageDecoder->AmlFirmwareImg = (AmlFirmwareImg_t*)malloc(sizeof(AmlFirmwareImg_t));
		if(ImageDecoder->AmlFirmwareImg == NULL){
			fprintf(stderr,"not enough memory\n");
			return -1;
		}
	}	
	#endif
	
	if(outpath){
		strcpy(outfile,outpath);
		strcat(outfile,"\\");
		strcpy(cfgfile,outfile);
	}
	strcat(cfgfile,"image.cfg");
    
	HIMAGE hImage = image_open(imagefile);
	if(image_check(hImage) < 0){
		fprintf(stderr,"the image check fail!!\n");
		return -1;
	}else{
		printf("the image check ok!\n");
	}

    itemCountTotal = image_get_item_count(hImage,NULL);
    const unsigned itemCountVerify = image_get_item_count(hImage, "VERIFY");
    const unsigned itemCountNormal = itemCountTotal - itemCountVerify * 2;
    debugP("item cnt:total[%u], normal[%u], verify[%u]\n", itemCountTotal, itemCountNormal, itemCountVerify);
	
    char *unPackBuf = (char*)malloc(RW_MAX_SIZE);
    if(unPackBuf==NULL){
        fprintf(stderr,"allocate memccpy failed  at %s  %d \n", __FILE__,__LINE__);
        return __LINE__;
    }

    FILE *fp_cfg = fopen(cfgfile,"wb+");
    if(fp_cfg==NULL){
        fprintf(stderr,"create image.cfg failed ! [%s] \n",strerror(errno));
        return __LINE__;
    }
    fwrite(TAG_NORMALLIST,1,strlen(TAG_NORMALLIST), fp_cfg);
    fwrite("\r\n", 1, 2, fp_cfg);

    for(nItem = 0; nItem < itemCountTotal; ++nItem)
    {
    	if(image_get_next_item(hImage,nItem,main_type,sub_type) < 0){
    		ret = -1;
    		break;
    	}
        if(!strcmp("VERIFY", main_type))
        {
            continue;//skip verify item
        }
        if(nItem == itemCountNormal)//[List_normal]ends, [List_verify] starts
        {
            fwrite("\r\n", 1, 2, fp_cfg);
            fwrite(TAG_VERIFYLIST,1,strlen(TAG_VERIFYLIST), fp_cfg);
            fwrite("\r\n", 1, 2, fp_cfg);
        }

    	memset(outfile,0,64);
    	if(outpath){
    		strcpy(outfile,outpath);
			strcat(outfile,"/");
    	}

    	strcat(outfile,sub_type);
    	strcat(outfile,".");
    	strcat(outfile,main_type);
    	debugP("out file: %s  \n",outfile);//sub_type.main_type

	    HIMAGEITEM hItem = image_open_item(hImage,main_type,sub_type);
	    if(hItem == NULL){
	    	fprintf(stderr,"open item[%s, %s] failed!\n", main_type, sub_type);
	    	ret = -1;
	    	break;
	    }

        int backUpItemId = 0;
        int itemIsBacked = is_item_backup_for_other_item(hItem, &backUpItemId);
        if(itemIsBacked < 0){
            errorP("Fail to in test is_item_backup_for_other_item\n");
            ret = __LINE__; break;
        }
        if(itemIsBacked)//item is back item
        {
            char* CfgLine = (char*)unPackBuf;
            char srcBackItemMainType[32];
            char srcBackItemSubType[32];

            if(image_get_next_item(hImage, backUpItemId, srcBackItemMainType, srcBackItemSubType)){
                errorP("Fail to get the backui item head\n");
                ret = __LINE__; break;
            }
            sprintf(CfgLine, IMG_CFG_LINE, srcBackItemSubType, srcBackItemMainType, main_type, sub_type);
            fwrite(CfgLine,1,strlen(CfgLine), fp_cfg);
            continue;
        }

    	FILE *fp_out = fopen(outfile,"wb+");
	    if(fp_out == NULL){
	    	fprintf(stderr,"failed to create out file : %s \n",outfile);
			ret = -1;
			break;
	    }

	    while((write_bytes = image_read_item_data(hImage, hItem, unPackBuf, RW_MAX_SIZE))>0)
        {
	    	if(fwrite(unPackBuf,1,write_bytes,fp_out)!=write_bytes){
	    		fprintf(stderr,"write to image file fail! [%s] \n",strerror(errno));
	    		ret = -1;
	    		break;
	    	}
	    }
	    fclose(fp_out);
	    image_close_item(hItem);

        char* CfgLine = (char*)unPackBuf;
        sprintf(CfgLine, IMG_CFG_LINE, sub_type, main_type, main_type, sub_type);
        fwrite(CfgLine,1,strlen(CfgLine), fp_cfg);
    }
    free(unPackBuf);
    fclose(fp_cfg); fp_cfg = NULL;

	#ifdef BUILD_DLL
	if(ImageDecoder->AmlFirmwareImg){
		free(ImageDecoder->AmlFirmwareImg);
		ImageDecoder->AmlFirmwareImg = NULL;
	}	
	#endif
	return ret;
}
Example #13
0
EXPORT
#endif
int image_pack(const char* cfg_file, const char* src_dir ,const char* target_file)
{
	struct stat64 s;
	FILE* fp_read = NULL;
	FILE* fp_write  = NULL;
	char *tmp;
	int count = 0;
    size_t write_bytes = 0;
    ItemInfo* totalItemInfo = NULL;
	char *buff = NULL;
	int ret = 0;
    ItemInfo*  AmlItem = NULL;

	if(!cfg_file||!src_dir||!target_file){
		fprintf(stderr,"invalid param! \n");
		return -1;
	}

	if(stat64(cfg_file, &s)){
		fprintf(stderr,"could not stat '%s'\n", cfg_file);
		return -1;
	}

	fp_read = fopen(cfg_file, "rb");
    if (fp_read == NULL){
    	fprintf(stderr,"failed to open canned file \n");
    	return -1;
    }

    tmp = (char*) malloc(s.st_size);
    if(tmp == NULL) {
    	fprintf(stderr,"allocate memccpy failed  at %s  %d \n", __FILE__,__LINE__);
    	free(tmp);
    	return -1;
    }

    if(fread(tmp,1, s.st_size,fp_read) != s.st_size) {
    	fprintf(stderr,"file read error [%s] \n", strerror(errno));
    	fclose(fp_read);
    	free(tmp);
    	return -1;
    }
    fclose(fp_read);

    if(image_cfg_parse(tmp,s.st_size) < 0){
    	fprintf(stderr,"image_cfg_parse error! \n");
    	free(tmp);
    	return -1;
    }
    free(tmp); tmp = NULL;

    if(image_check_files(src_dir)<0){
    	fprintf(stderr,"image check file error! \n");
    	return -1;
    }

	fp_write = fopen(target_file, "wb+");
	if (fp_write == NULL){
		fprintf(stderr,"failed to create target file! \n");
		return -1;
	}
    AmlFirmwareImg_t aAmlImage;
	AmlFirmwareImg_t  *FirmwareImg = &aAmlImage;
	memset(FirmwareImg,0,sizeof(AmlFirmwareImg_t));

    if(fwrite(FirmwareImg,1, sizeof(AmlFirmwareImg_t),fp_write) != sizeof(AmlFirmwareImg_t)) {
    	fprintf(stderr,"cannot write %u bytes\n", (unsigned)sizeof(AmlFirmwareImg_t));
    	fclose(fp_write);
    	return -1;
    }

    const int TotalItemCnt = ImageDecoder->gItemCount;
    debugP("TotalItemCnt %d\n", TotalItemCnt);
    totalItemInfo = new ItemInfo[TotalItemCnt];

	memset(totalItemInfo,0,sizeof(ItemInfo) * TotalItemCnt);
    write_bytes = fwrite(totalItemInfo,1, sizeof(ItemInfo) * TotalItemCnt, fp_write);
	if(write_bytes != sizeof(ItemInfo)* TotalItemCnt){
        fprintf(stderr,"cannot write %d bytes \n", (int)sizeof(ItemInfo));
        ret = __LINE__; goto _exit;
    }

	buff = new char[RW_MAX_SIZE];
	if(buff==NULL){
		fprintf(stderr,"allocate memccpy failed  at %s  %d \n", __FILE__,__LINE__);
        ret = __LINE__; goto _exit;
	}

    //For each list:
    //1, create item info;  2,pack the item data; 3, crate verify item info; 4, pack verify data
    AmlItem = totalItemInfo;
    for(const FileList *list = ImageDecoder->gImageCfg.file_list;
            list; list = list->next, AmlItem++, count++)
	{
        struct stat64 info;
        char path[256]={0};

		memset(path,0,256);
		strcpy(path,src_dir);
		strcat(path,list->name);
		printf("pack [%-12s, %16s] from (%s)\n", list->main_type, list->sub_type, path);

        fp_read = fopen(path,"rb");
        if(fp_read == NULL){
            fprintf(stderr,"failed to open source file : %s \n",path);
            ret = -1;
            break;
        }

        if(stat64(path,&info)<0){
			fprintf(stderr,"stat %s failed!\n",path);
			ret =  -1;
			break;
		}
		AmlItem->itemSz = info.st_size;
		AmlItem->itemId = count;
		AmlItem->verify = 0;//1 if a verify item
		strcpy(AmlItem->itemMainType,list->main_type);
		strcpy(AmlItem->itemSubType,list->sub_type);

        const ItemInfo* foundSamFileItemInfo = previous_duplicated_item_id(ImageDecoder->gImageCfg.file_list, list, totalItemInfo, AmlItem);
        if(foundSamFileItemInfo)//this item is source from a duplicated file item
        {
            AmlItem->offsetInImage  = foundSamFileItemInfo->offsetInImage;
            AmlItem->fileType       = foundSamFileItemInfo->fileType;
            AmlItem->isBackUpItem   = 1;
            AmlItem->backUpItemId   = foundSamFileItemInfo->itemId;
        }
        else
        {
            AmlItem->offsetInImage = ftello(fp_write);
            if(AmlItem->offsetInImage % ITEM_ALGIN){
                AmlItem->offsetInImage += ITEM_ALGIN - AmlItem->offsetInImage % ITEM_ALGIN;
            }

            fseeko(fp_read,0,SEEK_SET);
            write_bytes = fread(buff,1,RW_MAX_SIZE,fp_read);
            if(optimus_simg_probe(buff,RW_HEAD_SIZE) == 0){
                AmlItem->fileType = IMAGE_ITEM_TYPE_NORMAL;
            }else{
                AmlItem->fileType = IMAGE_ITEM_TYPE_SPARSE;
            }

            //Following create the item data
            //
            fseeko(fp_write,AmlItem->offsetInImage,SEEK_SET);
            fseeko(fp_read,0,SEEK_SET);
            while((write_bytes = fread(buff,1,RW_MAX_SIZE,fp_read))>0)
            {
                if(fwrite(buff,1,write_bytes,fp_write)!=write_bytes){
                    fprintf(stderr,"write to image file fail! [%s] \n",strerror(errno));
                    ret = -1;
                    break;
                }
            }
            fclose(fp_read);
            if(ret < 0)
                break;
        }

		if(list->verify)
		{
            ++count;
            ++AmlItem;

			AmlItem->itemSz = 48;
			AmlItem->itemId = count;
			strcpy(AmlItem->itemMainType,"VERIFY");
			strcpy(AmlItem->itemSubType,list->sub_type);
			AmlItem->fileType = IMAGE_ITEM_TYPE_NORMAL;
		    AmlItem->verify = 1;

            if(foundSamFileItemInfo)//the source file is already packed 
            {
                const ItemInfo* verfiyItem4_foundItem = foundSamFileItemInfo + 1;
                //test if the next item following foundSamFileItemInfo is verify item
                if(!strcmp(foundSamFileItemInfo->itemSubType, verfiyItem4_foundItem->itemSubType) 
                        && !strcmp(verfiyItem4_foundItem->itemMainType, AmlItem->itemMainType))//"VERIFY"
                {
                    AmlItem->offsetInImage = verfiyItem4_foundItem->offsetInImage;
                    AmlItem->isBackUpItem   = 1;
                    AmlItem->backUpItemId   = verfiyItem4_foundItem->itemId;
                    continue;//skip followings
                }
            }

            AmlItem->offsetInImage = ftello(fp_write);
            if(AmlItem->offsetInImage % ITEM_ALGIN){
                AmlItem->offsetInImage += ITEM_ALGIN - AmlItem->offsetInImage % ITEM_ALGIN;
            }

		    memset(buff,0,48);
		    gen_sha1sum_verify(path, buff);

		    fseeko(fp_write,AmlItem->offsetInImage,SEEK_SET);
			if(fwrite(buff,1,48,fp_write)!=48){
				fprintf(stderr,"write verify data to image file fail! [%s] \n",strerror(errno));
				ret = -1;
				break;
			}
		}
	}
	free(buff); buff = 0;

	FirmwareImg->magic = IMAGE_MAGIC;
	FirmwareImg->version = VERSION;

	FirmwareImg->itemNum = count;
	fseeko(fp_write, 0L, SEEK_END);
	FirmwareImg->imageSz = ftello(fp_write);
	FirmwareImg->itemAlginSize = 4;
	fseeko(fp_write,0L,SEEK_SET);
    if(fwrite(FirmwareImg,1, sizeof(AmlFirmwareImg_t),fp_write) != sizeof(AmlFirmwareImg_t)) {
    	fprintf(stderr,"cannot write %u bytes [%s] [0x%p]\n", 
                (unsigned)sizeof(AmlFirmwareImg_t), strerror(errno), fp_write);
    	ret = -1;
    }

    write_bytes = fwrite(totalItemInfo, 1, sizeof(ItemInfo) * TotalItemCnt, fp_write);
    if(write_bytes != sizeof(ItemInfo) * TotalItemCnt){
        errorP("fail to update item info\n");
        ret = __LINE__; goto _exit;
    }

	FirmwareImg->crc = calc_img_crc(fp_write,FirmwareImg->itemAlginSize);
	fseeko(fp_write,0L,SEEK_SET);
    if(fwrite(&(FirmwareImg->crc),1,FirmwareImg->itemAlginSize,fp_write) != FirmwareImg->itemAlginSize) {
    	fprintf(stderr,"cannot write crc32 [0x%x] [%s] \n",FirmwareImg->crc ,strerror(errno));
    	ret = -1;
    }
	printf("Size=0x%llxB[%lluM], crc=0x%x, Install image[%s] OK\n",
            FirmwareImg->imageSz, (FirmwareImg->imageSz>>20), FirmwareImg->crc, target_file);

_exit:
    if(fp_write)fclose(fp_write), fp_write = NULL;
    if(totalItemInfo)delete[] totalItemInfo, totalItemInfo = NULL;
    if(buff) delete[] buff, buff = NULL;

    return ret;
}
Example #14
0
/*
 * 1,
 */
static int _img_pack(const char** const path_src, const char* const packedImg, 
        pFunc_getFile getFile, const int totalFileNum)
{
        FILE *fd_src = NULL;
        FILE *fd_dest = NULL;
        unsigned int pos = 0;
        char file_path[MAX_PATH];
        const char *filename = NULL;
        unsigned imageSz = 0;
        const unsigned BufSz = ITEM_READ_BUF_SZ;
        char* itemBuf = NULL;
        unsigned thisWriteLen = 0;
        unsigned actualWriteLen = 0;
        int ret = 0;
        __hdle hDir = NULL;
        const unsigned   itemAlignSz  = AML_RES_IMG_ITEM_ALIGN_SZ;
        const unsigned   itemAlignMod = itemAlignSz - 1;
        const unsigned   itemSzAlignMask = ~itemAlignMod;
        const unsigned   totalItemNum = totalFileNum ? totalFileNum : get_dir_filenums(*path_src);
        const unsigned   HeadLen    = IMG_HEAD_SZ + ITEM_HEAD_SZ * totalItemNum;

        if(HeadLen > BufSz){
                errorP("head size 0x%x > max(0x%x)\n", HeadLen, BufSz); return __LINE__;
        }
        fd_dest = fopen(packedImg, "wb+");
        if(NULL == fd_dest)	{
                fprintf(stderr,"open %s failed: %s\n", packedImg, strerror(errno));
                return __LINE__;
        }

        itemBuf = new char[BufSz * 2];
        if(!itemBuf){
                errorP("Exception: fail to alloc buuffer\n");
                fclose(fd_dest); return __LINE__;
        }
        memset(itemBuf, 0, BufSz*2);
        AmlResImgHead_t* const aAmlResImgHead = (AmlResImgHead_t*)(itemBuf + BufSz);

        actualWriteLen = fwrite(aAmlResImgHead, 1, HeadLen, fd_dest);
        if(actualWriteLen != HeadLen){
                errorP("fail to write head, want 0x%x, but 0x%x\n", HeadLen, actualWriteLen);
                fclose(fd_dest); delete[] itemBuf;
                return __LINE__;
        }
        imageSz += HeadLen; //Increase imageSz after pack each item
        AmlResItemHead_t*       pItemHeadInfo           = (AmlResItemHead_t*)(aAmlResImgHead + 1);
        AmlResItemHead_t* const pFirstItemHeadInfo      = pItemHeadInfo;

        debugP("item num %d\n", totalItemNum);
        //for each loop: first create item header and pack it, second pack the item data
        //Fill the item head, 1) magic, 2)data offset, 3)next head start offset
        for(unsigned itemIndex = 0; itemIndex < totalItemNum; ++itemIndex)
        {
                char filePath[MAX_PATH*2];

                if(totalFileNum)//File list mode
                {
                        if((*getFile)(path_src, (__hdle*)itemIndex, filePath)) {
                                break;
                        }
                }
                else
                {//file directory mode
                        if((*getFile)(path_src, &hDir, filePath)) {
                                break;
                        }
                }
                const size_t itemSz = get_filesize(filePath);
                const char*  itemName = get_filename(filePath);
                const unsigned itemBodyOccupySz =  (itemSz & itemSzAlignMask) + itemAlignSz;
                const unsigned itemStuffSz      = itemBodyOccupySz - itemSz;

                if(IH_NMLEN - 1 < strlen(itemName)){
                        errorP("Item name %s len %d > max(%d)\n", itemName, (int)strlen(itemName), IH_NMLEN - 1);
                        ret = __LINE__; goto _exit;
                }
                pItemHeadInfo->magic = IH_MAGIC;
                pItemHeadInfo->size = itemSz;
                //imageSz += ITEM_HEAD_SZ;//not needed yet as all item_head moves to image header
                pItemHeadInfo->start = imageSz;
                pItemHeadInfo->next  =  (char*)(pItemHeadInfo + 1) - (char*)aAmlResImgHead;
                pItemHeadInfo->index = itemIndex;
                imageSz   += itemBodyOccupySz;
                pItemHeadInfo->nums   = totalItemNum;
                memcpy(pItemHeadInfo->name, itemName, strlen(itemName));
                debugP("pack item [%s]\n", itemName);
                ++pItemHeadInfo;//prepare for next item 

                fd_src = fopen(filePath, "rb");
                if(!fd_src){
                        errorP("Fail to open file [%s], strerror[%s]\n", filePath, strerror(errno));
                        ret = __LINE__; goto _exit;
                }
                for(size_t itemWriteLen = 0; itemWriteLen < itemSz; itemWriteLen += thisWriteLen)
                {
                        size_t leftLen = itemSz - itemWriteLen;

                        thisWriteLen = leftLen > BufSz ? BufSz : leftLen;
                        actualWriteLen = fread(itemBuf, 1, thisWriteLen, fd_src);
                        if(actualWriteLen != thisWriteLen){
                                errorP("Want to read 0x%x but actual 0x%x, at itemWriteLen 0x%x, leftLen 0x%x\n", 
                                                thisWriteLen, actualWriteLen, (unsigned)itemWriteLen, (unsigned)leftLen);
                                ret = __LINE__; goto _exit;
                        }
                        actualWriteLen = fwrite(itemBuf, 1, thisWriteLen, fd_dest);
                        if(actualWriteLen != thisWriteLen){
                                errorP("Want to write 0x%x but actual 0x%x\n", thisWriteLen, actualWriteLen);
                                ret = __LINE__; goto _exit;
                        }
                }
                fclose(fd_src), fd_src = NULL;
                memset(itemBuf, 0, itemStuffSz);
                thisWriteLen = itemStuffSz;
                actualWriteLen = fwrite(itemBuf, 1, thisWriteLen, fd_dest);
                if(actualWriteLen != thisWriteLen){
                        errorP("Want to write 0x%x, but 0x%x\n", thisWriteLen, actualWriteLen);
                        ret = __LINE__; goto _exit;
                }
        }
        (--pItemHeadInfo)->next = 0;

        //Create the header 
        aAmlResImgHead->version = AML_RES_IMG_VERSION_V2;
        memcpy(&aAmlResImgHead->magic[0], AML_RES_IMG_V1_MAGIC, AML_RES_IMG_V1_MAGIC_LEN);
        aAmlResImgHead->imgSz       = imageSz;
        aAmlResImgHead->imgItemNum  = totalItemNum;
        aAmlResImgHead->alignSz     = itemAlignSz;
        aAmlResImgHead->crc         = 0;
        //
        //Seek to file header to correct the header
        fseek(fd_dest, 0, SEEK_SET);
        actualWriteLen = fwrite(aAmlResImgHead, 1, HeadLen, fd_dest);
        if(actualWriteLen != HeadLen){
                errorP("Want to write 0x%x, but 0x%x\n", HeadLen, actualWriteLen);
                ret = __LINE__; goto _exit;
        }

        aAmlResImgHead->crc = calc_img_crc(fd_dest, 4);//Gen crc32
        fseek(fd_dest, 0, SEEK_SET);
        actualWriteLen = fwrite(&aAmlResImgHead->crc, 1, 4, fd_dest);
        if(4 != actualWriteLen){
                errorP("Want to write 4, but %d\n", actualWriteLen);
                ret = __LINE__; goto _exit;
        }

_exit:
        if(itemBuf) delete[] itemBuf, itemBuf = NULL;
        if(fd_src) fclose(fd_src), fd_src = NULL;
        if(fd_dest) fclose(fd_dest), fd_dest = NULL;
        return ret;
}
Example #15
0
DLL_API
#endif// #ifdef BUILD_DLL
int res_img_unpack(const char* const path_src, const char* const unPackDirPath, int needCheckCrc)
{
        char* itemReadBuf = NULL;
        FILE* fdResImg = NULL;
        int ret = 0;
        AmlResImgHead_t* pImgHead = NULL;
        int imgVersion = -1;

        fdResImg = fopen(path_src, "rb");
        if(!fdResImg){
                errorP("Fail to open res image at path %s\n", path_src);
                return __LINE__;
        }

        itemReadBuf = new char[ITEM_READ_BUF_SZ * 2];
        if(!itemReadBuf){
                errorP("Fail to new buffer at size 0x%x\n", ITEM_READ_BUF_SZ*2);
                fclose(fdResImg), fdResImg = NULL; return __LINE__;
        }
        pImgHead = (AmlResImgHead_t*)(itemReadBuf + ITEM_READ_BUF_SZ);

        ret = _img_unpack_check_img_header(fdResImg, path_src, needCheckCrc, pImgHead, &imgVersion);
        if(ret){
                errorP("Fail at check image header\n");
                delete[] itemReadBuf, itemReadBuf = NULL;
                fclose(fdResImg), fdResImg = NULL;
                return __LINE__;
        }

        //for each loop: 
        //    1, read item body and save as file; 
        //    2, get next item head
        const unsigned   itemAlignSz  = AML_RES_IMG_ITEM_ALIGN_SZ;
        const unsigned   itemAlignMod = itemAlignSz - 1;
        const unsigned   itemSzAlignMask = ~itemAlignMod;
        unsigned totalReadItemNum = 0;
        const AmlResItemHead_t* pItemHead = NULL;

        do{
                char itemFullPath[MAX_PATH*2];//TODO:512 is enough ??
                FILE* fp_item = NULL;

                pItemHead =  _img_unpack_get_item_header(imgVersion, pImgHead, totalReadItemNum++, fdResImg);
                if(!pItemHead){
                        errorP("Fail to get item header at index %d\n", totalReadItemNum - 1);
                        goto _exit;
                }

                sprintf(itemFullPath, "%s/%s", unPackDirPath, pItemHead->name);
                debugP("item %s\n", itemFullPath);

                fp_item = fopen(itemFullPath, "wb");
                if(!fp_item){
                        errorP("Fail to create file %s, strerror(%s)\n", itemFullPath, strerror(errno));
                        ret = __LINE__; goto _exit;
                }

                const unsigned thisItemBodySz = pItemHead->size; 
                const unsigned thisItemBodyOccupySz =  (thisItemBodySz & itemSzAlignMask) + itemAlignSz;
                const unsigned stuffLen       = thisItemBodyOccupySz - thisItemBodySz;
                
                for(unsigned itemTotalReadLen = 0; itemTotalReadLen < thisItemBodyOccupySz; )
                {
                        const unsigned leftLen = thisItemBodyOccupySz - itemTotalReadLen;
                        const unsigned thisReadSz = min(leftLen, ITEM_READ_BUF_SZ);

                        unsigned actualReadSz = fread(itemReadBuf, 1, thisReadSz, fdResImg);
                        if(thisReadSz != actualReadSz){
                                errorP("thisReadSz 0x%x != actualReadSz 0x%x\n", thisReadSz, actualReadSz);
                                ret = __LINE__;goto _exit;
                        }
                        itemTotalReadLen += thisReadSz;

                        const unsigned thisWriteSz = itemTotalReadLen < thisItemBodySz ? thisReadSz : (thisReadSz - stuffLen);
                        actualReadSz = fwrite(itemReadBuf, 1, thisWriteSz, fp_item);
                        if(thisWriteSz != actualReadSz){
                                errorP("want write 0x%x, but 0x%x\n", thisWriteSz, actualReadSz);
                                ret = __LINE__;goto _exit;
                        }

                }
                fclose(fp_item), fp_item = NULL;

        }while(pItemHead->next);


_exit:
        if(itemReadBuf)delete[] itemReadBuf, itemReadBuf = NULL;
        if(fdResImg)fclose(fdResImg), fdResImg = NULL;
        return ret;
}