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; }