www.pudn.com > SysRecover.rar > LOADER.C


/******************************************************************** 
created:	2007/02/08 
created:	8:2:2007   9:38 
filename: 	C:\TC\SRC\LOADER.C 
file path:	C:\TC\SRC 
file base:	LOADER 
file ext:	C 
author:		LXD 
 
  purpose:	系统备份恢复 V1.0 
*********************************************************************/ 
#include  
#include  
#include  
#include  
#include  
 
#define uchar			unsigned char 
#define TRUE			1 
#define FALSE			0 
 
#define SCREEN_CENTER_H 40 
#define SCREEN_CENTER_V 12 
#define MAINFRAME_WIDTH 56 
 
#define MAINFRAME_SX	(SCREEN_CENTER_H - MAINFRAME_WIDTH / 2) 
#define MAINFRAME_EX	(MAINFRAME_SX + MAINFRAME_WIDTH - 1) 
 
struct { 
	char filename[16]; 
	char info[64]; 
} listitem[16]; /*菜单项信息*/ 
 
 
int pos_mainframe_sx = MAINFRAME_SX, 
pos_mainframe_sy, 
pos_mainframe_ex = MAINFRAME_EX, 
pos_mainframe_ey, 
 
pos_title_sx, 
pos_title_sy, 
pos_newfilename_sx, 
 
pos_list_sx = MAINFRAME_SX + 1, 
pos_list_sy, 
pos_list_ex = MAINFRAME_EX - 1; 
 
/************************************************************************/ 
/* 工作模式: 
0、恢复 
1、备份 
2、删除备份 
3、更改密码                                                         */ 
/************************************************************************/ 
uchar mode = 0; 
 
const char password_string[16] = "$%%#12345678#%%$"; /*以明文存放的密码*/ 
char password_saved[16] = ""; 
char *instance_name;		/*程序实例名,用于改写密码*/ 
 
char command[128] = "";		/*将执行的DOS命令*/ 
char title[48] = "";		/*标题*/ 
char status[64] = "";		/*状态栏*/ 
 
char newfilename[16] = "";	/*新建备份文件各*/ 
uchar cursor_pos = 0;		/*光标与输入框的相对位置*/ 
 
uchar filenumber = 0;		/*已存在的备份文件数*/ 
int last_sel = 0;			/*上一个选择的菜单项*/ 
int curr_sel = 0;			/*当前选择的菜单项*/ 
 
/************************************************************************/ 
/* 计算标题的起始位置                                                   */ 
/************************************************************************/ 
void calc_title_pos() 
{ 
	pos_title_sx = SCREEN_CENTER_H - strlen(title) / 2; 
	pos_newfilename_sx = pos_title_sx + 6; 
} 
 
/************************************************************************/ 
/* 计算各框架的关键点座标                                               */ 
/************************************************************************/ 
void calc_pos() 
{ 
	pos_mainframe_sy = SCREEN_CENTER_V - (6 + filenumber) / 2; 
	pos_mainframe_ey = pos_mainframe_sy + 5 + filenumber; 
	 
	calc_title_pos(); 
	pos_title_sy = pos_mainframe_sy + 1; 
	pos_list_sy = pos_mainframe_sy + 3; 
} 
 
/************************************************************************/ 
/* 备份模式时使列表为灰色不可选状态                                     */ 
/************************************************************************/ 
void update_list() 
{ 
	int i; 
	if (!filenumber) 
		return; 
	 
	textbackground(BLACK); 
	textcolor(mode != 1 && mode != 3 ? GREEN : DARKGRAY); 
	for (i = 0; i < filenumber; i++) { 
		gotoxy(pos_list_sx, pos_list_sy + i); 
		if (mode != 1 && mode != 3 && i == curr_sel) { 
			textbackground(RED); 
			cprintf(listitem[i].info); 
			textbackground(BLACK); 
		} else { 
			cprintf(listitem[i].info); 
		} 
	} 
} 
 
/************************************************************************/ 
/* 选择项改变时更新菜单项的显示,减少计算量时取代update_list()          */ 
/************************************************************************/ 
void sel_changed() 
{ 
	if (!filenumber || mode == 1 || mode == 3) 
		return; 
	 
	textbackground(BLACK); 
	textcolor(GREEN); 
	gotoxy(pos_list_sx, pos_list_sy + last_sel); 
	cprintf(listitem[last_sel].info); 
	 
	textbackground(RED); 
	textcolor(GREEN); 
	gotoxy(pos_list_sx, pos_list_sy + curr_sel); 
	cprintf(listitem[curr_sel].info); 
} 
 
/************************************************************************/ 
/* 绘制水平分割条                                                       */ 
/************************************************************************/ 
void vsplit(int startx, int endx, int y) 
{ 
	if (startx > endx) 
		return; 
	 
	gotoxy(startx, y); 
	putch(195); 
	while (++startx < endx) 
		putch(196); 
	putch(180); 
} 
 
/************************************************************************/ 
/* 由四点座标绘制框架                                                   */ 
/************************************************************************/ 
void frame(int startx, int starty, int endx, int endy) 
{ 
	int i, t; 
	 
	if (startx > endx || starty > endy) 
		return; 
	 
	gotoxy(startx, starty); 
	putch(218); 
	t = endx - startx; 
	i = t; 
	while (--i) 
		putch(196); 
	putch(191); 
	 
	gotoxy(startx, endy); 
	putch(192); 
	while (--t) 
		putch(196); 
	putch(217); 
	 
	for (i = starty + 1; i < endy; i++) { 
		gotoxy(startx, i); 
		putch(179); 
		gotoxy(endx, i); 
		putch(179); 
	} 
} 
 
/************************************************************************/ 
/* 模式或选择项改变时更新标题                                           */ 
/************************************************************************/ 
void update_title() 
{ 
	int t; 
	static char buff[16] = ""; 
	 
	textbackground(BLACK); 
	textcolor(GREEN); 
	_setcursortype(_NOCURSOR); 
	 
	gotoxy(pos_mainframe_sx + 3, pos_title_sy); 
	t = pos_mainframe_ex - pos_mainframe_sx - 4; 
	while (--t) 
		putch(' '); 
	 
	switch (mode) { 
	case 0: 
		sprintf(title, "C: <- %s", filenumber ? listitem[curr_sel].filename : ""); 
		break; 
	case 1: 
		sprintf(title, "C: ->         .GHO"); 
		break; 
	case 2: 
		sprintf(title, "Delete : %s", filenumber ? listitem[curr_sel].filename: ""); 
		break; 
	case 3: 
		strcpy(title, "Press ENTER to change Password"); 
	default: 
		break; 
	} 
	 
	calc_title_pos(); 
	gotoxy(pos_title_sx, pos_title_sy); 
	cprintf(title); 
	if (mode == 1) { 
		textbackground(BLUE); 
		textcolor(RED); 
		_setcursortype(cursor_pos < 8 ? _NORMALCURSOR : _NOCURSOR); 
		 
		sprintf(buff, "%-8s", newfilename); 
		gotoxy(pos_newfilename_sx, pos_title_sy); 
		cprintf(buff); 
		gotoxy(pos_newfilename_sx + cursor_pos, pos_title_sy); 
	} 
} 
 
/************************************************************************/ 
/* 搜索当前目录下的GHO备份文件, 将文件名和详细信息存到指定结构体数组 
注意: 
最多只搜索16个备份文件                                              */ 
/************************************************************************/ 
void search_gho() 
{ 
	struct ffblk __ffblk; 
	double size; 
	int unit; 
	 
	filenumber = 0; 
	if (findfirst("*.gho", &__ffblk, 0) != 0) 
		return; 
	 
	do { 
		strcpy(listitem[filenumber].filename, __ffblk.ff_name); 
		 
		size = __ffblk.ff_fsize; 
		unit = 0; 
		while (size > 1024) { 
			size /= 1024; 
			unit++; 
		} 
		 
		sprintf(listitem[filenumber].info, "%-16s   %8.3g%c, %4d-%02d-%02d, %02d:%02d:%02d",  
			__ffblk.ff_name,  
			size, unit == 0 ? 'B' : (unit == 1 ? 'K' : (unit == 2 ? 'M' : 'G')),  
			(__ffblk.ff_fdate >> 9) + 1980, (__ffblk.ff_fdate >> 5) & 0xf, __ffblk.ff_fdate & 0x1f,  
			__ffblk.ff_ftime >> 11, (__ffblk.ff_ftime >> 5) & 0x3f, (__ffblk.ff_ftime << 1) & 0x3f); 
		filenumber++; 
	} while (findnext(&__ffblk) == 0 && filenumber < 16); 
} 
 
void update_frame() 
{ 
	textbackground(BLACK); 
	textcolor(GREEN); 
	_setcursortype(_NOCURSOR); 
	clrscr(); 
	 
	frame(pos_mainframe_sx, pos_mainframe_sy, pos_mainframe_ex, pos_mainframe_ey); 
	vsplit(pos_mainframe_sx, pos_mainframe_ex, pos_mainframe_sy + 2); 
	 
	gotoxy(pos_mainframe_sx + 1, pos_mainframe_sy + 1); 
	cprintf("<-"); 
	gotoxy(pos_mainframe_ex - 2, pos_mainframe_sy + 1); 
	cprintf("->"); 
	 
	vsplit(pos_mainframe_sx, pos_mainframe_ex, pos_mainframe_ey - 2); 
	gotoxy(pos_mainframe_sx + 1, pos_mainframe_ey - 1); 
	cprintf(status); 
} 
 
 
void get_status() 
{ 
	sprintf(status,  
		"   ------------------  %u backups ------------------",  
		filenumber); 
} 
 
void redraw_backgound() 
{ 
	update_frame(); 
	update_title(); 
	update_list(); 
} 
 
/************************************************************************/ 
/* 更新全部显示                                                         */ 
/************************************************************************/ 
void update_all() 
{ 
	newfilename[0] = '\0'; 
	cursor_pos = 0; 
	filenumber = 0; 
	last_sel = 0; 
	curr_sel = 0; 
	 
	search_gho(); 
	calc_pos(); 
	get_status(); 
	redraw_backgound(); 
} 
 
/************************************************************************/ 
/* 获取新备份文件名                                                     */ 
/************************************************************************/ 
int get_newfilename() 
{ 
	int keycode; 
	 
	_setcursortype(_NORMALCURSOR); 
	update_title(); 
	while (1) { 
		if (!kbhit()) 
			continue; 
		 
		keycode = getch(); 
		switch (keycode) { 
		case 13: 
			return 0; 
		case 75: 
			return -1; 
		case 77: 
			return 1; 
		default: 
			if ((keycode >= 'A' && keycode <= 'z' ||  
				keycode >= '0' && keycode <= '9' ||  
				keycode == '_') && cursor_pos < 8) { 
				newfilename[cursor_pos++] = keycode; 
				newfilename[cursor_pos] = '\0'; 
			} else if (keycode == 8 && cursor_pos > 0) 
				newfilename[--cursor_pos] = '\0'; 
			update_title(); 
		} 
	} 
} 
 
/************************************************************************/ 
/* 从键盘读入密码,prompt:提示信息,dest:存放密码                       */ 
/************************************************************************/ 
void get_password(char *prompt, char *dest) 
{ 
	int prompt_length = 0,  
		password_length = 0,  
		i,  
		result,  
		startx,  
		endx; 
	char keycode; 
	 
	textbackground(BLACK); 
	textcolor(GREEN); 
	 
	prompt_length = strlen(prompt);	 
	startx = SCREEN_CENTER_H - (prompt_length + 24) / 2; 
	endx = startx + prompt_length + 24; 
	frame(startx, SCREEN_CENTER_V - 1, endx, SCREEN_CENTER_V + 1); 
	gotoxy(startx + 1, SCREEN_CENTER_V); 
	cprintf(prompt); 
	i = 24; 
	while (--i) 
		putch(' '); 
	gotoxy(startx + prompt_length + password_length, SCREEN_CENTER_V); 
	_setcursortype(_NORMALCURSOR); 
	while (1) { 
		if (!kbhit()) 
			continue; 
		 
		keycode = getch(); 
		switch (keycode) { 
		case 13: 
			goto END; 
		default: 
			if ((keycode >= 'A' && keycode <= 'z' ||  
				keycode >= '0' && keycode <= '9' ||  
				keycode == '_') && password_length < 8) { 
				dest[password_length++] = keycode; 
				dest[password_length] = '\0'; 
			} else if (keycode == 8 && password_length > 0) 
				dest[--password_length] = '\0'; 
			gotoxy(startx + prompt_length, SCREEN_CENTER_V); 
			i = 0; 
			while (i++ < password_length) 
				putch('*'); 
			_setcursortype(_NOCURSOR); 
			while (i++ <= 24) 
				putch(' '); 
			gotoxy(startx + prompt_length + password_length, SCREEN_CENTER_V); 
			_setcursortype(_NORMALCURSOR); 
		} 
	} 
END: 
	redraw_backgound(); 
	_setcursortype(_NOCURSOR); 
} 
 
/************************************************************************/ 
/* 密码验证                                                             */ 
/************************************************************************/ 
int password_check() 
{ 
	char password[16] = ""; 
	get_password("Password: ", password); 
	if (strlen(password) == 0) 
		return -1; 
	if (strcmp(password, password_saved) == 0) 
		return TRUE; 
	else 
		return FALSE; 
} 
 
void reboot() 
{ 
	_asm int 19h; 
} 
 
/************************************************************************/ 
/* 显示警告信息                                                         */ 
/************************************************************************/ 
void alert(char *msg) 
{ 
	int length, startx, endx; 
	 
	 
	textbackground(BLACK); 
	textcolor(GREEN); 
	length = strlen(msg); 
	startx = SCREEN_CENTER_H - length / 2 - 1; 
	endx = startx + length + 1; 
	 
	frame(startx, SCREEN_CENTER_V - 1, endx, SCREEN_CENTER_V + 1); 
	gotoxy(startx + 1, SCREEN_CENTER_V); 
	cprintf(msg); 
	 
	sleep(2); 
	redraw_backgound(); 
	_setcursortype(_NOCURSOR); 
} 
 
void password_change() 
{ 
	char new_password[16]; 
	char confirm_password[16]; 
	char keyword[8]; 
	FILE *fp; 
	long offset; 
	 
	get_password("New password: ", new_password); 
	get_password("Confirm: ", confirm_password); 
	if (strcmp(new_password, confirm_password) == 0) { 
		memset(password_saved, 0, 8); 
		strcpy(password_saved, new_password); 
		fp = fopen(instance_name, "rb+"); 
		fseek(fp, 0, SEEK_END); 
		offset = ftell(fp) - 16; 
		while (offset--) { 
			fseek(fp, offset, SEEK_SET); 
			fread(keyword, 4, 1, fp); 
			if (keyword[0] == '#' &&  
				keyword[1] == '%' &&  
				keyword[2] == '%' &&  
				keyword[3] == '$') { 
				fseek(fp, offset - 12, SEEK_SET); 
				fread(keyword, 4, 1, fp); 
				if (keyword[0] == '$' &&  
					keyword[1] == '%' &&  
					keyword[2] == '%' &&  
					keyword[3] == '#') { 
					fseek(fp, offset - 8, SEEK_SET); 
					fwrite(password_saved, 8, 1, fp); 
					break; 
				} 
			} 
		} 
		fclose(fp); 
		alert(" Password updated successfully! "); 
	} else { 
		alert(" Password mismatch! "); 
	} 
} 
 
/************************************************************************/ 
/* 主程序, 响应铵键及程序调用                                          */ 
/************************************************************************/ 
int main(int argc, char *argv[]) 
{ 
	int i, resoult; 
	uchar move_down; 
	uchar move_right; 
	 
	if (argc) 
		instance_name = argv[0]; 
	 
	for (i = 0; i < 8; i++) 
		password_saved[i] = password_string[i+4]; 
	password_saved[i] = '\0'; 
	 
	textmode(C80); 
	update_all(); 
	 
	while (1) { 
		move_down = 1; 
		move_right = 1; 
		 
		switch (bioskey(0)) { 
		case 0x4b00: /*左键按下*/ 
MOVELEFT: 
			if (mode-- == 0) 
				mode = 3; 
			move_right = 0; 
		case 0x4d00: /*右键按下*/ 
MOVERIGHT: 
			if (move_right && mode++ == 3) 
				mode = 0; 
			update_title(); 
			update_list(); 
			if (mode == 1) { 
GET_NEW_FILE_NAME: 
			switch (get_newfilename()) { 
			case 0: 
				goto ENTER; 
			case 1: 
				move_right = 1; 
				goto MOVERIGHT; 
			case -1: 
				goto MOVELEFT; 
			default: 
				break; 
			} 
			} 
			break; 
			 
		case 0x4800: /*上箭头*/ 
			move_down = 0; 
		case 0x5000: /*下箭头*/ 
			if (mode != 1 && mode != 3) { 
				last_sel = curr_sel; 
				if (move_down) { 
					if (++curr_sel == filenumber) 
						curr_sel = 0; 
				} else { 
					if (curr_sel-- == 0) 
						curr_sel = filenumber - 1; 
				} 
				sel_changed(); 
				update_title(); 
			} 
			break; 
			 
		case 0x1c0d: /*回车*/ 
ENTER: 
			resoult = password_check(); 
			if (resoult == TRUE) { 
				switch (mode) { 
				case 0: 
					if (filenumber) { 
						gotoxy(1, 1); 
						sprintf(command,  
							"ghost -clone,mode=pload,src=%s:1,dst=1:1 -fro -sure -rb",  
							listitem[curr_sel].filename); 
						system(command); 
						reboot(); 
					} 
					break; 
					 
				case 1: 
					gotoxy(1, 1); 
					sprintf(command,  
						"ghost -clone,mode=pdump,src=1:1,dst=%s.gho -fro -sure -z9",  
						newfilename); 
					system(command); 
					break; 
					 
				case 2: 
					if (filenumber) { 
						if (strcmp(listitem[curr_sel].filename, "ORIGIN.GHO") != 0) { 
							sprintf(command, "del %s", listitem[curr_sel].filename); 
							system(command); 
						} else { 
							alert(" This file can't be deleted! "); 
						} 
					} 
					break; 
					 
				case 3: 
					password_change(); 
					break; 
				default: 
					break; 
				} 
			} else if (resoult == 0) { 
				alert(" Invalid password! "); 
			} 
			if (resoult != TRUE) 
				redraw_backgound(); 
			else 
				update_all(); 
			 
			if (mode == 1) 
				goto GET_NEW_FILE_NAME; 
			break; 
 
		case 0x11b: /*ESC键*/ 
			if (password_check() == TRUE) 
				goto END; 
			alert(" Invalid password! "); 
			break; 
		default: 
			break; 
		} 
	} 
END: 
	textmode(MONO); 
	clrscr(); 
	return 0; 
}