mb.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  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. //fill hdr
  209. memset(hdr, 0xff, sizeof(fw_hdr_t));
  210. get_magic(buf, "MODBUS_HEAD", hdr->hdr.magic);
  211. hdr->hdr.size = 0;
  212. hdr->hdr.version = version;
  213. hdr->hdr.partition = partition;
  214. //fill inf
  215. inf->operation_flag = 0; // 0
  216. inf->partition = 1; // 1
  217. inf->err = 0; // 0
  218. inf->error_count = 0; // 0
  219. inf->rom_addr = rom_addr; // PROGRAME_APP1 0x08005400
  220. inf->recent_running_time; // 0
  221. inf->running_app_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  222. inf->app1_version = version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  223. inf->app1_rom_addr = rom_addr; // PROGRAME_APP1 0x08005400
  224. inf->app1_partition = 1; // 1
  225. inf->app2_version = version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  226. inf->app2_rom_addr = get_int(buf, "PROGRAME_APP2"); // PROGRAME_APP2 0x0800A400
  227. inf->app2_partition = 2; // 1
  228. //fill img
  229. img->boot.blen = get_int(buf, "BOOT_LOADER_SIZE");
  230. img->boot.data = my_malloc(img->boot.blen);
  231. img->info.blen = get_int(buf, "META_DATA_SIZE");
  232. img->info.data = my_malloc(img->info.blen);
  233. img->app1.blen = get_int(buf, "PROGRAME_APP1_SIZE");
  234. img->app1.data = my_malloc(img->app1.blen);
  235. img->app2.blen = get_int(buf, "PROGRAME_APP2_SIZE");
  236. img->app2.data = my_malloc(img->app2.blen);
  237. return 0;
  238. }
  239. /////////////////////////////////////////////
  240. static TCHAR* char_to_tchar(char* str)
  241. {
  242. DWORD dwNum = 0;
  243. dwNum = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
  244. TCHAR* pUni = new TCHAR[dwNum];
  245. MultiByteToWideChar(CP_ACP, 0, str, -1, pUni, dwNum);
  246. return pUni;
  247. }
  248. static int file_read(const TCHAR* path, data_t *data)
  249. {
  250. int r=-1;
  251. HANDLE hFile;
  252. DWORD flen,rlen;
  253. hFile = CreateFile(path, //name
  254. GENERIC_READ, //以读方式打开
  255. FILE_SHARE_READ, //可共享读
  256. NULL, //默认安全设置
  257. OPEN_EXISTING, //只打开已经存在的文件
  258. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  259. NULL); //无模板
  260. if (hFile== INVALID_HANDLE_VALUE) {
  261. _tprintf(_T("%s open failed\n"), path);
  262. return -1;
  263. }
  264. flen = GetFileSize(hFile, NULL);
  265. if (flen== INVALID_FILE_SIZE) {
  266. printf("invalid file len\n");
  267. goto quit;
  268. }
  269. if(data->data==NULL) {
  270. data->data = (char*)malloc(flen);
  271. if (data->data == NULL) {
  272. printf("___ data->data is NULL\n");
  273. goto quit;
  274. }
  275. }
  276. data->dlen = flen;
  277. r = ReadFile(hFile, data->data, data->dlen, &rlen, NULL);
  278. if (r==FALSE) {
  279. _tprintf(_T("%s read failed\n"), path);
  280. goto quit;
  281. }
  282. r = 0;
  283. quit:
  284. CloseHandle(hFile);
  285. return r;
  286. }
  287. static int get_time(TCHAR* path, char* time, int len)
  288. {
  289. FILETIME IpCreationTime; //文件的创建时间
  290. FILETIME IpLastAccessTime; //对文件的最近访问时间
  291. FILETIME IpLastWriteTime; //文件的最近修改时间
  292. FILETIME ltime;
  293. SYSTEMTIME rtime;
  294. HANDLE hFile = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  295. if (hFile == INVALID_HANDLE_VALUE)
  296. {
  297. printf("Get the dictionary failed!\n");
  298. CloseHandle(hFile);
  299. return -1;
  300. }
  301. if (!GetFileTime(hFile, &IpCreationTime, &IpLastAccessTime, &IpLastWriteTime)) {
  302. return -1;
  303. }
  304. CloseHandle(hFile);
  305. FileTimeToLocalFileTime(&IpLastWriteTime, &ltime);
  306. FileTimeToSystemTime(&ltime, &rtime); //将文件时间转化为系统时间
  307. snprintf(time, len, "%04u%02u%02u_%02u%02u%02u", rtime.wYear, rtime.wMonth, rtime.wDay, rtime.wHour, rtime.wMinute, rtime.wSecond);
  308. return 0;
  309. }
  310. static int get_ver(char *ver, uint32_t v)
  311. {
  312. uint8_t* p = (uint8_t*) & v;
  313. sprintf(ver, "v%d.%d.%d.%d", p[3], p[2], p[1], p[0]);
  314. return 0;
  315. }
  316. //////////////////////////////////////////
  317. static TCHAR* cfgPath = (TCHAR*)__TEXT("./cfg.h");
  318. int main(char argc, char *argv[])
  319. {
  320. int r=0,flen;
  321. HANDLE hFile=NULL;
  322. char* path1, * path2;
  323. char imgPath[500],*dot;
  324. fw_hdr_t fwHdr = { 0 };
  325. fw_info_t fwInfo = { 0 };
  326. fw_image_t fwImg = { 0 };
  327. data_t fcfg = {0}, fupg = {0};
  328. char time1[100],time2[100],*ptime;
  329. TCHAR* xpath1=NULL, * xpath2 = NULL,* xpath3 = NULL;
  330. int make_single_bin = 0;
  331. char version[32],md5[32];
  332. if (argc==2) {
  333. printf("make a upgrade file\n");
  334. }
  335. else if(argc == 3){
  336. printf("make a single bin\n");
  337. make_single_bin = 1;
  338. }
  339. else {
  340. printf("usage: mb app.bin or mb boot.bin app.bin\n");
  341. return -1;
  342. }
  343. r = file_read(cfgPath, &fcfg);
  344. if (r) {
  345. goto fail;
  346. }
  347. get_info(fcfg.data, &fwHdr, &fwInfo, &fwImg);
  348. get_ver(version, fwHdr.hdr.version);
  349. path1 = argv[1];
  350. if (make_single_bin) {
  351. xpath1 = char_to_tchar(path1);
  352. flen = file_read(xpath1, &fwImg.boot);
  353. if (flen < 0) {
  354. goto fail;
  355. }
  356. path2 = argv[2];
  357. xpath2 = char_to_tchar(path2);
  358. flen = file_read(xpath2, &fwImg.app1);
  359. if (flen < 0) {
  360. goto fail;
  361. }
  362. md5_calc(fwImg.app1.data, fwImg.app1.dlen, md5);
  363. if (fwImg.info.data) {
  364. fwInfo.app1_len = fwImg.app1.dlen;
  365. fwInfo.app2_len = fwImg.app1.dlen;
  366. memcpy(fwInfo.md5_1, md5, sizeof(md5));
  367. memcpy(fwInfo.md5_2, md5, sizeof(md5));
  368. memcpy(fwImg.info.data, &fwInfo, sizeof(fwInfo));
  369. }
  370. get_time(xpath1, time1, sizeof(time1));
  371. get_time(xpath2, time2, sizeof(time2));
  372. if (memcmp(time1, time2, sizeof(time1)) > 0) {
  373. ptime = time1;
  374. }
  375. else {
  376. ptime = time2;
  377. }
  378. strcpy(imgPath, path1);
  379. dot = strrchr(imgPath, '\\');
  380. if (dot) {
  381. dot[1] = 0;
  382. }
  383. else {
  384. imgPath[0] = 0;
  385. }
  386. strcat(imgPath, "all_");
  387. strcat(imgPath, version);
  388. strcat(imgPath, "_");
  389. strcat(imgPath, ptime);
  390. strcat(imgPath, ".bin");
  391. xpath3 = char_to_tchar(imgPath);
  392. hFile = CreateFile(xpath3, //name
  393. GENERIC_WRITE, //以写方式打开
  394. 0, //可共享读
  395. NULL, //默认安全设置
  396. CREATE_ALWAYS, //创建新文件
  397. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  398. NULL);
  399. if (!hFile) {
  400. goto fail;
  401. }
  402. WriteFile(hFile, fwImg.boot.data, fwImg.boot.blen, NULL, NULL);
  403. WriteFile(hFile, fwImg.info.data, fwImg.info.blen, NULL, NULL);
  404. WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL);
  405. WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL);
  406. }
  407. else {
  408. xpath1 = char_to_tchar(path1);
  409. flen = file_read(xpath1, &fupg);
  410. if (flen < 0) {
  411. goto fail;
  412. }
  413. get_time(xpath1, time1, sizeof(time1));
  414. strcpy(imgPath, path1);
  415. dot = strrchr(imgPath, '\\');
  416. if (dot) {
  417. dot[1] = 0;
  418. }
  419. else {
  420. imgPath[0] = 0;
  421. }
  422. strcat(imgPath, "app_");
  423. strcat(imgPath, version);
  424. strcat(imgPath, "_");
  425. strcat(imgPath, time1);
  426. strcat(imgPath, ".upg");
  427. xpath3 = char_to_tchar(imgPath);
  428. hFile = CreateFile(xpath3, //name
  429. GENERIC_WRITE, //以写方式打开
  430. 0, //可共享读
  431. NULL, //默认安全设置
  432. CREATE_ALWAYS, //创建新文件
  433. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  434. NULL);
  435. if (!hFile) {
  436. goto fail;
  437. }
  438. md5_calc(fupg.data, fupg.dlen, md5);
  439. fwHdr.hdr.size = fupg.dlen;
  440. memcpy(fwHdr.hdr.md5, md5, sizeof(md5));
  441. WriteFile(hFile, &fwHdr, sizeof(fwHdr), NULL, NULL);
  442. WriteFile(hFile, fupg.data, fupg.dlen, NULL, NULL);
  443. //WriteFile(hFile, &md5, sizeof(md5), NULL, NULL);
  444. print_md5("md5: ", md5);
  445. }
  446. fail:
  447. if(hFile) CloseHandle(hFile);
  448. delete xpath1;delete xpath2;delete xpath3;
  449. return r;
  450. }