⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tools321.c

📁 这是一个强大的磁盘维护工具 读写任意扇区 能对MBR等重要数据进行备份
💻 C
📖 第 1 页 / 共 2 页
字号:
//--------------------- Added by 吕维安 -------------->Begin
//This program was updated by 吕维安 in May 2004 -boot_res2
/*
说明
1)原代码中扩展13H中断的部分作了大幅度修改.
2)分区表及各分区引导扇区的扩展读写均由新的函数实现.MBR读写由原来代码负责.
3)所有修改或增加的代码全部清楚标明.
*/


#include <math.h>
#include <bios.h>
#include <dir.h>
#include <stdlib.h>
#include <process.h>
#include <io.h>
#include <fcntl.h>
#include <dos.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include "mouse_c.h"
#include "text.h"
#include "mouse_c.c"
//--------------------- Added by 吕维安 -------------->End

//The following 14 lines were commented by 吕维安
/*#include "math.h"
#include "bios.h"
#include "dir.h"
#include "stdlib.h"
#include "process.h"
#include "io.h"
#include "fcntl.h"
#include "dos.h"
#include "stdio.h"
#include "string.h"
#include "conio.h"
#include "mouse_c.h"
#include "text.h"
#include "mouse_c.c"*/

//--------------------- Added by 吕维安 -------------->Begin
int hotkey_func(int key);   //热键判断
int make_sure(int len,char *mess);               /*  提示,要求确定  */
int help(void);
int write_boot(int disk_no);     /*  写入MBR或分区表  */
int read_freely(void);           /*  读写硬盘任意扇区 */
int g_gets(char *mess,char str_buff[],int lens); /*  字符串输入  */
int load_disk_data(void);            /*  加载硬盘数据 菜单:load ...(mbr) */
int save_disk_data(void);            /*  备份硬盘数据  */
int read_CMOS(void);         /*  读取CMOS数据  */
int write_CMOS(void);        /*  重写CMOS数据  */
int check_a();  //检查软盘的前四个扇区
int load_boot(void);
int save_boot(void);         /*  备份硬盘数据  */
int read_boot(int disk_no);      /*  读取分区的引导扇区  */
int get_BPB(struct BPB_type *b,unsigned char *bpb_buff);
int load_cmos_data(void);            /*  加载CMOS数据  */
int save_cmos_data(void);            /*  备份CMOS数据  */
int read_boot_bpb(int disk_no);
void GetFDiskType(unsigned char chData,char *szFD);
int init_arr(void);
int read_boot_bpb(int disk_no);
int fdisk(void);


/*			数组partition_map[16][4][12]说明:
 partition_map[]: 驱动器
 partition_map[1]: C盘
 partition_map[2]: D盘
 partition_map[3]: E盘
 partition_map[][]: 分区表项(最多四个,一般电脑是两个)
 partition_map[][0]: Partition table entry 1
 partition_map[][1]: Partition table entry 2
 partition_map[][2]: Partition table entry 3
 partition_map[][3]: Partition table entry 4
 partition_map[][][0]: 绝对扇区开始数
 partition_map[][][1]: 绝对扇区结束数
 partition_map[][][2]: 相对扇区开始数(比较复杂, 不作介绍)
 partition_map[][][3]: 扇区个数(==绝对扇区结束数-绝对扇区开始数+1)
 partition_map[][][4]: PARTITION ID
 partition_map[][][5]: Inactive or Active
 partition_map[][][6]: Begin Cyl
 partition_map[][][7]: Begin Hd
 partition_map[][][8]: Begin Sect
 partition_map[][][9]: End Cyl
 partition_map[][][10]: End Hd
 partition_map[][][11]: End Sect

 		典型实例举例:
20G硬盘, 6个分区, C盘为FAT16, 其他为FAT32; C:1.99GB, D,E:4.87GB
F,G:2.92GB, H:1.43GB

          ABSOLUTE          PART-TABLE
       START     END      START    BLOCKS
      ======== ========  ======== ========
         0        1         2        3       4
1-0 : 0000003F 003FFAC4  0000003F 003FFA86  FAT16
1-1 : 003FFAC5 02629FFA  003FFAC5 0222A536  Win95 Ext'd (LBA)
2-0 : 003FFB04 00DC5FC2  0000003F 009C64BF  Win95 FAT32
2-1 : 00DC5FC3 0178C4C0  009C64FE 009C64FE  Extended
3-0 : 00DC6002 0178C4C0  0000003F 009C64BF  Win95 FAT32
3-1 : 0178C4C1 01D6A77F  0138C9FC 005DE2BF  Extended
4-0 : 0178C500 01D6A77F  0000003F 005DE280  Win95 FAT32
4-1 : 01D6A780 02348A3E  0196ACBB 005DE2BF  Extended
5-0 : 01D6A7BF 02348A3E  0000003F 005DE280  Win95 FAT32
5-1 : 02348A3F 02629FFA  01F48F7A 002E15BC  Extended
6-0 : 02348A7E 02629FFA  0000003F 002E157D  Win95 FAT32


 partition_map[1][0][0]==0000003F	C盘引导扇区在该扇区,C盘从此处开始
 partition_map[1][0][1]==003FFAC4	C盘在该扇区结束
 partition_map[1][0][3]==003FFA86	C盘扇区个数
 partition_map[1][0][4]==06		FAT16
 partition_map[1][1][0]==003FFAC5	D盘分区表在该扇区,D盘以及扩展分区从此处开始
 partition_map[1][1][1]==02629FFA	扩展分区在该扇区结束
 partition_map[1][1][3]==0222A536	扩展分区扇区个数
 partition_map[1][1][4]==0F		Win95 Ext'd (LBA)
 partition_map[2][0][0]==003FFB04	D盘引导扇区在该扇区
 partition_map[2][0][1]==00DC5FC2	D盘在该扇区结束
 partition_map[2][0][3]==009C64BF	D盘扇区个数(不含从分区表开始的63个扇区)
 partition_map[2][0][4]==0B		Win95 FAT32
 partition_map[2][1][0]==00DC5FC3	E盘分区表在该扇区,E盘从此处开始
 partition_map[2][1][1]==0178C4C0	E盘在该扇区结束
 partition_map[2][1][3]==009C64FE	E盘扇区个数(含从分区表开始的63个扇区)
 partition_map[2][1][4]==05		Extended


*/
unsigned long partition_map[16][4][12];

//Physical Geometry	Get drive parameters	AH - 48h
unsigned int Cyls,Hds,Sects;
//unsigned long number_of_physical_sectors;

//读写硬盘绝对扇区时用
unsigned long absolute_sector;

//计算各主菜单的子菜单数目时用
unsigned int number_of_partitions;

int read_absolute_sector(void);
int write_absolute_sector(void);
int PartitionMap(void);

int access_one_sector(int operation, int Cyl, int Hd, int Sect);

//按 Ctrl + R 时用
unsigned long cur_abs_sect=0;//current absolute sector

//按 F1 时用
void show_dpt_LBA(void);

int INT_13H_Extensions_INSTALLATION_CHECK(void);

//operation: READ, WRITE; drive_no: C:->1, D:->2, ...;
//option: 0->boot sector, 1->partition table
int AccessHardDisk(int operation, int drive_no, int option);

int ReadHardDisk(int operation, int drive_no, int option);

//int read_partition_boot(int);
int write_partition_boot(int);
//int13hEx() operation: read, write; drive_no: C:, D:, ...
void int13hEx(int operation, int drive_no, int option, char *sector_buffer);
void ScanMBR_DPT_BOOT(void);

void GetHardDiskInfo(void);
char *getascii (unsigned int in_data [], int off_start, int off_end);
int WindowsIsRuning(void);


//#define CYL(r1, r2) (((r1 >> 6) << 8)+r2)
//#define SEC(r) (r % 0x40)
#define EXT(r) (5 == r || 0xf == r || 0x85 == r)  // Partition ID == Extended ?

struct patlist {
  int lba;  // 0 = non-LBA, 1 = LBA
  int depth;
  int startsec;  // start sector
  int cyll;      // cylinder low
  int cylhsec;   // cylinder high + sector
  int head;
  int partid;    // partition id
  int drv;
  unsigned long abssect; // abs base sector
  unsigned long extsect; // ext sector
  int pte;       // partition table entry
};

struct diskparm {
   int drv; // drive id, 0x80 - 0x8n
   unsigned int lba; // 0=non-LBA, 1=LBA
   unsigned int cc;  // # of Cyl
   unsigned int hh;  // # of Heads
   unsigned int ss;  // # of Sec/trac
   unsigned long blks;  // # of sectors
};

void mbrdisp(struct patlist *plist, unsigned char ptable[16][4][16]);
void partdisp(unsigned char *ptable);
char* ppartid(int partid);
void getparm(struct diskparm *drv);
void int1348(struct diskparm *drv);
unsigned long getnum(unsigned char *buff, int ofs, int len);
char* int13err(int rc);
void resetdisk(int drv);
void setdap(int sects,char *dap,unsigned char *buff, unsigned long bptr);
void partmap3(unsigned char ptable[16][4][16], int dep);

//--------------------- Added by 吕维安 -------------->End


unsigned char system_type[9];
void main(void)
{
  int   i,j,key=F1,error,mousex,mousey;

//--------------------- Added by 吕维安 -------------->Begin
  char *envptr;
 	//Added detection of Windows NT at the front of coding.
	// get the current environment
	envptr = getenv("OS");
	if(stricmp(envptr, "Windows_NT")!=0)
	{//not Windows NT
		if(WindowsIsRuning()==0)
			GetHardDiskInfo();
	}
//--------------------- Added by 吕维安 ---------------->End


/*---------------------------------------------------*///读软盘的指定位置
/*unsigned char gongbing[9];char mima[]={"GONGBING"};
  bootdisk_a(READ,01,00,02,boot_buff);
  for(i=0x80;i<0x88;i++)
      gongbing[i-0x80]=boot_buff[i];
  gongbing[8]='\0';
  if(strcmp(gongbing,mima)!=0)
     {window(18,9,50,14);textattr(14+(4<<4));clrscr();
      box(1,1,6,32);
      gotoxy (2,2);cprintf("YOU CAN NOT USE THIS TOOLS");
      gotoxy(2,4); cprintf("please press any key......."); getch(); goto ENDS;}
 */
/*------------------------------------------------------*/
//	int azz=5;
//	sub_menu_nums[1]=azz;
   setblank(0);
   setcursor(1,0);
   search_drivers();
   menu_status=system_object(0);
   init_menu();
   display(pos);
   srand(biostime(0,0));
   bootdisk(READ,1,drivers[0][1],drivers[0][0],boot_buff);
   for(i=0;i<0x5a;i++)
     	bpbbuf[i]=boot_buff[i];	//记录现在的 bpb
   init_mouse(MOUSE_OPTIONAL,MOUSE_TEXT_MODE,MOUSE_TEXT_MODE);//初始化鼠标

  //--------------------- Added by 吕维安 -------------->Begin
 	//Added detection of Windows NT.
	// get the current environment
	envptr = getenv("OS");
	if(stricmp(envptr, "Windows_NT")==0)
	{
		make_sure(0,"Can't run properly under an unsupported OS");
		//printf("Sorry, this program cannot run under Windows NT, 2000, XP, 2003\n");

	}
  //--------------------- Added by 吕维安 ---------------->End
   show_version();
   do{
      while(!(key=mouse_trigger(1)));

/*    if(!key) key=getkey();*/
    if(key>='a' && key<='z') key-=32;
    if(!hotkey_func(key))
      for(i=0;i<Max_menus;i++)               /*  菜单热键判断  */
	    if(key==main_menu[i].hotkey)
	    if(i!=last_menu || !sub_menu_on){
		if(sub_menu_on)
		clear_sub_menu(last_menu);
		sub_menu_on=0;
		last_menu=i;
		key=F10;
		break;
	    }
    /*  普通菜单键判断  */
    if(sub_menu_on || key==ESC || key==F10 || key==' '||key==LEFT_MOUSE_PRESS){
      switch(key){
	case ENTER:             /*  回车  */
enter:        mouse_off(1);
	       if(sub_menu_on)
		if(sub_num<main_menu[last_menu].sub_menu_nums){
		     main_menu[last_menu].last_choice=sub_num;	//记住最后选择的子菜单
		     if(last_menu==3&&sub_num==2) {kv300();break;}
		     if(last_menu==5&&sub_num==2) {restore_fat16();break;}
		     if(last_menu==5&&sub_num==3) {restore_fat32();break;}
		     sub_menu_on=0;
		     clear_sub_menu(last_menu);	//用于刷新菜单3,5
		     key=menu_function(last_menu,sub_num);
		     if(key){
		      	if(key!=Ctrl_Q)  ring();
		      	else sys_end=1;
		     }
		}
	    mouse_on(1);
	    break;
	case LEFT:              /*  左右键  */
	case RIGHT:
	    if(!sub_menu_on) break;
	    clear_sub_menu(last_menu);
	    if(key==LEFT)
	      	if(--last_menu<0)  last_menu=Max_menus-1;
	    if(key==RIGHT)
	      	if(++last_menu>=Max_menus) last_menu=0;
	    draw_sub_menu(last_menu,1);
	    sub_num=last_sub_num=main_menu[last_menu].last_choice;
	    break;
	case UP:                /*  上下键  */
	case DOWN:
	    if(main_menu[last_menu].sub_menu_nums==0)   break;
	    if(!sub_menu_on)   break;
	    clear_roll_bar(last_menu,last_sub_num);
	    if(key==UP){
	      	if(--sub_num<0)
		sub_num=main_menu[last_menu].sub_menu_nums-1;
	      	/*if((last_menu==2)){	//||(last_menu==5)){
	       	//if((sub_num==2) ||(sub_num==4))
	       	if(sub_num==4)
		 	if(menu_status==32)
		  		sub_num--;
			if((sub_num==3) ||(sub_num==5))
		 	if(menu_status==16)
		  		sub_num--;
			if(sub_num==3)
		 	if(menu_status==0)
		  		sub_num=sub_num-2;
	       }*/
	       if((last_menu==5)){		//上面是原来的程序段,在这里有三个子菜单项被我删除了
	     		if(sub_num==2)
	     		if(menu_status==32)
	     			sub_num--;
	     		if(sub_num==3)
	     			sub_num--;
	     		if(sub_num==2)
	       	if(menu_status==0)
				sub_num=sub_num-1;
		}
	    }
	    if(key==DOWN){	//注意,这个大括号是刚加上去的
	      	if(++sub_num>=main_menu[last_menu].sub_menu_nums)
		sub_num=0;
	    	/*if((last_menu==2)){	//||(last_menu==5)){
	    		if((sub_num==2)||(sub_num==4))
	       	if(menu_status==32)
				sub_num++;
	      		if((sub_num==3)||(sub_num==5))
	       	if(menu_status==16)
				sub_num++;
	      		if(sub_num==2)
	       	if(menu_status==0)
				sub_num=sub_num+2;
	     	}*/
	     	if((last_menu==5)){
	     		if(sub_num==2)
	     		if(menu_status==32)
	     			sub_num++;
	     		if(sub_num==3)
	     			sub_num++;
	     		if(sub_num==2)
	       	if(menu_status==0)
				sub_num=sub_num+1;
	     	}
	    }
	    last_sub_num=sub_num;
	    draw_roll_bar(last_menu,sub_num);
	    break;
	case LEFT_MOUSE_PRESS:     //当点击鼠标左键时
	if(!sub_menu_on){
		if(mouse_in_box(0,3,4,9,4)) {mouse_off(1);last_menu=0;//判断是否菜单一
			draw_sub_menu(last_menu,1);
		    	sub_num=last_sub_num=main_menu[last_menu].last_choice;
		    	sub_menu_on=1;
		}
		else if(mouse_in_box(0,13,4,16,4)){mouse_off(1);last_menu=1;//判断是否菜单二
			draw_sub_menu(last_menu,1);
			sub_num=last_sub_num=main_menu[last_menu].last_choice;
			sub_menu_on=1;
		}
		else if(mouse_in_box(0,20,4,24,4)){mouse_off(1);last_menu=2;//判断是否菜单三
			draw_sub_menu(last_menu,1);
			sub_num=last_sub_num=main_menu[last_menu].last_choice;
			sub_menu_on=1;
		}
		else if(mouse_in_box(0,28,4,34,4)){mouse_off(1);last_menu=3;//判断是否菜单四
			draw_sub_menu(last_menu,1);
			sub_num=last_sub_num=main_menu[last_menu].last_choice;
			sub_menu_on=1;
		}
		else if(mouse_in_box(0,38,4,41,4)){mouse_off(1);last_menu=4;//判断是否菜单五
			draw_sub_menu(last_menu,1);
			sub_num=last_sub_num=main_menu[last_menu].last_choice;
			sub_menu_on=1;
		}
		else if(mouse_in_box(0,45,4,48,4)){mouse_off(1);last_menu=5;//判断是否菜单六
			draw_sub_menu(last_menu,1);
			sub_num=last_sub_num=main_menu[last_menu].last_choice;
			sub_menu_on=1;
		}
		else if(mouse_in_box(0,52,4,56,4)){mouse_off(1);last_menu=6;//判断是否菜单七
			draw_sub_menu(last_menu,1);
			sub_num=last_sub_num=main_menu[last_menu].last_choice;
			sub_menu_on=1;
		}
		else if(mouse_in_box(0,69,4,72,4)){mouse_off(1);last_menu=7;//判断是否菜单八
			draw_sub_menu(last_menu,1);
			sub_num=last_sub_num=main_menu[last_menu].last_choice;
			sub_menu_on=1;
		}
		mouse_on(1);break;
	}
	else switch(last_menu){ 	//判断子菜单行数而执行相应的程序,不只限于鼠标操作
		case 0:		//这里mouse_in_box左、上用了绝对坐标,不太好
			if(mouse_in_box(0,3,6,3+sub_width[0],5+sub_menu_nums[0]))
			    {
			    	mouse_txt_posn(&mousex,&mousey);	//得到鼠标的文本坐标
			      	sub_num=mousey-7;			//记录用鼠标选择子菜单第几项
			      	mouse_off(1);
			      	clear_roll_bar(last_menu,last_sub_num);	//当子菜单失去焦点时变回原来的颜色(白底黑字)
			      	last_sub_num=sub_num;
			      	draw_roll_bar(last_menu,sub_num);	//改变得到焦点的子菜单的颜色
			     	mouse_on(1);
			      	key=ENTER;goto enter;
			     }
			 else {
			   	mouse_off(1);
			   	clear_sub_menu(last_menu);
			   	sub_menu_on=0;mouse_on(1);
			 }
		break;

		case 1:
			if(mouse_in_box(0,13,6,13+sub_width[1],5+sub_menu_nums[1]))
			     {
			     	mouse_txt_posn(&mousex,&mousey);
			       sub_num=mousey-7;
			       mouse_off(1);
			       clear_roll_bar(last_menu,last_sub_num);
			       last_sub_num=sub_num;
			       draw_roll_bar(last_menu,sub_num);
			       mouse_on(1);
			       goto enter;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -