#include #include #include #include #include #include #include #include "md5.h" //https://blog.csdn.net/phunxm/article/details/5082618 //https://blog.csdn.net/byxdaz/article/details/80507510 #pragma pack (1) typedef struct { uint8_t digit[32]; }md5_t; typedef struct { char *data; uint32_t blen; uint32_t dlen; }data_t; typedef union { struct { uint8_t magic[14]; uint16_t size; uint32_t partition; uint32_t version; char md5[32]; }hdr; uint8_t padd[128]; }fw_hdr_t; typedef struct { uint32_t operation_flag; // 0 uint32_t partition; // 1 uint32_t err; // 0 uint32_t error_count; // 0 uint32_t rom_addr; // PROGRAME_APP1 0x08005400 uint32_t recent_running_time; // 0 uint32_t running_app_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0) uint32_t app1_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0) uint32_t app1_rom_addr; // PROGRAME_APP1 0x08005400 uint32_t app1_partition; // 1 uint32_t app2_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0) uint32_t app2_rom_addr; // PROGRAME_APP2 0x0800A400 uint32_t app2_partition; // 1 char md5_1[32]; char md5_2[32]; uint32_t app1_len; uint32_t app2_len; }fw_info_t; typedef struct { data_t boot; data_t info; data_t app1; data_t app2; }fw_image_t; #pragma pack () static void print_md5(const char* s, char* m) { uint8_t i; printf("__%s", s); for (i = 0; i < 32; i++) { printf("%c", m[i]); } printf("\n"); } static char* my_malloc(uint32_t len) { char* p = (char*)malloc(len); if (p) { memset(p, 0xff, len); } return p; } static int str_cpy(char *dst, char *src) { char* p = strchr(src, '"'); if (!p) { return -1; } p += 1; while ((*p) != '"') { *dst++ = *p++; } *dst = 0; return 0; } static int digit_cpy(char* dst, char* src) { int x = 10; char* p = src; if (p[0] == '0' && (p[1]=='x' || p[1]=='X')) { memcpy(dst, p, 2); dst += 2; p += 2; x = 16; } while (isxdigit(*p)) { *dst++ = *p++; } *dst = 0; return x; } static char* get_token(char *buf, const char *tok) { char* p = strstr(buf, tok); if (!p) { printf("%s not found!!!\n", tok); return NULL; } p += strlen(tok); while (isblank(*p)) p++; return p; } static uint32_t get_addr(char* buf, const char* tok) { int x; char tmp[100]; char* p = get_token(buf, tok); if (!p) { return -1; } x = digit_cpy(tmp, p); return (uint32_t)strtol(tmp, NULL, x); } static char* strstr_line(char *s, const char *tok) { char* p1 = strstr(s, tok); char* p2 = strchr(s, '\n'); if (p1 && p2 && p1 0) { tmp[i] = 0; p8[j--] = (uint8_t)atoi(tmp); } i = 0; } p++; } return v; } static int get_magic(char *buf, const char *tok, void *magic) { static char tmp[500]; char* p = get_token(buf, tok); if (!p) { return -1; } str_cpy(tmp, p); memcpy(magic, tmp, strlen(tmp)); return 0; } static int get_info(char *buf, fw_hdr_t *hdr, fw_info_t *inf, fw_image_t *img) { uint32_t version = get_version(buf, "VERSION"); uint32_t partition = get_int(buf, "PARTITION"); uint32_t rom_addr = get_int(buf, "PROGRAME_APP1"); uint32_t use_one_app = get_int(buf, "USE_ONE_APP"); //fill hdr memset(hdr, 0xff, sizeof(fw_hdr_t)); get_magic(buf, "MODBUS_HEAD", hdr->hdr.magic); hdr->hdr.size = 0; hdr->hdr.version = version; hdr->hdr.partition = partition; //fill inf inf->operation_flag = 0; // 0 inf->partition = 1; // 1 inf->err = 0; // 0 inf->error_count = 0; // 0 inf->rom_addr = rom_addr; // PROGRAME_APP1 0x08005400 inf->recent_running_time; // 0 inf->running_app_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0) inf->app1_version = version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0) inf->app1_rom_addr = rom_addr; // PROGRAME_APP1 0x08005400 inf->app1_partition = 1; // 1 if(use_one_app) { inf->app2_version = 0xFFFFFFFF; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0) inf->app2_rom_addr = 0xFFFFFFFF; // PROGRAME_APP2 0x0800A400 inf->app2_partition = 0xFFFFFFFF; // 1 } else { inf->app2_version = version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0) inf->app2_rom_addr = get_int(buf, "PROGRAME_APP2"); // PROGRAME_APP2 0x0800A400 inf->app2_partition = 2; // 1 } //fill img img->boot.blen = get_int(buf, "BOOT_LOADER_SIZE"); img->boot.data = my_malloc(img->boot.blen); img->info.blen = get_int(buf, "META_DATA_SIZE"); img->info.data = my_malloc(img->info.blen); img->app1.blen = get_int(buf, "PROGRAME_APP1_SIZE"); img->app1.data = my_malloc(img->app1.blen); if (use_one_app) { img->app2.blen = 0; img->app2.data == NULL; } else { img->app2.blen = get_int(buf, "PROGRAME_APP2_SIZE"); img->app2.data = my_malloc(img->app2.blen); } return 0; } ///////////////////////////////////////////// static TCHAR* char_to_tchar(char* str) { DWORD dwNum = 0; dwNum = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); TCHAR* pUni = new TCHAR[dwNum]; MultiByteToWideChar(CP_ACP, 0, str, -1, pUni, dwNum); return pUni; } static int file_read(const TCHAR* path, data_t *data) { int r=-1; HANDLE hFile; DWORD flen,rlen; hFile = CreateFile(path, //name GENERIC_READ, //以读方式打开 FILE_SHARE_READ, //可共享读 NULL, //默认安全设置 OPEN_EXISTING, //只打开已经存在的文件 FILE_ATTRIBUTE_NORMAL, //常规文件属性 NULL); //无模板 if (hFile== INVALID_HANDLE_VALUE) { _tprintf(_T("%s open failed\n"), path); return -1; } flen = GetFileSize(hFile, NULL); if (flen== INVALID_FILE_SIZE) { printf("invalid file len\n"); goto quit; } if(data->data==NULL) { data->data = (char*)malloc(flen); if (data->data == NULL) { printf("___ data->data is NULL\n"); goto quit; } } data->dlen = flen; r = ReadFile(hFile, data->data, data->dlen, &rlen, NULL); if (r==FALSE) { _tprintf(_T("%s read failed\n"), path); goto quit; } r = 0; quit: CloseHandle(hFile); return r; } static int get_time(TCHAR* path, char* time, int len) { FILETIME IpCreationTime; //文件的创建时间 FILETIME IpLastAccessTime; //对文件的最近访问时间 FILETIME IpLastWriteTime; //文件的最近修改时间 FILETIME ltime; SYSTEMTIME rtime; HANDLE hFile = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("Get the dictionary failed!\n"); CloseHandle(hFile); return -1; } if (!GetFileTime(hFile, &IpCreationTime, &IpLastAccessTime, &IpLastWriteTime)) { return -1; } CloseHandle(hFile); FileTimeToLocalFileTime(&IpLastWriteTime, <ime); FileTimeToSystemTime(<ime, &rtime); //将文件时间转化为系统时间 snprintf(time, len, "%04u%02u%02u_%02u%02u%02u", rtime.wYear, rtime.wMonth, rtime.wDay, rtime.wHour, rtime.wMinute, rtime.wSecond); return 0; } static int get_ver(char *ver, uint32_t v) { uint8_t* p = (uint8_t*) & v; sprintf(ver, "v%d.%d.%d.%d", p[3], p[2], p[1], p[0]); return 0; } ////////////////////////////////////////// //static TCHAR* cfgPath = (TCHAR*)__TEXT("./cfg.h"); int main(char argc, char *argv[]) { int r=0,flen; HANDLE hFile=NULL; char* path1, * path2; char imgPath[500],*dot; fw_hdr_t fwHdr = { 0 }; fw_info_t fwInfo = { 0 }; fw_image_t fwImg = { 0 }; data_t fcfg = {0}, fupg = {0}; char time1[100],time2[100],*ptime; TCHAR* xpath1=NULL, * xpath2 = NULL,* xpath3 = NULL; int make_single_bin = 0; char version[32],md5[32]; TCHAR* cfgPath; //if (argc==2) { // printf("make a upgrade file\n"); //} //else if(argc == 3){ // printf("make a single bin\n"); // make_single_bin = 1; //} //else { // printf("usage: mb app.bin or mb boot.bin app.bin\n"); // return -1; //} if (argc != 4) { printf("usage: mb cfg.h app.bin or mb boot.bin app.bin\n"); return -1; } cfgPath = char_to_tchar(argv[1]); r = file_read(cfgPath, &fcfg); if (r) { goto fail; } get_info(fcfg.data, &fwHdr, &fwInfo, &fwImg); get_ver(version, fwHdr.hdr.version); path1 = argv[2]; //if (make_single_bin) { xpath1 = char_to_tchar(path1); flen = file_read(xpath1, &fwImg.boot); if (flen < 0) { goto fail; } path2 = argv[3]; xpath2 = char_to_tchar(path2); flen = file_read(xpath2, &fwImg.app1); if (flen < 0) { goto fail; } md5_calc(fwImg.app1.data, fwImg.app1.dlen, md5); if (fwImg.info.data) { fwInfo.app1_len = fwImg.app1.dlen; fwInfo.app2_len = fwImg.app1.dlen; memcpy(fwInfo.md5_1, md5, sizeof(md5)); memcpy(fwInfo.md5_2, md5, sizeof(md5)); memcpy(fwImg.info.data, &fwInfo, sizeof(fwInfo)); } get_time(xpath1, time1, sizeof(time1)); get_time(xpath2, time2, sizeof(time2)); if (memcmp(time1, time2, sizeof(time1)) > 0) { ptime = time1; } else { ptime = time2; } strcpy(imgPath, path1); dot = strrchr(imgPath, '\\'); if (dot) { dot[1] = 0; } else { imgPath[0] = 0; } strcat(imgPath, "all_"); strcat(imgPath, version); strcat(imgPath, "_"); strcat(imgPath, ptime); strcat(imgPath, ".bin"); xpath3 = char_to_tchar(imgPath); hFile = CreateFile(xpath3, //name GENERIC_WRITE, //以写方式打开 0, //可共享读 NULL, //默认安全设置 CREATE_ALWAYS, //创建新文件 FILE_ATTRIBUTE_NORMAL, //常规文件属性 NULL); if (!hFile) { goto fail; } WriteFile(hFile, fwImg.boot.data, fwImg.boot.blen, NULL, NULL); WriteFile(hFile, fwImg.info.data, fwImg.info.blen, NULL, NULL); WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL); if(fwImg.app2.data != NULL) WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL); //} //else { xpath1 = char_to_tchar(path2); flen = file_read(xpath1, &fupg); if (flen < 0) { goto fail; } get_time(xpath1, time1, sizeof(time1)); strcpy(imgPath, path2); dot = strrchr(imgPath, '\\'); if (dot) { dot[1] = 0; } else { imgPath[0] = 0; } strcat(imgPath, "app_"); strcat(imgPath, version); strcat(imgPath, "_"); strcat(imgPath, time1); strcat(imgPath, ".upg"); xpath3 = char_to_tchar(imgPath); hFile = CreateFile(xpath3, //name GENERIC_WRITE, //以写方式打开 0, //可共享读 NULL, //默认安全设置 CREATE_ALWAYS, //创建新文件 FILE_ATTRIBUTE_NORMAL, //常规文件属性 NULL); if (!hFile) { goto fail; } md5_calc(fupg.data, fupg.dlen, md5); fwHdr.hdr.size = fupg.dlen; memcpy(fwHdr.hdr.md5, md5, sizeof(md5)); WriteFile(hFile, &fwHdr, sizeof(fwHdr), NULL, NULL); WriteFile(hFile, fupg.data, fupg.dlen, NULL, NULL); //WriteFile(hFile, &md5, sizeof(md5), NULL, NULL); print_md5("md5: ", md5); // } fail: if(hFile) CloseHandle(hFile); delete xpath1;delete xpath2;delete xpath3; return r; }