guohui пре 1 година
родитељ
комит
7e1e8a24e7

+ 26 - 1
pro/config/cfg.h

@@ -21,7 +21,9 @@
 //#define PRJ_ANDERSON_AC_I3_O3
 //#define PRJ_HYPERTEC_AC_I3_O1
 //#define PRJ_SG_I3_O3
-#define PRJ_TEST
+//#define PRJ_TEST
+//#define PRJ_TEST_AC_I1_O1
+#define PRJ_TEST_AC_I3_O1
 
 
 #define USE_SMTP
@@ -177,6 +179,29 @@
     #define CHANNEL_DELAY                       8
 
     #define PROD_POWER_TYPE                     5
+#elif defined PRJ_TEST_AC_I1_O1
+    #define LANGUAGE                            0           //chinese
+    #define SMPLE_TIME                          30          //ms
+    #define SAVE_TIME                           60000       //ms
+    #define CASCADE_CNT                         0
+
+    #define MAX_CHN_COUNT                       24//24//4
+    #define PHASE_GROUP                         8
+    #define CHANNEL_DELAY                       8
+
+    #define PROD_POWER_TYPE                     0
+#elif defined PRJ_TEST_AC_I3_O1
+    #define LANGUAGE                            0           //chinese
+    #define SMPLE_TIME                          30          //ms
+    #define SAVE_TIME                           60000       //ms
+    #define CASCADE_CNT                         0
+
+    #define MAX_CHN_COUNT                       24//24//4
+    #define PHASE_GROUP                         8
+    #define CHANNEL_DELAY                       8
+
+    #define PROD_POWER_TYPE                     5
+
 #else
     #error define a PRJ_XXXX please!
 #endif

+ 13 - 2
pub

@@ -15,12 +15,14 @@
 #PRJS="PRJ_RELEASE_AC_I3_O1"
 #PRJS="PRJ_RELEASE_AC_I3_O3"
 #PRJS="PRJ_STSC_I3_O3"
-#PRJS="PRJ_SG_I3_O3"
-PRJS="PRJ_TEST"
+#PRJS="PRJ_SG_I3_O3"PRJS="PRJ_TEST"
+#PRJS="PRJ_TEST_AC_I1_O1"
+#PRJS="PRJ_TEST_AC_I3_O1"
 
 #PRJS="PRJ_USASL_AC_I3_O1 PRJ_USASL_AC_I3_O3"
 #PRJS="PRJ_XIAN_AC_I1_O1_P4 PRJ_XIAN_AC_I1_O1_P8"
 #PRJS="PRJ_ITK_AC_I1_O1 PRJ_ITK_AC_I3_O1"
+#PRJS="PRJ_TEST_AC_I1_O1 PRJ_TEST_AC_I3_O1"
 #PRJS="PRJ_LITECH_AC_I1_O1 PRJ_LITECH_AC_I3_O1"
 #PRJS="PRJ_RELEASE_DC_I_DC_O PRJ_RELEASE_AC_I1_O1 PRJ_RELEASE_AC_I3_O1 PRJ_RELEASE_AC_I3_O3"
 #PRJS="PRJ_LITECH_AC_I1_O1 PRJ_LITECH_AC_I3_O1 PRJ_XIAN_AC_I1_O1_P4 PRJ_XIAN_AC_I1_O1_P8"
@@ -122,6 +124,15 @@ function do_copy()
     elif [ "$1" = "PRJ_TEST" ]; then
         name=ac_in3_out1_test
         cp -f $custdir/logo/logo_neuter.png $curdir/output/t113i/root/run/app/image/logo.png
+    elif [ "$1" = "PRJ_TEST_AC_I1_O1" ]; then
+        name=ac_in1_out1_test
+        cp -f $custdir/logo/logo_neuter.png $curdir/output/t113i/root/run/app/image/logo.png
+    elif [ "$1" = "PRJ_TEST_AC_I3_O1" ]; then
+        name=ac_in3_out1_test
+        cp -f $custdir/logo/logo_neuter.png $curdir/output/t113i/root/run/app/image/logo.png
+    elif [ "$1" = "PRJ_TEST" ]; then
+        name=ac_in3_out1_test
+        cp -f $custdir/logo/logo_neuter.png $curdir/output/t113i/root/run/app/image/logo.png
     else
         echo error! $RPJ not define!!!
         exit 1

+ 144 - 0
tools/mb/cfg.h

@@ -0,0 +1,144 @@
+#ifndef _CFG_H_
+#define _CFG_H_
+
+#include "stdint.h"
+
+#define TRIPHASIC   0
+#define SINGLE			0
+
+#define MD_BASE_Addr   (1500)
+
+#define MD_STATUS_Addr 1
+
+
+
+
+
+
+
+
+
+#define MD_WRITE_Addr  50
+
+#define MD_READ_STATUS (MD_BASE_Addr + MD_STATUS_Addr)
+#define MD_WRIE_DATA   (MD_BASE_Addr+MD_WRITE_Addr)
+
+
+
+#define BOOT_LOADER              					((uint32_t)(0x08000000))	      	//boot loadr addr
+#define BOOT_LOADER_SIZE							(20*1024)							//boot loade size
+
+
+#define META_DATA 				 					((uint32_t)(0x08005000))			//meta data addr
+#define META_DATA_SIZE     							(1*1024)								//meta data size
+
+#define PROGRAME_APP1			 					((uint32_t)(0x08005400))			//App1 Rom Start addr
+#define PROGRAME_APP1_SIZE							(20*1024)							//App1 programe Max size
+
+#define PROGRAME_APP2								((uint32_t)(0x0800A400))			//App2 Rom Start addr
+#define PROGRAME_APP2_SIZE							(20*1024)							//App2 programe Max size
+
+#define PARTITION                                    1
+#define VERSION										"V1.0.0.0"
+
+#define MODBUS_HEAD									"GOWONE_UPGRADE"
+
+#define MB_Boot_Loader_Version_Addr  		1
+#define MB_Boot_APP1_Version						2
+#define MB_Boot_APP2_Version            3
+
+#define MB_default_Start_Area						4							//defalut start						and defalut app1
+
+#define MB_Last_Running_Area						5
+#define MB_Last_Running_Error						6							//running error number
+#define MB_Upload_Status                7
+#define MB_APP1_CRC											8
+#define MB_APP2_CRC											9
+
+
+
+#define MB_Upload_Area									30
+
+#define MB_META_DATA_Addr  							31
+#define MB_META_DATA_Addr_BytN   				20
+
+#define MB_Recive_Data									32
+#define MB_Recive_Over									33
+
+#define MB_Start_Area                   34
+
+
+#define BOOT_Version      							(MD_BASE_Addr + MB_Boot_Loader_Version_Addr)
+#define BOOT_APP1_Version 							(MD_BASE_Addr + MB_Boot_APP1_Version)
+#define BOOT_APP2_Version 							(MD_BASE_Addr + MB_Boot_APP2_Version)
+
+#define BOOT_Last_Running_Area 					(MD_BASE_Addr + MB_Last_Running_Area)
+#define BOOT_Last_Running_Error					(MD_BASE_Addr + MB_Last_Running_Error)
+
+#define BOOT_Upload_Status							(MD_BASE_Addr + MB_Upload_Status)
+#define BOOT_APP1_CRC										(MD_BASE_Addr + MB_APP1_CRC)
+#define BOOT_APP2_CRC										(MD_BASE_Addr + MB_APP2_CRC)
+
+
+
+#define BOOT_Upload_Area								(MD_BASE_Addr + MB_Upload_Area)
+#define BOOT_META_DATA									(MD_BASE_Addr + MB_META_DATA_Addr)
+#define BOOT_Recive_Data								(MD_BASE_Addr + MB_Recive_Data)
+#define BOOT_Recive_Over								(MD_BASE_Addr + MB_Recive_Over)
+#define BOOT_Start_Area									(MD_BASE_Addr + MB_Start_Area)
+
+
+
+#define MAX_LENTH  (128)
+#define Mb_Wcmd_Width       16
+
+
+
+#define NOERROR      0
+#define MAX_ERROR_COUNT   2
+
+
+#define ERROR_VERSION  0xFFFFFFFF
+
+
+typedef struct {
+	int index;
+	uint16_t lenth;
+	uint8_t recive[MAX_LENTH];
+}Flash_Data;
+
+typedef struct
+{
+	uint8_t flag;
+	uint16_t base_addr;
+	Flash_Data flash_Data;
+}MD_DATA;
+
+typedef struct {
+	uint32_t operation_flag;						// 0
+	uint32_t partition;									// 1
+	uint32_t errno;											// 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;						// 2
+}META_DATA_S;
+
+
+
+typedef struct g_MD_Data{
+	uint8_t count;
+	MD_DATA data[Mb_Wcmd_Width];
+}g_MD_Data;
+
+g_MD_Data* get_md_data();
+
+
+#endif
+

+ 488 - 0
tools/mb/mb.cpp

@@ -0,0 +1,488 @@
+#include <windows.h>
+#include <tchar.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#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 struct {
+	uint8_t         magic[14];
+	uint16_t        size;
+	uint32_t        partition;
+	uint32_t		version;
+}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
+}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, md5_t* m)
+{
+	uint8_t i; 
+
+	printf("__%s", s);
+	for (i = 0; i < 32; i++) {
+		printf("%c", m->digit[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<p2) {
+		return p1;
+	}
+	return NULL;
+}
+static uint32_t get_int(char* buf, const char* tok)
+{
+	int x;
+	uint32_t v = 1;
+	char *t,tmp[100];
+	char* p = get_token(buf, tok);
+	if (!p) {
+		return -1;
+	}
+	t = strstr_line(p, "0x");
+	if (!t) {
+		t = strstr_line(p, "0X");
+	}
+	if (t) {
+		p = t;
+	}
+
+	while (1) {
+		if (isdigit(*p)) {
+			x = digit_cpy(tmp, p);
+			v *= strtol(tmp, NULL, x);
+			p += strlen(tmp);
+		}
+		else {
+			if (!isgraph(*p)) {
+				break;
+			}
+			p++;
+		}
+	}
+
+	return v;
+}
+/////////////////////////////////////////////
+static uint32_t get_version(char *buf, const char *tok)
+{
+	char tmp[10];
+	uint32_t v, i = 0, j = 3;
+	uint8_t* p8 = (uint8_t*)&v;
+	char* p = get_token(buf, tok);
+
+	if (!p) {
+		return -1;
+	}
+	while (!isdigit(*p)) p++;
+
+	while (*p) {
+		if (isdigit(*p)) {
+			tmp[i++] = *p;
+		}
+		else {
+			if (!isgraph(*p)) {
+				break;
+			}
+			if (i > 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");
+
+	//fill hdr
+	get_magic(buf, "MODBUS_HEAD", hdr->magic);
+	hdr->size = 0;
+	hdr->version = version;
+	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 = partition;						// 1
+	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 = partition;				        // 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);
+	if (img->info.data) {
+		memcpy(img->info.data, inf, sizeof(fw_info_t));
+	}
+
+	img->app1.blen = get_int(buf, "PROGRAME_APP1_SIZE");
+	img->app1.data = my_malloc(img->app1.blen);
+
+	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);
+		data->dlen = flen;
+	}
+	if (data->data == NULL) {
+		printf("___ data->data is NULL\n");
+		goto quit;
+	}
+	
+	r = ReadFile(hFile, data->data, data->dlen, &rlen, NULL);
+	if (r==FALSE) {
+		printf("ReadFile fw failed\n");
+		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, &ltime);
+	FileTimeToSystemTime(&ltime, &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_t md5;
+
+	if (argc==2) {
+		printf("make to a upgrade file\n");
+	}
+	else if(argc == 3){
+		printf("make 2 files to a single bin\n");
+		make_single_bin = 1;
+	}
+	else {
+		printf("usage: mb app.bin or mb boot.bin app.bin\n");
+		return -1;
+	}
+	r = file_read(cfgPath, &fcfg);
+	if (r) {
+		goto fail;
+	}
+
+	get_info(fcfg.data, &fwHdr, &fwInfo, &fwImg);
+	get_ver(version, fwHdr.version);
+
+	path1 = argv[1];
+	if (make_single_bin) {
+		
+		xpath1 = char_to_tchar(path1);
+		flen = file_read(xpath1, &fwImg.boot);
+		if (flen < 0) {
+			goto fail;
+		}
+
+		path2 = argv[2];
+		xpath2 = char_to_tchar(path2);
+		flen = file_read(xpath2, &fwImg.app1);
+		if (flen < 0) {
+			goto fail;
+		}
+
+		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);
+		WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL);
+	}
+	else {
+		xpath1 = char_to_tchar(path1);
+		flen = file_read(xpath1, &fupg);
+		if (flen < 0) {
+			goto fail;
+		}
+		get_time(xpath1, time1, sizeof(time1));
+
+		strcpy(imgPath, path1);
+		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(&fwHdr, sizeof(fwHdr), fupg.data, fupg.dlen, (char*)md5.digit);
+		WriteFile(hFile, &fwHdr, sizeof(fwHdr), NULL, NULL);
+		WriteFile(hFile, fupg.data, fupg.blen, 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;
+}
+

+ 31 - 0
tools/mb/mb.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34902.65
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mb", "mb.vcxproj", "{2105DF33-3711-405F-8DDE-CDA04F7D926B}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{2105DF33-3711-405F-8DDE-CDA04F7D926B}.Debug|x64.ActiveCfg = Debug|x64
+		{2105DF33-3711-405F-8DDE-CDA04F7D926B}.Debug|x64.Build.0 = Debug|x64
+		{2105DF33-3711-405F-8DDE-CDA04F7D926B}.Debug|x86.ActiveCfg = Debug|Win32
+		{2105DF33-3711-405F-8DDE-CDA04F7D926B}.Debug|x86.Build.0 = Debug|Win32
+		{2105DF33-3711-405F-8DDE-CDA04F7D926B}.Release|x64.ActiveCfg = Release|x64
+		{2105DF33-3711-405F-8DDE-CDA04F7D926B}.Release|x64.Build.0 = Release|x64
+		{2105DF33-3711-405F-8DDE-CDA04F7D926B}.Release|x86.ActiveCfg = Release|Win32
+		{2105DF33-3711-405F-8DDE-CDA04F7D926B}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {0558E62C-8D67-4FBA-AC34-BF1BD6ACF5E1}
+	EndGlobalSection
+EndGlobal

+ 138 - 0
tools/mb/mb.vcxproj

@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>17.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{2105df33-3711-405f-8dde-cda04f7d926b}</ProjectGuid>
+    <RootNamespace>mb</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="mb.cpp" />
+    <ClCompile Include="md5.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 25 - 0
tools/mb/mb.vcxproj.filters

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="源文件">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="头文件">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="资源文件">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="mb.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="md5.c">
+      <Filter>源文件</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 192 - 0
tools/mb/md5.c

@@ -0,0 +1,192 @@
+#include <string.h>
+#include "md5.h"  
+  
+uint8_t PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  
+  
+void md5_init(md5_ctx_t *ctx)
+{  
+    ctx->count[0] = 0;
+    ctx->count[1] = 0;
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+}  
+void md5_update(md5_ctx_t* ctx, uint8_t *input,uint32_t inputlen)
+{  
+    uint32_t i = 0,index = 0,partlen = 0;  
+    index = (ctx->count[0] >> 3) & 0x3F;
+    partlen = 64 - index;  
+    ctx->count[0] += inputlen << 3;
+    if(ctx->count[0] < (inputlen << 3))
+        ctx->count[1]++;
+    ctx->count[1] += inputlen >> 29;
+  
+    if(inputlen >= partlen)  
+    {  
+        memcpy(&ctx->buffer[index],input,partlen);
+        md5_transform(ctx->state, ctx->buffer);
+        for(i = partlen;i+64 <= inputlen;i+=64)  
+            md5_transform(ctx->state,&input[i]);
+        index = 0;          
+    }    
+    else  
+    {  
+        i = 0;  
+    }  
+    memcpy(&ctx->buffer[index],&input[i],inputlen-i);
+}  
+void md5_final(md5_ctx_t* ctx,uint8_t digest[16])
+{  
+    uint32_t index = 0,padlen = 0;  
+    uint8_t bits[8];  
+    index = (ctx->count[0] >> 3) & 0x3F;
+    padlen = (index < 56)?(56-index):(120-index);  
+    md5_encode(bits, ctx->count,8);
+    md5_update(ctx,PADDING,padlen);
+    md5_update(ctx,bits,8);
+    md5_encode(digest, ctx->state,16);
+}  
+void md5_encode(uint8_t *output,uint32_t *input,uint32_t len)  
+{  
+    uint32_t i = 0,j = 0;  
+    while(j < len)  
+    {  
+        output[j] = input[i] & 0xFF;    
+        output[j+1] = (input[i] >> 8) & 0xFF;  
+        output[j+2] = (input[i] >> 16) & 0xFF;  
+        output[j+3] = (input[i] >> 24) & 0xFF;  
+        i++;  
+        j+=4;  
+    }  
+}  
+void md5_decode(uint32_t *output,uint8_t *input,uint32_t len)  
+{  
+    uint32_t i = 0,j = 0;  
+    while(j < len)  
+    {  
+        output[i] = (input[j]) |  
+            (input[j+1] << 8) |  
+            (input[j+2] << 16) |  
+            (input[j+3] << 24);  
+        i++;  
+        j+=4;   
+    }  
+}  
+void md5_transform(uint32_t state[4],uint8_t block[64])  
+{  
+    uint32_t a = state[0];  
+    uint32_t b = state[1];  
+    uint32_t c = state[2];  
+    uint32_t d = state[3];  
+    uint32_t x[64];  
+    md5_decode(x,block,64);  
+    FF(a, b, c, d, x[ 0], 7, 0xd76aa478);   
+    FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);   
+    FF(c, d, a, b, x[ 2], 17, 0x242070db);   
+    FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);   
+    FF(a, b, c, d, x[ 4], 7, 0xf57c0faf);   
+    FF(d, a, b, c, x[ 5], 12, 0x4787c62a);   
+    FF(c, d, a, b, x[ 6], 17, 0xa8304613);   
+    FF(b, c, d, a, x[ 7], 22, 0xfd469501);   
+    FF(a, b, c, d, x[ 8], 7, 0x698098d8);   
+    FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);   
+    FF(c, d, a, b, x[10], 17, 0xffff5bb1);   
+    FF(b, c, d, a, x[11], 22, 0x895cd7be);   
+    FF(a, b, c, d, x[12], 7, 0x6b901122);   
+    FF(d, a, b, c, x[13], 12, 0xfd987193);   
+    FF(c, d, a, b, x[14], 17, 0xa679438e);   
+    FF(b, c, d, a, x[15], 22, 0x49b40821);   
+  
+      
+    GG(a, b, c, d, x[ 1], 5, 0xf61e2562);   
+    GG(d, a, b, c, x[ 6], 9, 0xc040b340);   
+    GG(c, d, a, b, x[11], 14, 0x265e5a51);   
+    GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);   
+    GG(a, b, c, d, x[ 5], 5, 0xd62f105d);   
+    GG(d, a, b, c, x[10], 9,  0x2441453);   
+    GG(c, d, a, b, x[15], 14, 0xd8a1e681);   
+    GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);   
+    GG(a, b, c, d, x[ 9], 5, 0x21e1cde6);   
+    GG(d, a, b, c, x[14], 9, 0xc33707d6);   
+    GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);   
+    GG(b, c, d, a, x[ 8], 20, 0x455a14ed);   
+    GG(a, b, c, d, x[13], 5, 0xa9e3e905);   
+    GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8);   
+    GG(c, d, a, b, x[ 7], 14, 0x676f02d9);   
+    GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);   
+  
+      
+    HH(a, b, c, d, x[ 5], 4, 0xfffa3942);   
+    HH(d, a, b, c, x[ 8], 11, 0x8771f681);   
+    HH(c, d, a, b, x[11], 16, 0x6d9d6122);   
+    HH(b, c, d, a, x[14], 23, 0xfde5380c);   
+    HH(a, b, c, d, x[ 1], 4, 0xa4beea44);   
+    HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);   
+    HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);   
+    HH(b, c, d, a, x[10], 23, 0xbebfbc70);   
+    HH(a, b, c, d, x[13], 4, 0x289b7ec6);   
+    HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);   
+    HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);   
+    HH(b, c, d, a, x[ 6], 23,  0x4881d05);   
+    HH(a, b, c, d, x[ 9], 4, 0xd9d4d039);   
+    HH(d, a, b, c, x[12], 11, 0xe6db99e5);   
+    HH(c, d, a, b, x[15], 16, 0x1fa27cf8);   
+    HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);   
+  
+      
+    II(a, b, c, d, x[ 0], 6, 0xf4292244);   
+    II(d, a, b, c, x[ 7], 10, 0x432aff97);   
+    II(c, d, a, b, x[14], 15, 0xab9423a7);   
+    II(b, c, d, a, x[ 5], 21, 0xfc93a039);   
+    II(a, b, c, d, x[12], 6, 0x655b59c3);   
+    II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);   
+    II(c, d, a, b, x[10], 15, 0xffeff47d);   
+    II(b, c, d, a, x[ 1], 21, 0x85845dd1);   
+    II(a, b, c, d, x[ 8], 6, 0x6fa87e4f);   
+    II(d, a, b, c, x[15], 10, 0xfe2ce6e0);   
+    II(c, d, a, b, x[ 6], 15, 0xa3014314);   
+    II(b, c, d, a, x[13], 21, 0x4e0811a1);   
+    II(a, b, c, d, x[ 4], 6, 0xf7537e82);   
+    II(d, a, b, c, x[11], 10, 0xbd3af235);   
+    II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);   
+    II(b, c, d, a, x[ 9], 21, 0xeb86d391);   
+    state[0] += a;  
+    state[1] += b;  
+    state[2] += c;  
+    state[3] += d;  
+}
+
+#define CHAR(b) (b<=9)?(b+0x30):(b-10+0x61);
+static void byte2char(char *chr, uint8_t b)
+{
+    char h,l;
+    
+    l = b&0x0f;
+    h = (b>>4)&0x0f;
+    
+    chr[0] = CHAR(h);
+    chr[1] = CHAR(l);
+}
+
+int md5_calc(void *p1, int len1, void *p2, int len2, char *md5)
+{
+    int i;
+    uint8_t tmp[16];
+    md5_ctx_t ctx;
+    
+    md5_init(&ctx);
+    md5_update(&ctx, (uint8_t*)p1, len1);
+    md5_update(&ctx, (uint8_t*)p2, len2);
+    md5_final(&ctx, tmp);
+    
+    for (i=0; i<16; i++) {
+        byte2char(&md5[i*2], tmp[i]);
+    }
+    
+    return 0;
+}
+

+ 68 - 0
tools/mb/md5.h

@@ -0,0 +1,68 @@
+#ifndef MD5_H  
+#define MD5_H  
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct
+{
+	uint32_t count[2];
+	uint32_t state[4];
+	uint8_t buffer[64];
+}md5_ctx_t;
+
+
+#define F(x,y,z) ((x & y) | (~x & z))  
+#define G(x,y,z) ((x & z) | (y & ~z))  
+#define H(x,y,z) (x^y^z)  
+#define I(x,y,z) (y ^ (x | ~z))  
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))  
+
+#define FF(a,b,c,d,x,s,ac) \
+	{ \
+		a += F(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define GG(a,b,c,d,x,s,ac) \
+	{ \
+		a += G(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define HH(a,b,c,d,x,s,ac) \
+	{ \
+		a += H(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define II(a,b,c,d,x,s,ac) \
+	{ \
+		a += I(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+void md5_init(md5_ctx_t* context);
+void md5_update(md5_ctx_t* context, uint8_t* input, uint32_t inputlen);
+void md5_final(md5_ctx_t* context, uint8_t digest[16]);
+void md5_transform(uint32_t state[4], uint8_t block[64]);
+void md5_encode(uint8_t* output, uint32_t* input, uint32_t len);
+void md5_decode(uint32_t* output, uint8_t* input, uint32_t len);
+
+int md5_calc(void* p1, int len1, void* p2, int len2, char* md5);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif  

+ 104 - 0
tools/mb/mu.cpp

@@ -0,0 +1,104 @@
+#include "myFile.h"
+#include "protocol.h"
+#include "datetime.h"
+#include "md5.h"
+
+
+TCHAR* cfgPath = (TCHAR*)__TEXT("./user/cfg.h");
+
+static void print_fw(const char* s, fw_hdr_t* hdr)
+{
+	printf("\n");
+	printf("__%s__hdr.fw.magic:     0x%08x\n", s, hdr->fw.magic);
+	printf("__%s__hdr.fw.version:   %s\n", s, hdr->fw.version);
+	printf("__%s__hdr.fw.length:    %d\n", s, hdr->fw.length);
+	printf("__%s__hdr.fw.bldtime:   %s\n", s, hdr->fw.bldtime);
+
+	printf("__%s__hdr.upg.obj:      %d\n", s, hdr->upg.obj);
+	printf("__%s__hdr.upg.force:    %d\n", s, hdr->upg.force);
+	printf("__%s__hdr.upg.erase:    %d\n", s, hdr->upg.erase);
+	printf("__%s__hdr.upg.flag :    %d\n", s, hdr->upg.flag);
+	printf("__%s__hdr.upg.jumpAddr: 0x%08x\n", s, hdr->upg.jumpAddr);
+	printf("\n");
+}
+
+
+static void print_md5(const char* s, md5_t* m)
+{
+	U8 i;
+
+	printf("__%s", s);
+	for (i = 0; i < 32; i++) {
+		printf("%c", m->digit[i]);
+	}
+	printf("\n");
+}
+
+int main(char argc, char *argv[])
+{
+	int r;
+	FILE* fp;
+	data_t dat;
+	md5_t md5;
+	char newPath[1000];
+	fw_hdr_t hdr;
+	char* path = argv[1];
+	//char* goal = argv[1];
+	TCHAR* xPath;
+	myFile mf;
+
+	//TCHAR curPath[500];
+	//GetCurrentDirectory(500, curPath);
+	//_tprintf(_T("curPath: %s\n"), curPath);
+    
+	if(argc<2) {
+		printf("usage: mu.exe app.bin\n");
+		return -1;
+	}
+
+	xPath = mf.char_to_tchar(path);
+	if (!xPath) {
+		printf("char_to_tchar failed\n");
+		return -1;
+	}
+
+	strcpy(newPath, path);
+	char* dot = strrchr(newPath, '.');
+	if (dot) *(dot + 1) = 0;
+	strcat(newPath, "upg");
+
+	fp = fopen(newPath, "wb");
+	if (!fp) {
+		printf("%s create failed\r\n", newPath);
+		return -1;
+	}
+
+	r = mf.read_file(xPath, &dat);
+	if (r) {
+		return -1;
+	}
+
+	hdr.upg.obj = OBJ_APP;
+	hdr.upg.force = 0;
+	hdr.upg.erase = 0;
+	hdr.upg.flag = 0;
+	hdr.upg.jumpAddr = 0;
+	hdr.fw.magic = FW_MAGIC;
+	hdr.fw.length = dat.dlen;
+	mf.get_version(cfgPath, hdr.fw.version, sizeof(hdr.fw.version));
+	mf.get_time(xPath, (char*)hdr.fw.bldtime, sizeof(hdr.fw.bldtime));
+	print_fw("$$$", &hdr);
+
+	md5_calc(&hdr, sizeof(hdr), dat.data, dat.dlen, (char*)md5.digit);
+	fwrite(&hdr, 1, sizeof(hdr), fp);
+	fwrite(dat.data, 1, dat.dlen, fp);
+	fwrite(&md5, 1, sizeof(md5), fp);
+	print_md5("md5: ", &md5);
+
+	fclose(fp);
+	free(dat.data);
+	delete xPath;
+
+	return 0;
+}
+

+ 68 - 0
tools/merge/Makefile

@@ -0,0 +1,68 @@
+TARGET=merge
+OUT_DIR=
+
+CUR_DIR=$(shell pwd)
+SRC_DIR=$(CUR_DIR)
+BLD_DIR=$(SRC_DIR)/build2
+OUT_DIR=$(CUR_DIR)
+
+T113_DIR=/home/tronlong/T113
+BR_DIR=$(T113_DIR)/T113-i_v1.0/out/t113_i/tlt113-evm-emmc/longan/buildroot
+SYS_DIR=$(BR_DIR)/host/arm-buildroot-linux-gnueabi/sysroot
+BIN_DIR=$(BR_DIR)/host/bin
+BIN_PRE=$(BIN_DIR)/arm-linux-gnueabi-
+
+SYS_DIR=
+BIN_PRE=
+
+CC=$(BIN_PRE)gcc
+CXX=$(BIN_PRE)g++
+LD=$(BIN_PRE)gcc
+AS=$(BIN_PRE)as
+AR=$(BIN_PRE)ar
+GDB=$(BIN_PRE)gdb
+DUMP=$(BIN_PRE)objdump
+STRIP=$(BIN_PRE)strip
+READELF=$(BIN_PRE)readelf
+
+CFILES += md5.cpp myFile.cpp merge.cpp
+
+         
+DFLAGS += -DINNER_USE
+IFLAGS += -I$(SYS_DIR)/usr/include \
+          -I../../upgd
+
+
+OBJS = $(addprefix $(BLD_DIR)/,$(CFILES:.cpp=.o))
+DFILES = $(OBJS:.o=.d)
+########################################
+
+
+$(warning $(OBJS))
+
+DEPFLAGS += -MMD -MP -MF $(@:.o=.d)
+CFLAGS += $(IFLAGS) $(DFLAGS) $(DEPFLAGS)
+
+LDFLAGS += -s -lstdc++ 
+
+########################################
+
+
+.PHONEY: all clean
+
+all: $(TARGET)
+
+$(TARGET): $(OBJS)
+	@$(LD) $(LDFLAGS) $^ -o $(BLD_DIR)/$@
+	-cp -uf $(BLD_DIR)/$@ $(OUT_DIR)/
+
+$(BLD_DIR)/%.o:$(SRC_DIR)/%.cpp Makefile
+	@mkdir -p $(dir $@)
+	$(CXX) -c $(CFLAGS) $< -o $@
+
+clean:
+	rm -rf $(BLD_DIR) $(TARGET)
+
+
+
+-include $(DFILES)

+ 192 - 0
tools/merge/md5.cpp

@@ -0,0 +1,192 @@
+#include <string.h>
+#include "md5.h"  
+  
+uint8_t PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  
+  
+void md5_init(md5_ctx_t *ctx)
+{  
+    ctx->count[0] = 0;
+    ctx->count[1] = 0;
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+}  
+void md5_update(md5_ctx_t* ctx, uint8_t *input,uint32_t inputlen)
+{  
+    uint32_t i = 0,index = 0,partlen = 0;  
+    index = (ctx->count[0] >> 3) & 0x3F;
+    partlen = 64 - index;  
+    ctx->count[0] += inputlen << 3;
+    if(ctx->count[0] < (inputlen << 3))
+        ctx->count[1]++;
+    ctx->count[1] += inputlen >> 29;
+  
+    if(inputlen >= partlen)  
+    {  
+        memcpy(&ctx->buffer[index],input,partlen);
+        md5_transform(ctx->state, ctx->buffer);
+        for(i = partlen;i+64 <= inputlen;i+=64)  
+            md5_transform(ctx->state,&input[i]);
+        index = 0;          
+    }    
+    else  
+    {  
+        i = 0;  
+    }  
+    memcpy(&ctx->buffer[index],&input[i],inputlen-i);
+}  
+void md5_final(md5_ctx_t* ctx,uint8_t digest[16])
+{  
+    uint32_t index = 0,padlen = 0;  
+    uint8_t bits[8];  
+    index = (ctx->count[0] >> 3) & 0x3F;
+    padlen = (index < 56)?(56-index):(120-index);  
+    md5_encode(bits, ctx->count,8);
+    md5_update(ctx,PADDING,padlen);
+    md5_update(ctx,bits,8);
+    md5_encode(digest, ctx->state,16);
+}  
+void md5_encode(uint8_t *output,uint32_t *input,uint32_t len)  
+{  
+    uint32_t i = 0,j = 0;  
+    while(j < len)  
+    {  
+        output[j] = input[i] & 0xFF;    
+        output[j+1] = (input[i] >> 8) & 0xFF;  
+        output[j+2] = (input[i] >> 16) & 0xFF;  
+        output[j+3] = (input[i] >> 24) & 0xFF;  
+        i++;  
+        j+=4;  
+    }  
+}  
+void md5_decode(uint32_t *output,uint8_t *input,uint32_t len)  
+{  
+    uint32_t i = 0,j = 0;  
+    while(j < len)  
+    {  
+        output[i] = (input[j]) |  
+            (input[j+1] << 8) |  
+            (input[j+2] << 16) |  
+            (input[j+3] << 24);  
+        i++;  
+        j+=4;   
+    }  
+}  
+void md5_transform(uint32_t state[4],uint8_t block[64])  
+{  
+    uint32_t a = state[0];  
+    uint32_t b = state[1];  
+    uint32_t c = state[2];  
+    uint32_t d = state[3];  
+    uint32_t x[64];  
+    md5_decode(x,block,64);  
+    FF(a, b, c, d, x[ 0], 7, 0xd76aa478);   
+    FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);   
+    FF(c, d, a, b, x[ 2], 17, 0x242070db);   
+    FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);   
+    FF(a, b, c, d, x[ 4], 7, 0xf57c0faf);   
+    FF(d, a, b, c, x[ 5], 12, 0x4787c62a);   
+    FF(c, d, a, b, x[ 6], 17, 0xa8304613);   
+    FF(b, c, d, a, x[ 7], 22, 0xfd469501);   
+    FF(a, b, c, d, x[ 8], 7, 0x698098d8);   
+    FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);   
+    FF(c, d, a, b, x[10], 17, 0xffff5bb1);   
+    FF(b, c, d, a, x[11], 22, 0x895cd7be);   
+    FF(a, b, c, d, x[12], 7, 0x6b901122);   
+    FF(d, a, b, c, x[13], 12, 0xfd987193);   
+    FF(c, d, a, b, x[14], 17, 0xa679438e);   
+    FF(b, c, d, a, x[15], 22, 0x49b40821);   
+  
+      
+    GG(a, b, c, d, x[ 1], 5, 0xf61e2562);   
+    GG(d, a, b, c, x[ 6], 9, 0xc040b340);   
+    GG(c, d, a, b, x[11], 14, 0x265e5a51);   
+    GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);   
+    GG(a, b, c, d, x[ 5], 5, 0xd62f105d);   
+    GG(d, a, b, c, x[10], 9,  0x2441453);   
+    GG(c, d, a, b, x[15], 14, 0xd8a1e681);   
+    GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);   
+    GG(a, b, c, d, x[ 9], 5, 0x21e1cde6);   
+    GG(d, a, b, c, x[14], 9, 0xc33707d6);   
+    GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);   
+    GG(b, c, d, a, x[ 8], 20, 0x455a14ed);   
+    GG(a, b, c, d, x[13], 5, 0xa9e3e905);   
+    GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8);   
+    GG(c, d, a, b, x[ 7], 14, 0x676f02d9);   
+    GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);   
+  
+      
+    HH(a, b, c, d, x[ 5], 4, 0xfffa3942);   
+    HH(d, a, b, c, x[ 8], 11, 0x8771f681);   
+    HH(c, d, a, b, x[11], 16, 0x6d9d6122);   
+    HH(b, c, d, a, x[14], 23, 0xfde5380c);   
+    HH(a, b, c, d, x[ 1], 4, 0xa4beea44);   
+    HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);   
+    HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);   
+    HH(b, c, d, a, x[10], 23, 0xbebfbc70);   
+    HH(a, b, c, d, x[13], 4, 0x289b7ec6);   
+    HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);   
+    HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);   
+    HH(b, c, d, a, x[ 6], 23,  0x4881d05);   
+    HH(a, b, c, d, x[ 9], 4, 0xd9d4d039);   
+    HH(d, a, b, c, x[12], 11, 0xe6db99e5);   
+    HH(c, d, a, b, x[15], 16, 0x1fa27cf8);   
+    HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);   
+  
+      
+    II(a, b, c, d, x[ 0], 6, 0xf4292244);   
+    II(d, a, b, c, x[ 7], 10, 0x432aff97);   
+    II(c, d, a, b, x[14], 15, 0xab9423a7);   
+    II(b, c, d, a, x[ 5], 21, 0xfc93a039);   
+    II(a, b, c, d, x[12], 6, 0x655b59c3);   
+    II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);   
+    II(c, d, a, b, x[10], 15, 0xffeff47d);   
+    II(b, c, d, a, x[ 1], 21, 0x85845dd1);   
+    II(a, b, c, d, x[ 8], 6, 0x6fa87e4f);   
+    II(d, a, b, c, x[15], 10, 0xfe2ce6e0);   
+    II(c, d, a, b, x[ 6], 15, 0xa3014314);   
+    II(b, c, d, a, x[13], 21, 0x4e0811a1);   
+    II(a, b, c, d, x[ 4], 6, 0xf7537e82);   
+    II(d, a, b, c, x[11], 10, 0xbd3af235);   
+    II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);   
+    II(b, c, d, a, x[ 9], 21, 0xeb86d391);   
+    state[0] += a;  
+    state[1] += b;  
+    state[2] += c;  
+    state[3] += d;  
+}
+
+#define CHAR(b) (b<=9)?(b+0x30):(b-10+0x61);
+static void byte2char(char *chr, uint8_t b)
+{
+    char h,l;
+    
+    l = b&0x0f;
+    h = (b>>4)&0x0f;
+    
+    chr[0] = CHAR(h);
+    chr[1] = CHAR(l);
+}
+
+int md5_calc(void *p1, int len1, void *p2, int len2, char *md5)
+{
+    int i;
+    uint8_t tmp[16];
+    md5_ctx_t ctx;
+    
+    md5_init(&ctx);
+    md5_update(&ctx, (uint8_t*)p1, len1);
+    md5_update(&ctx, (uint8_t*)p2, len2);
+    md5_final(&ctx, tmp);
+    
+    for (i=0; i<16; i++) {
+        byte2char(&md5[i*2], tmp[i]);
+    }
+    
+    return 0;
+}
+

+ 68 - 0
tools/merge/md5.h

@@ -0,0 +1,68 @@
+#ifndef MD5_H  
+#define MD5_H  
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct
+{
+	uint32_t count[2];
+	uint32_t state[4];
+	uint8_t buffer[64];
+}md5_ctx_t;
+
+
+#define F(x,y,z) ((x & y) | (~x & z))  
+#define G(x,y,z) ((x & z) | (y & ~z))  
+#define H(x,y,z) (x^y^z)  
+#define I(x,y,z) (y ^ (x | ~z))  
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))  
+
+#define FF(a,b,c,d,x,s,ac) \
+	{ \
+		a += F(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define GG(a,b,c,d,x,s,ac) \
+	{ \
+		a += G(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define HH(a,b,c,d,x,s,ac) \
+	{ \
+		a += H(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+#define II(a,b,c,d,x,s,ac) \
+	{ \
+		a += I(b, c, d) + x + ac; \
+		a = ROTATE_LEFT(a, s); \
+		a += b; \
+	}
+
+void md5_init(md5_ctx_t* context);
+void md5_update(md5_ctx_t* context, uint8_t* input, uint32_t inputlen);
+void md5_final(md5_ctx_t* context, uint8_t digest[16]);
+void md5_transform(uint32_t state[4], uint8_t block[64]);
+void md5_encode(uint8_t* output, uint32_t* input, uint32_t len);
+void md5_decode(uint32_t* output, uint8_t* input, uint32_t len);
+
+int md5_calc(void* p1, int len1, void* p2, int len2, char* md5);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif  

+ 94 - 0
tools/merge/merge.cpp

@@ -0,0 +1,94 @@
+#include "myFile.h"
+#include "md5.h"
+#include "upgrade.h"
+
+
+static void print_md5(md5_t* m)
+{
+	int i;
+
+	printf("md5:");
+	for (i = 0; i < 32; i++) {
+		printf("%c", m->data[i]);
+	}
+}
+static void print_info(const char* s, upgrade_file_t* hdr, md5_t *m)
+{
+	printf("\n");
+	printf("__%s__hdr.magic:        0x%08x\n",  s, hdr->magic);
+	printf("__%s__hdr.obj.num:      %d\n",		s, hdr->obj.num);
+	printf("__%s__hdr.obj.stra:     %d\n",		s, hdr->obj.stra);
+	printf("__%s__hdr.obj.obj1:     %s\n",		s, hdr->obj.obj1);
+	printf("__%s__hdr.obj.obj2:     %s\n",		s, hdr->obj.obj2);
+	print_md5(m);
+}
+
+
+
+int main(int argc, char *argv[])
+{
+	int r;
+	FILE* fp;
+	node_t nd;
+	md5_t md5;
+	char newPath[1000];
+	upgrade_obj_t obj;
+	upgrade_file_t hdr;
+	char* path = NULL;
+	myFile mf;
+
+	//TCHAR curPath[500];
+	//GetCurrentDirectory(500, curPath);
+	//_tprintf(_T("curPath: %s\n"), curPath);
+    
+	if(argc<5) {
+		printf("usage: pack num stra obj1 obj2 packageFile\n");
+		return -1;
+	}
+
+	obj.num  = (uint8_t)atoi(argv[1]);
+	obj.stra = (uint8_t)atoi(argv[2]);
+	strcpy(obj.obj1, argv[3]);
+	strcpy(obj.obj2, argv[4]);
+	path = argv[5];
+
+	strcpy(newPath, path);
+	char* dot = strrchr(newPath, '/');
+	if (!dot) {
+		dot = strrchr(newPath, '\\');
+	}
+
+	if (dot) {
+		*(dot + 1) = 0;
+		strcat(newPath, "pdupkg");
+	}
+	else {
+		strcat(newPath, "./pdupkg");
+	}
+
+	fp = fopen(newPath, "wb");
+	if (!fp) {
+		printf("%s create failed\n", newPath);
+		return -1;
+	}
+
+	r = mf.read_file(path, &nd);
+	if (r) {
+		return -1;
+	}
+
+	hdr.magic = UPG_FILE_MAGIC;
+	hdr.obj = obj;
+
+	md5_calc(&hdr, sizeof(hdr), nd.pbuf, nd.dlen, (char*)md5.data);
+	fwrite(&hdr, 1, sizeof(hdr), fp);
+	fwrite(nd.pbuf, 1, nd.dlen, fp);
+	fwrite(&md5, 1, sizeof(md5), fp);
+	print_info("$$$", &hdr, &md5);
+
+	fclose(fp);
+	free(nd.pbuf);
+
+	return 0;
+}
+

+ 31 - 0
tools/merge/merge.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34902.65
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "merge", "merge.vcxproj", "{7B62227B-476E-4ABA-964B-750C2AE8AAF1}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{7B62227B-476E-4ABA-964B-750C2AE8AAF1}.Debug|x64.ActiveCfg = Debug|x64
+		{7B62227B-476E-4ABA-964B-750C2AE8AAF1}.Debug|x64.Build.0 = Debug|x64
+		{7B62227B-476E-4ABA-964B-750C2AE8AAF1}.Debug|x86.ActiveCfg = Debug|Win32
+		{7B62227B-476E-4ABA-964B-750C2AE8AAF1}.Debug|x86.Build.0 = Debug|Win32
+		{7B62227B-476E-4ABA-964B-750C2AE8AAF1}.Release|x64.ActiveCfg = Release|x64
+		{7B62227B-476E-4ABA-964B-750C2AE8AAF1}.Release|x64.Build.0 = Release|x64
+		{7B62227B-476E-4ABA-964B-750C2AE8AAF1}.Release|x86.ActiveCfg = Release|Win32
+		{7B62227B-476E-4ABA-964B-750C2AE8AAF1}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {E5D273D5-53E3-4C26-B93B-E545EFE2B862}
+	EndGlobalSection
+EndGlobal

+ 139 - 0
tools/merge/merge.vcxproj

@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>17.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{7b62227b-476e-4aba-964b-750c2ae8aaf1}</ProjectGuid>
+    <RootNamespace>merge</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <AdditionalIncludeDirectories>../../upgd</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="md5.cpp" />
+    <ClCompile Include="merge.cpp" />
+    <ClCompile Include="myFile.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 28 - 0
tools/merge/merge.vcxproj.filters

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="源文件">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="头文件">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="资源文件">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="merge.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="myFile.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="md5.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 195 - 0
tools/merge/myFile.cpp

@@ -0,0 +1,195 @@
+#include "myFile.h"
+
+
+int myFile::read_file(char* path, node_t* nd)
+{
+#ifdef _WIN32
+	char* pbuf;
+	HANDLE hFile;
+	DWORD  flen,rlen;
+	BOOL r;
+
+	hFile = CreateFileA(path,			//name
+		GENERIC_READ,                   //以读方式打开
+		FILE_SHARE_READ,               //可共享读
+		NULL,                           //默认安全设置
+		OPEN_EXISTING,                   //只打开已经存在的文件
+		FILE_ATTRIBUTE_NORMAL,           //常规文件属性
+		NULL);                           //无模板
+	if (hFile== INVALID_HANDLE_VALUE) {
+		printf("%s open failed, err: %d\n", path, GetLastError());
+		return -1;
+	}
+
+	flen = GetFileSize(hFile, NULL);
+	if (flen== INVALID_FILE_SIZE) {
+		printf("%s, get invalid file size!\n", path);
+		return -1;
+	}
+
+	pbuf = (char*)malloc(flen);
+	if (!pbuf) {
+		printf("malloc %d failed!\n", flen);
+		CloseHandle(hFile);
+		return -1;
+	}
+
+	r = ReadFile(hFile, pbuf, flen, &rlen, NULL);
+	if (r==FALSE) {
+		printf("ReadFile failed!\n");
+		CloseHandle(hFile);
+		return -1;
+	}
+
+	nd->pbuf = pbuf;
+	nd->dlen = rlen;
+	nd->blen = rlen;
+	CloseHandle(hFile);
+#else
+    struct stat st;
+    char* pbuf;
+	FILE* fp;
+	int  r,flen,rlen;
+
+    r = stat((const char *)path, &st);
+    if (r) {
+        return -1;
+    }
+    flen = st.st_size;
+
+    fp = fopen((const char *)path, "r");
+    if(!fp) {
+        printf("fopen %s failed!\n", path);
+		return -1;
+    }
+
+    pbuf = (char*)malloc(flen);
+	if (!pbuf) {
+		printf("malloc %d failed!\n", flen);
+		fclose(fp);
+		return -1;
+	}
+
+    r = fread(pbuf, 1, flen, fp);
+    if (r!=flen) {
+        printf("fread %s failed!\n", path);
+        fclose(fp);
+        return -1;
+    }
+
+    nd->pbuf = pbuf;
+    nd->dlen = rlen;
+    nd->blen = rlen;
+    fclose(fp);
+#endif
+
+	return 0;
+}
+
+int myFile::get_time(char *path, char *time, int len)
+{
+#ifdef _WIN32
+	FILETIME IpCreationTime;                 //文件的创建时间
+	FILETIME IpLastAccessTime;               //对文件的最近访问时间
+	FILETIME IpLastWriteTime;                //文件的最近修改时间
+	FILETIME ltime;
+	SYSTEMTIME rtime;
+
+	HANDLE hFile = CreateFileA(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, &ltime);
+	FileTimeToSystemTime(&ltime, &rtime);        //将文件时间转化为系统时间
+	snprintf(time, len, "%04u%02u%02u %02u:%02u:%02u", rtime.wYear, rtime.wMonth, rtime.wDay, rtime.wHour, rtime.wMinute, rtime.wSecond);
+#else
+    int r;
+    struct stat st;
+
+    r = stat((const char *)path, &st);
+    if (r) {
+        return -1;
+    }
+
+    struct tm* ptm=localtime(&st.st_atime);
+    snprintf(time, len, "%04u%02u%02u %02u:%02u:%02u \n", ptm->tm_year, ptm->tm_mon, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
+#endif
+
+	return 0;
+}
+
+
+int myFile::get_version(char* path, void* version, int len)
+{
+	int r=-1;
+	
+
+	return r;
+}
+
+
+char* myFile::wchar_to_char(wchar_t* wchr)
+{
+#ifdef _WIN32
+	int clen = WideCharToMultiByte(CP_ACP, 0, wchr, -1, NULL, 0, NULL, NULL);
+	char* chr = new char[clen];
+	WideCharToMultiByte(CP_ACP, 0, wchr, -1, chr, clen, NULL, NULL);
+#else
+    char* chr;
+    int r,len = wcslen(wchr) + 1;
+    
+    if(len <= 1)
+        return 0;
+    
+    chr = (char*)malloc(len);
+    if(!chr) {
+        return NULL;
+    }
+    
+    r = wcstombs(chr, wchr, len);
+    if(r<=0) {
+        free(chr);
+        chr = NULL;
+    }
+#endif
+
+	return chr;
+}
+
+wchar_t* myFile::char_to_wchar(char* chr)
+{
+#ifdef _WIN32
+	int clen = MultiByteToWideChar(CP_ACP, 0, chr, -1, NULL, 0);
+	wchar_t* wchr = new wchar_t[clen];
+	MultiByteToWideChar(CP_ACP, 0, chr, -1, wchr, clen);
+#else
+    wchar_t *wchr;
+    int r,len = strlen(chr) + 1;
+    
+    if(len <= 1)
+        return 0;
+
+    wchr = (wchar_t*)malloc(sizeof(wchar_t)*len);
+    if(!wchr) {
+        return NULL;
+    }
+    
+    r = mbstowcs(wchr, chr, sizeof(wchar_t)*len);
+    if(r<=0) {
+        free(wchr);
+        wchr = NULL;
+    }
+#endif
+
+	return wchr;
+}
+
+

+ 36 - 0
tools/merge/myFile.h

@@ -0,0 +1,36 @@
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <wchar.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include<sys/types.h>
+#include<sys/stat.h>
+#endif
+
+
+typedef struct {
+    char* pbuf;
+    int   dlen;
+    int   blen;
+}node_t;
+
+class myFile {
+
+public:
+    char* wchar_to_char(wchar_t* tchr);
+    wchar_t* char_to_wchar(char* chr);
+
+    int read_file(char* path, node_t* nd);
+    int get_time(char *path, char *time, int len);
+    int get_version(char* path, void* version, int len);
+    
+};
+
+
+
+