mb.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. #include <windows.h>
  2. #include <tchar.h>
  3. #include <time.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include "md5.h"
  9. //https://blog.csdn.net/phunxm/article/details/5082618
  10. //https://blog.csdn.net/byxdaz/article/details/80507510
  11. #pragma pack (1)
  12. typedef struct {
  13. uint8_t digit[32];
  14. }md5_t;
  15. typedef struct {
  16. char *data;
  17. uint32_t blen;
  18. uint32_t dlen;
  19. }data_t;
  20. typedef union {
  21. struct {
  22. uint8_t magic[14];
  23. uint16_t size;
  24. uint32_t partition;
  25. uint32_t version;
  26. char md5[32];
  27. }hdr;
  28. uint8_t padd[128];
  29. }fw_hdr_t;
  30. typedef struct {
  31. uint32_t operation_flag; // 0
  32. uint32_t partition; // 1
  33. uint32_t err; // 0
  34. uint32_t error_count; // 0
  35. uint32_t rom_addr; // PROGRAME_APP1 0x08005400
  36. uint32_t recent_running_time; // 0
  37. uint32_t running_app_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  38. uint32_t app1_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  39. uint32_t app1_rom_addr; // PROGRAME_APP1 0x08005400
  40. uint32_t app1_partition; // 1
  41. uint32_t app2_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  42. uint32_t app2_rom_addr; // PROGRAME_APP2 0x0800A400
  43. uint32_t app2_partition; // 1
  44. char md5_1[32];
  45. char md5_2[32];
  46. uint32_t app1_len;
  47. uint32_t app2_len;
  48. }fw_info_t;
  49. typedef struct {
  50. data_t boot;
  51. data_t info;
  52. data_t app1;
  53. data_t app2;
  54. }fw_image_t;
  55. #pragma pack ()
  56. static void print_md5(const char* s, char* m)
  57. {
  58. uint8_t i;
  59. printf("__%s", s);
  60. for (i = 0; i < 32; i++) {
  61. printf("%c", m[i]);
  62. }
  63. printf("\n");
  64. }
  65. static char* my_malloc(uint32_t len)
  66. {
  67. char* p = (char*)malloc(len);
  68. if (p) {
  69. memset(p, 0xff, len);
  70. }
  71. return p;
  72. }
  73. static int str_cpy(char *dst, char *src)
  74. {
  75. char* p = strchr(src, '"');
  76. if (!p) {
  77. return -1;
  78. }
  79. p += 1;
  80. while ((*p) != '"') {
  81. *dst++ = *p++;
  82. }
  83. *dst = 0;
  84. return 0;
  85. }
  86. static int digit_cpy(char* dst, char* src)
  87. {
  88. int x = 10;
  89. char* p = src;
  90. if (p[0] == '0' && (p[1]=='x' || p[1]=='X')) {
  91. memcpy(dst, p, 2);
  92. dst += 2; p += 2;
  93. x = 16;
  94. }
  95. while (isxdigit(*p)) {
  96. *dst++ = *p++;
  97. }
  98. *dst = 0;
  99. return x;
  100. }
  101. static char* get_token(char *buf, const char *tok)
  102. {
  103. char* p = strstr(buf, tok);
  104. if (!p) {
  105. printf("%s not found!!!\n", tok);
  106. return NULL;
  107. }
  108. p += strlen(tok);
  109. while (isblank(*p)) p++;
  110. return p;
  111. }
  112. static uint32_t get_addr(char* buf, const char* tok)
  113. {
  114. int x;
  115. char tmp[100];
  116. char* p = get_token(buf, tok);
  117. if (!p) {
  118. return -1;
  119. }
  120. x = digit_cpy(tmp, p);
  121. return (uint32_t)strtol(tmp, NULL, x);
  122. }
  123. static char* strstr_line(char *s, const char *tok)
  124. {
  125. char* p1 = strstr(s, tok);
  126. char* p2 = strchr(s, '\n');
  127. if (p1 && p2 && p1<p2) {
  128. return p1;
  129. }
  130. return NULL;
  131. }
  132. static uint32_t get_int(char* buf, const char* tok)
  133. {
  134. int x;
  135. uint32_t v = 1;
  136. char *t,tmp[100];
  137. char* p = get_token(buf, tok);
  138. if (!p) {
  139. return -1;
  140. }
  141. t = strstr_line(p, "0x");
  142. if (!t) {
  143. t = strstr_line(p, "0X");
  144. }
  145. if (t) {
  146. p = t;
  147. }
  148. while (1) {
  149. if (isdigit(*p)) {
  150. x = digit_cpy(tmp, p);
  151. v *= strtol(tmp, NULL, x);
  152. p += strlen(tmp);
  153. }
  154. else {
  155. if (!isgraph(*p)) {
  156. break;
  157. }
  158. p++;
  159. }
  160. }
  161. return v;
  162. }
  163. /////////////////////////////////////////////
  164. static uint32_t get_version(char *buf, const char *tok)
  165. {
  166. char tmp[10];
  167. uint32_t v, i = 0, j = 3;
  168. uint8_t* p8 = (uint8_t*)&v;
  169. char* p = get_token(buf, tok);
  170. if (!p) {
  171. return -1;
  172. }
  173. while (!isdigit(*p)) p++;
  174. while (*p) {
  175. if (isdigit(*p)) {
  176. tmp[i++] = *p;
  177. }
  178. else {
  179. if (!isgraph(*p)) {
  180. break;
  181. }
  182. if (i > 0) {
  183. tmp[i] = 0;
  184. p8[j--] = (uint8_t)atoi(tmp);
  185. }
  186. i = 0;
  187. }
  188. p++;
  189. }
  190. return v;
  191. }
  192. static int get_magic(char *buf, const char *tok, void *magic)
  193. {
  194. static char tmp[500];
  195. char* p = get_token(buf, tok);
  196. if (!p) {
  197. return -1;
  198. }
  199. str_cpy(tmp, p);
  200. memcpy(magic, tmp, strlen(tmp));
  201. return 0;
  202. }
  203. static int get_info(char *buf, fw_hdr_t *hdr, fw_info_t *inf, fw_image_t *img)
  204. {
  205. uint32_t version = get_version(buf, "VERSION");
  206. uint32_t partition = get_int(buf, "PARTITION");
  207. uint32_t rom_addr = get_int(buf, "PROGRAME_APP1");
  208. uint32_t use_one_app = get_int(buf, "USE_ONE_APP");
  209. //fill hdr
  210. memset(hdr, 0xff, sizeof(fw_hdr_t));
  211. get_magic(buf, "MODBUS_HEAD", hdr->hdr.magic);
  212. hdr->hdr.size = 0;
  213. hdr->hdr.version = version;
  214. hdr->hdr.partition = partition;
  215. //fill inf
  216. inf->operation_flag = 0; // 0
  217. inf->partition = 1; // 1
  218. inf->err = 0; // 0
  219. inf->error_count = 0; // 0
  220. inf->rom_addr = rom_addr; // PROGRAME_APP1 0x08005400
  221. inf->recent_running_time; // 0
  222. inf->running_app_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  223. inf->app1_version = version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  224. inf->app1_rom_addr = rom_addr; // PROGRAME_APP1 0x08005400
  225. inf->app1_partition = 1; // 1
  226. if(use_one_app)
  227. {
  228. inf->app2_version = 0xFFFFFFFF; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  229. inf->app2_rom_addr = 0xFFFFFFFF; // PROGRAME_APP2 0x0800A400
  230. inf->app2_partition = 0xFFFFFFFF; // 1
  231. }
  232. else
  233. {
  234. inf->app2_version = version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  235. inf->app2_rom_addr = get_int(buf, "PROGRAME_APP2"); // PROGRAME_APP2 0x0800A400
  236. inf->app2_partition = 2; // 1
  237. }
  238. //fill img
  239. img->boot.blen = get_int(buf, "BOOT_LOADER_SIZE");
  240. img->boot.data = my_malloc(img->boot.blen);
  241. img->info.blen = get_int(buf, "META_DATA_SIZE");
  242. img->info.data = my_malloc(img->info.blen);
  243. img->app1.blen = get_int(buf, "PROGRAME_APP1_SIZE");
  244. img->app1.data = my_malloc(img->app1.blen);
  245. if (use_one_app)
  246. {
  247. img->app2.blen = 0;
  248. img->app2.data == NULL;
  249. }
  250. else
  251. {
  252. img->app2.blen = get_int(buf, "PROGRAME_APP2_SIZE");
  253. img->app2.data = my_malloc(img->app2.blen);
  254. }
  255. return 0;
  256. }
  257. /////////////////////////////////////////////
  258. static TCHAR* char_to_tchar(char* str)
  259. {
  260. DWORD dwNum = 0;
  261. dwNum = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
  262. TCHAR* pUni = new TCHAR[dwNum];
  263. MultiByteToWideChar(CP_ACP, 0, str, -1, pUni, dwNum);
  264. return pUni;
  265. }
  266. static int file_read(const TCHAR* path, data_t *data)
  267. {
  268. int r=-1;
  269. HANDLE hFile;
  270. DWORD flen,rlen;
  271. hFile = CreateFile(path, //name
  272. GENERIC_READ, //以读方式打开
  273. FILE_SHARE_READ, //可共享读
  274. NULL, //默认安全设置
  275. OPEN_EXISTING, //只打开已经存在的文件
  276. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  277. NULL); //无模板
  278. if (hFile== INVALID_HANDLE_VALUE) {
  279. _tprintf(_T("%s open failed\n"), path);
  280. return -1;
  281. }
  282. flen = GetFileSize(hFile, NULL);
  283. if (flen== INVALID_FILE_SIZE) {
  284. printf("invalid file len\n");
  285. goto quit;
  286. }
  287. if(data->data==NULL) {
  288. data->data = (char*)malloc(flen);
  289. if (data->data == NULL) {
  290. printf("___ data->data is NULL\n");
  291. goto quit;
  292. }
  293. }
  294. data->dlen = flen;
  295. r = ReadFile(hFile, data->data, data->dlen, &rlen, NULL);
  296. if (r==FALSE) {
  297. _tprintf(_T("%s read failed\n"), path);
  298. goto quit;
  299. }
  300. r = 0;
  301. quit:
  302. CloseHandle(hFile);
  303. return r;
  304. }
  305. static int get_time(TCHAR* path, char* time, int len)
  306. {
  307. FILETIME IpCreationTime; //文件的创建时间
  308. FILETIME IpLastAccessTime; //对文件的最近访问时间
  309. FILETIME IpLastWriteTime; //文件的最近修改时间
  310. FILETIME ltime;
  311. SYSTEMTIME rtime;
  312. HANDLE hFile = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  313. if (hFile == INVALID_HANDLE_VALUE)
  314. {
  315. printf("Get the dictionary failed!\n");
  316. CloseHandle(hFile);
  317. return -1;
  318. }
  319. if (!GetFileTime(hFile, &IpCreationTime, &IpLastAccessTime, &IpLastWriteTime)) {
  320. return -1;
  321. }
  322. CloseHandle(hFile);
  323. FileTimeToLocalFileTime(&IpLastWriteTime, &ltime);
  324. FileTimeToSystemTime(&ltime, &rtime); //将文件时间转化为系统时间
  325. snprintf(time, len, "%04u%02u%02u_%02u%02u%02u", rtime.wYear, rtime.wMonth, rtime.wDay, rtime.wHour, rtime.wMinute, rtime.wSecond);
  326. return 0;
  327. }
  328. static int get_ver(char *ver, uint32_t v)
  329. {
  330. uint8_t* p = (uint8_t*) & v;
  331. sprintf(ver, "v%d.%d.%d.%d", p[3], p[2], p[1], p[0]);
  332. return 0;
  333. }
  334. //////////////////////////////////////////
  335. //static TCHAR* cfgPath = (TCHAR*)__TEXT("./cfg.h");
  336. int main(char argc, char *argv[])
  337. {
  338. int r=0,flen;
  339. HANDLE hFile=NULL;
  340. char* path1, * path2;
  341. char imgPath[500],*dot;
  342. fw_hdr_t fwHdr = { 0 };
  343. fw_info_t fwInfo = { 0 };
  344. fw_image_t fwImg = { 0 };
  345. data_t fcfg = {0}, fupg = {0};
  346. char time1[100],time2[100],*ptime;
  347. TCHAR* xpath1=NULL, * xpath2 = NULL,* xpath3 = NULL;
  348. int make_single_bin = 0;
  349. char version[32],md5[32];
  350. TCHAR* cfgPath;
  351. //if (argc==2) {
  352. // printf("make a upgrade file\n");
  353. //}
  354. //else if(argc == 3){
  355. // printf("make a single bin\n");
  356. // make_single_bin = 1;
  357. //}
  358. //else {
  359. // printf("usage: mb app.bin or mb boot.bin app.bin\n");
  360. // return -1;
  361. //}
  362. if (argc != 4)
  363. {
  364. printf("usage: mb cfg.h app.bin or mb boot.bin app.bin\n");
  365. return -1;
  366. }
  367. cfgPath = char_to_tchar(argv[1]);
  368. r = file_read(cfgPath, &fcfg);
  369. if (r) {
  370. goto fail;
  371. }
  372. get_info(fcfg.data, &fwHdr, &fwInfo, &fwImg);
  373. get_ver(version, fwHdr.hdr.version);
  374. path1 = argv[2];
  375. //if (make_single_bin) {
  376. xpath1 = char_to_tchar(path1);
  377. flen = file_read(xpath1, &fwImg.boot);
  378. if (flen < 0) {
  379. goto fail;
  380. }
  381. path2 = argv[3];
  382. xpath2 = char_to_tchar(path2);
  383. flen = file_read(xpath2, &fwImg.app1);
  384. if (flen < 0) {
  385. goto fail;
  386. }
  387. md5_calc(fwImg.app1.data, fwImg.app1.dlen, md5);
  388. if (fwImg.info.data) {
  389. fwInfo.app1_len = fwImg.app1.dlen;
  390. fwInfo.app2_len = fwImg.app1.dlen;
  391. memcpy(fwInfo.md5_1, md5, sizeof(md5));
  392. memcpy(fwInfo.md5_2, md5, sizeof(md5));
  393. memcpy(fwImg.info.data, &fwInfo, sizeof(fwInfo));
  394. }
  395. get_time(xpath1, time1, sizeof(time1));
  396. get_time(xpath2, time2, sizeof(time2));
  397. if (memcmp(time1, time2, sizeof(time1)) > 0) {
  398. ptime = time1;
  399. }
  400. else {
  401. ptime = time2;
  402. }
  403. strcpy(imgPath, path1);
  404. dot = strrchr(imgPath, '\\');
  405. if (dot) {
  406. dot[1] = 0;
  407. }
  408. else {
  409. imgPath[0] = 0;
  410. }
  411. strcat(imgPath, "all_");
  412. strcat(imgPath, version);
  413. strcat(imgPath, "_");
  414. strcat(imgPath, ptime);
  415. strcat(imgPath, ".bin");
  416. xpath3 = char_to_tchar(imgPath);
  417. hFile = CreateFile(xpath3, //name
  418. GENERIC_WRITE, //以写方式打开
  419. 0, //可共享读
  420. NULL, //默认安全设置
  421. CREATE_ALWAYS, //创建新文件
  422. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  423. NULL);
  424. if (!hFile) {
  425. goto fail;
  426. }
  427. WriteFile(hFile, fwImg.boot.data, fwImg.boot.blen, NULL, NULL);
  428. WriteFile(hFile, fwImg.info.data, fwImg.info.blen, NULL, NULL);
  429. WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL);
  430. if(fwImg.app2.data != NULL)
  431. WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL);
  432. //}
  433. //else {
  434. xpath1 = char_to_tchar(path2);
  435. flen = file_read(xpath1, &fupg);
  436. if (flen < 0) {
  437. goto fail;
  438. }
  439. get_time(xpath1, time1, sizeof(time1));
  440. strcpy(imgPath, path2);
  441. dot = strrchr(imgPath, '\\');
  442. if (dot) {
  443. dot[1] = 0;
  444. }
  445. else {
  446. imgPath[0] = 0;
  447. }
  448. strcat(imgPath, "app_");
  449. strcat(imgPath, version);
  450. strcat(imgPath, "_");
  451. strcat(imgPath, time1);
  452. strcat(imgPath, ".upg");
  453. xpath3 = char_to_tchar(imgPath);
  454. hFile = CreateFile(xpath3, //name
  455. GENERIC_WRITE, //以写方式打开
  456. 0, //可共享读
  457. NULL, //默认安全设置
  458. CREATE_ALWAYS, //创建新文件
  459. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  460. NULL);
  461. if (!hFile) {
  462. goto fail;
  463. }
  464. md5_calc(fupg.data, fupg.dlen, md5);
  465. fwHdr.hdr.size = fupg.dlen;
  466. memcpy(fwHdr.hdr.md5, md5, sizeof(md5));
  467. WriteFile(hFile, &fwHdr, sizeof(fwHdr), NULL, NULL);
  468. WriteFile(hFile, fupg.data, fupg.dlen, NULL, NULL);
  469. //WriteFile(hFile, &md5, sizeof(md5), NULL, NULL);
  470. print_md5("md5: ", md5);
  471. // }
  472. fail:
  473. if(hFile) CloseHandle(hFile);
  474. delete xpath1;delete xpath2;delete xpath3;
  475. return r;
  476. }