[C语言] 联想手机szb格式的制作工具,部分开源代码(仅提供程序思想);

news/2024/12/4 18:29:11/
/** =====================================================================================**       Filename:  szbtool.c**    Description:  联想手机szb格式的制作工具,部分开源代码(仅提供程序思想);**        Version:  1.0*        Created:  2013年03月25日 01时46分16秒*       Revision:  none*       Compiler:  gcc**         Author:  linkscue (scue), *   Organization:  ** =====================================================================================*/
#include    <stdlib.h>
#include    <stdio.h>
#include    <string.h>
#include    <unistd.h>
#include    <fcntl.h>
#include    <time.h>extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;#define u8 unsigned char
#define u32 unsigned int
#define u16 unsigned short
#define INFOSIZE 256
#define BUFFER_SIZE 1024typedef struct {
/* * 保密信息:szb文件0~12字节* */
}szb_header_t;typedef struct {
/* * 保密信息:szb文件12~256字节*/
}szb_head_t;typedef struct {
/** 保密信息:szb文件的结构体*/
}szb_info;typedef struct{
/* *保密信息:存放image信息的结构体* */
}szb_images_t;/*获取文件长度*/
long getSize( FILE *fp )
{long int save_pos;                          /* 保存当前文件指针 */long size_of_file;                          /* 保存文件的大小 */save_pos = ftell( fp );                     /* 暂存当前文件指针位置 */fseek( fp, 0L, SEEK_END );                  /* 从文件开始位置移动至文件结尾 */size_of_file = ftell( fp );                 /* 获取文件指针位置 */fseek( fp, save_pos, SEEK_SET );            /* 还原之前的文件指针位置 */return( size_of_file );                     /* 返回文件大小数值 */
}unsigned int getSzbSum(char *file){
/* *保密信息:获取szb文件校验码* */return sum;                    }/*计算一个文件的CRC校验*/
unsigned int getSum(FILE *fp)
{
/* *保密信息:获取image文件校验码* */return sum;                                 /* 这里的检验和的值是正确的 */
}/* 分解szb函数 */
void splitFile(char *file){FILE *fd = NULL;FILE *ft = NULL;int i;get_szb_info(file);                         /* 显示szb文件信息 */if ( (fd=fopen(file,"rb")) == NULL ) {      /* 打开文件进行操作 */printf ( "Extract szb file, open %s failure!\n", file );exit(1);}fseek( fd, 0, SEEK_SET );                   /* 重新定向文件指针位置 */u32 imagecount = 0;fseek( fd, 84, SEEK_SET );                  /* 略过前边的84字节 */fscanf( fd,"%4c", &imagecount );            /* 获取镜像文件个数 */fseek( fd, 168, SEEK_CUR );                 /* 总共略过前边的256字节的Header信息 */szb_images_t images[10];memset(images,0x00,sizeof(images));for ( i=0; i < imagecount ; i++ ){          fscanf(fd,"%64c",&images[i].filename);      /* 获取得文件名称 */fscanf(fd,"%32c",&images[i].partname);fscanf(fd,"%4c",&images[i].checksum);fscanf(fd,"%4c",&images[i].timestamp);fscanf(fd,"%4c",&images[i].imageoffset);    /* 获取偏移位置 */fscanf(fd,"%4c",&images[i].imagesize);      /* 获取镜像文件的大小 */fscanf(fd,"%4c",&images[i].eraseflag);fscanf(fd,"%4c",&images[i].writeflag);fscanf(fd,"%136c",&images[i].reserve);}//开始分解数据;int size,n,offset,fp_local,end;unsigned char imagename[32]="";unsigned char buffer[BUFFER_SIZE];              /* 创建缓冲区 */strncpy(buffer,"",sizeof(buffer));              /* 清空缓冲区内容 */for( i=0; i < imagecount ; i++ ){strncpy(imagename, images[i].filename, sizeof(imagename));offset=images[i].imageoffset;size=images[i].imagesize;end=(offset+size);if ( size != 0 ) {if ( ( ft=fopen(imagename,"wb") ) == NULL ){printf("Extract szb file, open %s failure!\n",imagename);}fseek( fd, offset, SEEK_SET);                /* 跳转至数据段 */printf("Extract %s..\n",imagename);while ( fp_local !=  end )  {n  = fread(buffer,1, sizeof(buffer), fd);fwrite(buffer, n, 1, ft);fp_local=ftell(fd);}}}fclose(fd);printf("Extract szb file done!\n");
}/* 在尾部追加二进制文件(cat a >> b) */
void appendFile(char *fp, char *body) { int n=0;FILE *in,*out;u8 buffer[BUFFER_SIZE];if ( (in = fopen(fp, "rb")) == NULL){printf ( "Open in file failure!\n" );exit(1);}if ( (out=fopen( body , "ab")) == NULL ){printf ( "Open out file failure!\n" );exit(1);}while (!feof(in)) {n = fread(buffer, 1, BUFFER_SIZE, in);fwrite(buffer, 1, n, out);}fclose(in);fclose(out);
}/* 复制一个文件至另一个文件位置 */
//void copyFile(char *from, char *to){
//    FILE * outfile, *infile;
//    infile = fopen(from, "rb");
//    outfile = fopen(to, "wb" );
//    unsigned char buf[BUFFER_SIZE];
//    if( outfile == NULL || infile == NULL )
//    {
//        printf("Copy file failure!");
//        exit(1);
//    }   
//    int rc;
//    while( (rc = fread(buf,sizeof(unsigned char), BUFFER_SIZE ,infile)) != 0 )
//    {
//        fwrite( buf, sizeof( unsigned char ), rc, outfile );
//    } 
////    sleep(0.1);
//    fclose(infile);
//    fclose(outfile);
//}/* 合并两个文件至一个文件 (cat a b > c) */
//void mergeFile(char *fp1,char *fp2,char *name){
//    FILE *fd1,*fd2,*fp3;
//    unsigned char buf[BUFFER_SIZE];
//    char filename[100];
//    strncpy(filename,name,sizeof(filename));
//    int rc1,rc2;
//    fd1 = fopen(fp1,"rb");
//    fd2 = fopen(fp2,"rb");
//    fp3 = fopen(filename, "wb" );
//    while( (rc1 = fread(buf,sizeof(unsigned char), BUFFER_SIZE,fd1)) != 0 )
//    {
//        fwrite( buf, sizeof( unsigned char ), rc1, fp3 );
//    } 
//    while( (rc2 = fread(buf,sizeof(unsigned char), BUFFER_SIZE,fd2)) != 0 )
//    {
//        fwrite( buf, sizeof( unsigned char ), rc2, fp3 );
//    } 
//    sleep(0.1);
//    fclose(fd1);
//    fclose(fd2);
//    fclose(fp3);
//}/* appendImage(szb文件, image文件,文件名称,分区位置,偏移量,索引位置) */
u32 appendImage(char *szb, char *file, char *filename, char *partname, u32 offset, int index){FILE *fp,*fb;if((fp=fopen(file,"rb")) == NULL){printf ( "Open %s failure!\n",filename );exit(1);}szb_images_t image;strncpy(image.filename, filename, sizeof(image.filename));strncpy(image.partname, partname, sizeof(image.partname));strncpy(image.reserve, "", sizeof(image.reserve));time(&image.timestamp);image.imageoffset=offset;image.imagesize=getSize(fp);image.checksum=getSum(fp);image.eraseflag=1;image.writeflag=1;fclose(fp);printf("Adding: %-12sOffset: 0x%08x Checksum: 0x%08x\n",image.partname, image.imageoffset, image.checksum);if ( (fb=fopen(szb, "rb+")) == NULL) {printf(" append %s to szb file, open szb file failure!\n", file);exit(1);}fseek( fb, ( index * INFOSIZE ), SEEK_SET );     /* 移动文件指针的位置 */fwrite(&image.filename, sizeof(image.filename), 1, fb);           /* 向szb文件写入Image的相关信息 */fwrite(&image.partname, sizeof(image.partname), 1, fb);           /* 向szb文件写入Image的相关信息 */fwrite(&image.checksum, sizeof(image.checksum), 1, fb);           /* 向szb文件写入Image的相关信息 */fwrite(&image.timestamp, sizeof(image.timestamp), 1, fb);         /* 向szb文件写入Image的相关信息 */fwrite(&image.imageoffset, sizeof(image.imageoffset), 1, fb);     /* 向szb文件写入Image的相关信息 */fwrite(&image.imagesize, sizeof(image.imagesize), 1, fb);         /* 向szb文件写入Image的相关信息 */fwrite(&image.eraseflag, sizeof(image.eraseflag), 1, fb);         /* 向szb文件写入Image的相关信息 */fwrite(&image.writeflag, sizeof(image.writeflag), 1, fb);         /* 向szb文件写入Image的相关信息 */fwrite(&image.reserve, sizeof(image.reserve), 1, fb);             /* 向szb文件写入Image的相关信息 */fclose(fb);                                   /* 向szb文件写完Image信息后关闭 */appendFile(file, szb);                        /* 向szb文件的尾部添加image数据 */return (image.imagesize+image.imageoffset);   /* 返回一个偏移数据,方便之后的判断 */
}void get_szb_info(char *file){FILE *fp;int i,count;szb_info info;if ( (fp=fopen(file, "rb"))  == NULL ) {/* code */}fscanf(fp,"%8c",&info.magic);/* *保密信息: 获取szb头部信息* */fscanf(fp,"%136c",&info.reserve);u8 magic[]="LmSzBfMt";if ( strstr(info.magic,magic) == NULL ){printf ( "This file not in szb format, abort!\n" );exit(1);}struct tm *ptr;                             /* 格式化时间输出 */time_t lt;unsigned int times=info.timestamp;char str[80];lt=times;ptr=localtime(&lt);strftime(str,100,"%F%X",ptr);printf ( "\n" );printf ( "Header:\n" );printf ( "Checksum:\t0x%08x\n",info.checksum );printf ( "Size:\t\t0x%08x\n",info.filesize );printf ( "Author:\t\t%s\n",info.author );printf ( "Version:\t%s\n",info.version );printf ( "Times:\t\t%s\n",str );printf ( "Counts:\t\t0x%x\n",info.imagecount );count=info.imagecount;szb_images_t images[10];printf ( "\n" );printf ( "Images:\n" );for ( i=0; i < info.imagecount ; i++ ){fscanf(fp,"%64c",&images[i].filename);fscanf(fp,"%32c",&images[i].partname);fscanf(fp,"%4c",&images[i].checksum);fscanf(fp,"%4c",&images[i].timestamp);fscanf(fp,"%4c",&images[i].imageoffset);fscanf(fp,"%4c",&images[i].imagesize);fscanf(fp,"%4c",&images[i].eraseflag);fscanf(fp,"%4c",&images[i].writeflag);fscanf(fp,"%136c",&images[i].reserve);if ( strlen(images[i].filename) != 0 ){printf ( "Position: %-10sOffset: 0x%08x  Checksum: 0x%08x\n",images[i].partname,  images[i].imageoffset, images[i].checksum );}else{printf ( "Earse:    %-10sCaution!\n",images[i].partname);}}printf ( "\n" );fclose(fp);
}/* 显示szbtool作者信息 */
void author_info(){  printf ( "\n" );printf ( "===============================================================\n" );printf ( "          Welcome to use Lenovo K860/K860i szbtool!    \n" );printf ( "\n" );printf ( "                                    -- version: 0.14       \n" );printf ( "                                    -- author:  linkscue   \n" );printf ( "===============================================================\n" );
}
/* 显示使用帮助 */
void usage(){  printf ( "\n" );printf ( "---------------------------------------------------------------\n" );printf ( "usage:\n" );printf ( "szbtool -b uboot      # add uboot.bin\n" );printf ( "szbtool -k boot       # add boot.img\n" );printf ( "szbtool -r recovery   # add recovery.img\n" );printf ( "szbtool -s system     # add system.img\n" );printf ( "szbtool -c cpimage    # add cpimage.img\n" );printf ( "szbtool -p preload    # add preload.img\n" );printf ( "szbtool -d userdata   # add userdata.img\n" );printf ( "szbtool -e erase      # erase data & cache space\n" );printf ( "szbtool -a author     # specify author\n" );printf ( "szbtool -v version    # specify version\n" );printf ( "szbtool -i szb        # szb information\n" );printf ( "szbtool -x szb        # extract szb \n" );printf ( "szbtool -h            # help\n" );printf ( "---------------------------------------------------------------\n" );printf ( "e.g. szbtool -k boot.img -s system.img -a scue@Link -v Link.szb\n" );printf ( "\n" );
}/*主函数*/
int main ( int argc, char *argv[] )
{FILE *fp,*fp1,*fp2,*fd1,*fd2,*sub_image;char *file=NULL;u8 magic[8];u8 imagename[64];u8 partname[32];u8 version[32];u8 author[32];u32 filesize;u32 offset=8192;                            /* 初始的偏移量 */char opt;                                   /* 获取输入的选项 */int index=0;                                /* 判断szb中的分区索引数量 */int DO_NOTHING=0;                           /* 依据此变量判断是否执行 */int ERASE_DATA=0;                           /* 依据此变量判断是否擦除数据 *///清空变量memset(version,0x00,sizeof(version));memset(imagename,0x00,sizeof(imagename));memset(partname,0x00,sizeof(partname));strncpy(author,"scue@Link",sizeof(author));//显示作者信息
    author_info();//检测输入参数if(argc == 1){usage();                                /* 显示使用手册 */exit(0);}//判断选项中是否有版本int i;char tmp1[32]="";char tmp2[32]="";strncpy(tmp2,"-v",sizeof(tmp2));for (i = 0; i < argc; i++) {strncpy(tmp1,argv[i],sizeof(tmp1));if ( strcmp(tmp1,tmp2) == 0 ) {strncpy(version,argv[i+1],sizeof(version));}if ( strcmp(tmp1,"-x") == 0 || strcmp(tmp1,"-i")==0 ) { DO_NOTHING = 1;}}if ( strlen(version) == 0 && DO_NOTHING !=1 ){printf ( "\n" );printf ( "Please use -v to specify a version name!\n" );usage();exit(1);}if (DO_NOTHING != 1) {                      /* 当发现有事可做的时候... *///创建文件remove(version);                            /* delete the old szb file */if ( (fp=fopen(version,"wb+")) == NULL ) {printf ( "Create version file %s failure!\n",version);exit(1);}   u8 header_buffer[INFOSIZE*32];strncpy(header_buffer, "LmSzBfMt", sizeof(header_buffer));fwrite(header_buffer,  sizeof(header_buffer) , 1, fp); /* 向其中写8192字节后退出 */index++;fclose(fp);}//开始获取选项信息opterr=0;                                   /* 不显示错误的选项信息 */while ((opt = getopt(argc, argv, "b:k:r:s:c:p:d:x:i:v:a:e")) != -1)switch (opt) {case 'v':strncpy(version,optarg,sizeof(version));break;case 'b':file=optarg;strncpy(partname,"bootloader",sizeof(partname));strncpy(imagename,"uboot.bin",sizeof(imagename));offset=appendImage(version, file, imagename, partname, offset, index);index++;break;case 'k':file=optarg;strncpy(partname,"boot",sizeof(partname));strncpy(imagename,"boot.img",sizeof(imagename));offset=appendImage(version, file, imagename, partname, offset, index);index++;break;case 'r':file=optarg;strncpy(partname,"recovery",sizeof(partname));strncpy(imagename,"recovery.img",sizeof(imagename));offset=appendImage(version, file, imagename, partname, offset, index);index++;break;case 's':file=optarg;strncpy(partname,"system",sizeof(partname));strncpy(imagename,"system.img",sizeof(imagename));offset=appendImage(version, file, imagename, partname, offset, index);index++;break;case 'c':file=optarg;strncpy(partname,"cpimage",sizeof(partname));strncpy(imagename,"cpimage.img",sizeof(imagename));offset=appendImage(version, file, imagename, partname, offset, index);index++;break;case 'p':file=optarg;strncpy(partname,"preload",sizeof(partname));strncpy(imagename,"preload.img",sizeof(imagename));offset=appendImage(version, file, imagename, partname, offset, index);index++;break;case 'd':file=optarg;strncpy(partname,"userdata",sizeof(partname));strncpy(imagename,"userdata.img",sizeof(imagename));offset=appendImage(version, file, imagename, partname, offset, index);index++;break;case 'e':ERASE_DATA=1;break;case 'a':strncpy(author,optarg,sizeof(author));break;case 'x':DO_NOTHING=1;file=optarg; splitFile(file);break;case 'i':DO_NOTHING=1;file=optarg;get_szb_info(file);break;default:DO_NOTHING=1;usage();}argv += optind; //开始执行制作szb文件if ( DO_NOTHING != 1 ){//检查是否输入格式名    if ( strlen(version) == 0 ){DO_NOTHING = 1;printf ( "\n" );printf ( "Please use -v to specify a version name!\n" );usage();exit(1);}// 双清功能if ( ERASE_DATA == 1) {                     /* 判断是否有“双清功能” */u8 erase_data[32];u8 erase_cache[32];strncpy(erase_data, "userdata", sizeof(erase_data));strncpy(erase_cache, "cache", sizeof(erase_data));if ( (fp=fopen(version, "rb+")) == NULL ) {printf("Add erase features, open file %s failure!\n", version);exit(1);}fseek( fp, (INFOSIZE * index + 64 ), SEEK_SET ); /* erase userdata */fwrite(erase_data, sizeof(erase_data), 1, fp);index++;fseek( fp, (INFOSIZE * index + 64 ), SEEK_SET ); /* erase cache */fwrite(erase_cache, sizeof(erase_cache), 1, fp);index++;fclose(fp);}//制作SZB格式文件头部(256-12)部分
    szb_head_t head;if ( (fp=fopen(version,"rb+")) ==NULL ){printf("Calculate file size, open file %s failure!\n", version);exit(1);}head.filesize=getSize(fp);                          /* get szb file size *//* * 保密信息:向szb文件写入数据* */time(&head.timestamp);                              /* 写入时间信息 *//* * 保密信息:向szb文件写入数据* */fseek( fp, 12, SEEK_SET );fwrite(&head,sizeof(szb_head_t),1,fp);              /* 写入256-12字节部分 */fclose(fp);u32 szb_checksum;szb_checksum=getSzbSum(version);if ( (fp=fopen(version,"rb+")) ==NULL ){printf("Calculate file size, open file %s failure!\n", version);exit(1);}fseek(fp, 8, SEEK_SET);fwrite(&szb_checksum,sizeof(szb_checksum),1,fp);     /* 写入总的验证码字节部分 */fclose(fp);get_szb_info(version);printf ( ">> Congratulations! The Official ROM %s done!\n",version);printf ( "\n" );}return 0;
}

 


http://www.ppmy.cn/news/251316.html

相关文章

android系统如何获得外置卡路径

1、Android中查看USB连接的外接设备信息的代码实例 1,USB存储设备(如&#xff1a;U盘,移动硬盘)&#xff1a; //USB存储设备 插拔监听与 SD卡插拔监听一致。 private USBBroadCastReceiver mBroadcastReceiver;IntentFilter iFilter new IntentFilter();iFilter.addAction(Int…

国行Android手机使用google全套GMS服务小结

由于众所周知的原因&#xff0c;国行手机是不能内置google服务的&#xff0c;但作为铁杆google粉&#xff0c;没有GMS的Android不是完整的Android&#xff0c;NEXUS系列机器又由于各种原因买不到或者不想选购&#xff0c;那么也只有买国行机器了。 本文以联想K860i Android4.1…

高通与MTK瓜分天下?手机处理器品牌分析

http://mobile.pconline.com.cn/337/3379352.html 【PConline 杂谈】如果你向朋友请教买一台怎样的台式机或者笔记本的话&#xff0c;很多时候那朋友会根据你对电脑的使用需求而作一个性能划分&#xff0c;如“你只是需要处理一些简单的文档&#xff0c;对游戏的要求也并不高&a…

刷机

驱动问题 1、驱动问题最烦人&#xff0c;计算机–设备管理器–看看你的手机是否显示出来了 如果没有&#xff0c;可以尝试重启电脑&#xff0c;不停按f8&#xff0c;然后然后选择强制关闭驱动签名&#xff0c;一般可以解决。如果不行就加入 “线刷宝”的qq群,他们会帮助你。htt…

为了验证一下下载的CM11的源码有没有问题,决定编译一下cm官方支持的机器,手上正好有台nexus7 2012,就拿它为例测试一下在mac os x平台的整个编译过程。

发现一篇好文章&#xff0c;作为记录转载一下。 转载自&#xff1a;http://blog.sina.com.cn/s/blog_5f2e119b0101utae.html 为了验证一下下载的CM11的源码有没有问题&#xff0c;决定编译一下cm官方支持的机器&#xff0c;手上正好有台nexus7 2012&#xff0c;就拿它为例测试…

K860i的109升级需要的PinyinIME.apk和QuickSearchBox.apk两个文件

联想K860i的109版本终于可以正常更新了&#xff0c;感谢下乐Phone之家的 蚊子咬&#xff08; http://bbs.lephone.cc/space-uid-6410.html&#xff09;提供了关键的两个文件&#xff1a; PinyinIME.zip QuickSearchBox.zip 更新之后的版本号是&#xff1a;K860i_1_S_2_002_0165…

k860i 4.2root成功,用root大师20130705

root大师官网http://www.mgyun.com/ 试过各种手机直接root软件&#xff08;不需要连接数据线到电脑&#xff09;&#xff0c;但是都宣告失败&#xff0c;如猎户座1.4等等。只有root大师可行&#xff0c;其他的电脑一键root也无效果。

Lenovo k860i 移植Android 4.4 cm11进度记录【上篇已完结】

2014.5.16 为了验证一下下载的CM11的源码有没有问题&#xff0c;决定编译一下cm官方支持的机器&#xff0c;手上正好有台nexus7 2012&#xff0c;就拿它为例测试一下在mac os x平台的整个编译过程。 1. 最开始&#xff0c;是在os x下面搭编译环境&#xff0c;以前有说过的&…