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

📄 gformat.c

📁 关于操作系统中存储管理的一个程序
💻 C
字号:
#include<dos.h>
#include<stdio.h>
#include"gformat.h"
#include"genfunc.h"
long cylinder_count;
int       head_count,sector_count;
long      disk_size,part_size,filespc_size;
unsigned  bytes_per_sector;
int       sectors_per_cluster;
unsigned  maximum_number_of_root_entries;
unsigned  total_number_of_sectors;
char      media_descriptor;
unsigned  sectors_per_FAT;
unsigned  sectors_per_track;
unsigned  number_of_heads;
long      number_of_hidden_sectors;
long      volume_id=655627769;
char      volume_lable[11];


void main(int argc,char* agrv[])/*for example:gformat 2(drive_no) p(bpl) l(vpno)*/
{
	union          REGS inregs,outregs;
	struct         SREGS segs;
	BootSector     priboot;
	DOSBootSector  fpriboot;
	DOSBootSector  dosboot;
	FAT16          fat16;
	DirEntry*      direntry;
	int bpl;                /*主分区p,P, 逻辑分区l,L,此程序只能格式化主分区,逻辑分区原理与此相同*/

	int drive_no;            /*驱动器号1,2,a*/

	int vpno,rpno,ttno;      /*Virtual part_no,Real part_no*/

	int    fs;
	int    speed_idt;
	char*  sspeed_idt;
	char*  iddata;
	int    bfs;
	int    i,j,k,m;
	int    bcylinder,bhead,bsector;
	int    ttcylinder,tthead,ttsector;
	int    ttcylinder1,tthead1,ttsector1,ttcylinder2,tthead2,ttsector2;
	char   tt[2];
	FILE*  fp;
	long   ttlogsector;
	void(argc);
	
	bpl=argv[2][0];          /*是主分区p,P,还是逻辑分区l,L*/
	drive_no=atoi(argv[1]);  /*驱动器号*/
	vpno=atoi(argv[3]);      /*虚拟分区号*/
	 
	if(bpl==80||bpl=120)                      /*bpl="p" or bpl="P" 将要格式化主分区*/
	{
		inregs.h.ah=0x8;
		inregs.h.dl=0x80+drive_no-1;         /*驱动器号为1时为第一块硬盘,dl寄存器为0x80*/

		int86(0x13,&inregs,&outregs);
		head_count=outregs.h.dh+1;            /*磁头数*/

		cylinder_count=outregs.h.ch+1+(outregs.h.cl>>6)*256; /*柱面数(磁道数)*/

		sector_count=outregs.h.cl&63;                         /*每道扇区数*/
		disk_size=cylinder_count*sector_count*head_count;/*磁盘空间大小=柱面数*每道扇区数*磁头数*/
        
        inregs.h.ah=0x2;    /*读磁盘扇区*/
		inregs.h.al=1;      /*读取的扇区数为1*/
		inregs.h.ch=0;      /*位置:0道*/
		inregs.h.cl=1;      /*位置:1扇区*/
		inregs.h.dh=0;      /*位置:0磁头*/

		inregs.h.dl=0x80+drive_no-1;         /*位置:驱动器号(0x80开始为第一块硬盘)*/
		inregs.x.bx=(unsigned)&priboot;      /*读出的数据存放地址*/
		segread(&segs);
		int86(0x13,&inregs,&outregs,&segs);  /*将主引导扇区(0道0头1扇区)内容读到priboot数据结构中*/

		/*此时,vpno=1的意义是第一个未格式化的分区*/
		/*下叙过程没有查找逻辑分区的主引导扇区,尚不能提供对逻辑分区格式化*/

		rpno=-1;
		ttno=0;
		for(i=0;i<4;i++)
		{
			if(priboot.part[i].file_system!=0x0)
			{
				ttno++;
				if(ttno==vpno)
				{
					rpno=i;
					break;
				}
			}
		}
		if(rpno==-1)
		{
			Textout(23,2,"Error part number");
			return;
		}

		part_size=priboot.part[rpn0].sector_count;/*分区大小*/
		/*初始化引导扇区的内容*/
		bytes_per_sector=512;                     /*每个扇区字节数*/
		sector_per_cluster=8;                     /*每簇扇区数*/
		number_of_reserved=sectors=1;             /*保留扇区数*/
		number_of_FATs=2;                         /*文件分配表数,第二个FAT为备份*/
		maxinum_number_of_root_entries=512;       /*根目录中目录项数*/
		total_number_of_sectors=part_size;        /*总扇区数*/
		media_descriptor=0xf8;                    /*磁盘介质标志*/
		sectors_per_track=sector_count;           /*每道扇区数*/
		number_of_heads=head_count;               /*磁头数*/
		number_of_hidden_sectors=priboot.part[rpno].first_sector<=sector_count?sector_count:0;/*隐藏扇区数*/
		sectors_per_FAT=2+((part_size-
			number_of_reserved_sectors-maximum_number_of_root_entries*32/bytes_per_sector)/
			sectors_per_cluster*2)/bytes_per_sector;/*每个FAT扇区数*/
		filespc_size=part_size-number_of_reserved_sectors-maximum_number_of_root_entries*32/
			bytes_per_sector-sectors_per_FAT*number_of_FATS;/*数据空间大小*/
		/*--------------check all cylinders------------------*/
		sspeed_idt=(char*)malloc(5);                         /*界面显示格式化进度*/
		bcylinder=priboot.part[rpno].beginning_cylinder;     /*格式化开始柱面*/
		bhead=priboot.part[rpno].beginning_head;             /*开始磁头*/
		bsector=1;                                           /*开始扇区*/
		ttcylinder=bcylinder;
		tthead=bhead;
		ttsector=bsector;
		/*检查DOS引导扇区,FAT和根目录区的磁盘空间,如果有损坏则退出程序*/
		for(i=0;i<number_of_reserved_sectors+sectors_per_FAT*number_of_FATs+
			maximum_number_of_root_entries*32/bytes_per_sector;i++)
		{
			inregs.h.ah=0x4;
			inregs.h.al=1;
			inregs.h.ch=ttcylinder;
			inregs.h.cl=ttsector;
			inregs.h.dh=tthead;
			inregs.h.dl=0x80+drive_no-1;
			int86x(0x13,&inregs,&outregs,&segs);
			if(outregs.h.ah!=0x0)
			{
				if(i<number_of_reserved_sectors)
					Textout(23,2,"Boot Sector destroyed! Can't format!");
				else if(i<sectors_per_FAT*number_of_FATs)
					Textout(23,2,"FAT Sectors destroyed! Can't format!");
				else 
					Textout(23,2,"Root Entry Sectors destroyed! Can't format!");
				return;
			}
			/***下一个循环过程检查下一个扇区*/
			ttsector++;
			if(ttsector>sector_count)
			{
				ttsector=1;
				tthead++;
				if(tthead>head_count-1)
				{
					tthead=0;
					ttcylinder++;
				}
			}
		}
		/*************************check file section sector**********************/
		/*检查数据区的磁盘空间,识别破坏簇*/
		/*FAT表1*/
		ttcylinder=bcylinder;
		tthead1=bhead;
		ttsector1=bsector+1;
		/*FAT表2,假定有两个FAT表*/
		ttcylinder2=bcylinder+(bsector+1+sectors_per_FAT-1)/sector_count/head_count;
		tthead2=(bhead+(bsector+1+sectors_per_FAT-1)/sector_count)%head_count;
		ttsector2=(bsector+1+sectors_per_FAT-1)%sector_count+1;
		/*初始化一个扇区的FAT表项缓冲区,每个表项为2个字节*/
		for(i=0;i<bytes_per_sector/2;i++)
			fat16.item[i]=0xfff0;
		for(i=0;i<filespc_size/sectors_per_cluster;i++) /*按簇进行格式化,每次格式化一个簇*/
		{
			inregs.h.ah=0x4;
			inregs.h.al=sectors_per_cluster;/*每簇扇区数*/
			inregs.h.ch=ttcylinder;
			inregs.h.cl=ttsector;
			inregs.h.dh=tthead;
			inregs.h.dl=0x80+drive_no-1;
			int86x(0x13,&inregs,&outregs,*segs);
			if(i==0)                     /*前两个FAT表项被占用*/
			{
				fat16.item[0]=0xff+edia_descriptor<<8;
				fat16.item[1]=0xffff;
			}
			/*标志坏簇*/
			if(outregs.h.ah!=0x0)
			{
				fat16.item[(i+2)%(bytes_per_sector/2)]=0xfff7;
			}
			else
			{
				fat16.item[(i+2)%(bytes_per_sector/2)]=0x0;
			}

			/*当FAT表项缓冲区满,写入磁盘*/
			if((i>0&&(i+1)*2%bytes_per_sector==0)||(i>=filespc_size/sectors_per_cluster-1))
			{
				/*写入第一个FAT表*/
				inregs.h.ah=0x3;
				inregs.h.al=1;
				inregs.h.ch=ttcylinder;
				inregs.h.cl=ttsector1;
				inregs.h.dh=tthead1;
				inregs.h.dl=0x80+drive_no-1;
				inregs.x.bx=(unsigned)&fat16;
				segread(&segs);
				int86x(0x13,&inregs,&outregs,&segs);
				/*写入第二个FAT表,备分,通常为2个FAT表*/
				inregs.h.ah=0x3;
				inregs.h.al=1;
				inregs.h.ch=ttcylinder2;
				inregs.h.cl=ttsector2;
				inregs.h.dh=tthead2;
				inregs.h.dl=0x80+drive_no-1;
				inregs.x.bx=(unsigned)&fat16;
				segread(&segs);
				int86x(0x13,&inregs,&outregs,&segs);
				/*修改将写入的FAT表1和表2的位置*/
				ttsector1++;
				if(ttsector1>sector_count)
				{
					ttsector1=1;
					tthead1++;
					if(tthead1>head_count-1)
					{
						tthead1=0;
						ttcylinder++;
					}
				}
				ttsector2++;
				if(ttsector2>sector_count)
				{
					ttsector2=1;
					tthead2++;
					if(tthead2>head_count-1)
					{
						tthead2=0;
						ttcylinder2++;
					}
				}
				/*	清空FAT表缓冲区*/
				for(k=0;k<256;k++)
					fat16.item[k]=0xfff0;
			}
			/*修改将要检查的文件区扇区位置*/
				ttsector+=sectors_per_cluster;
				if(ttsector>sector_count)
				{
					ttsector=1;
					tthead++;
					if(tthead>head_count-1)
					{
						tthead=0;
						ttcylinder++;
					}
				}
			/*显示界面上的格式化进度*/
				speed_idt=(i+1)/(filespc_size)/sectors_per_cluster/100);
				speed_itd=speed_idt<=100?speed_idt:100;
				itoa(speed_idt,sspeed_idt,10);
				strcat(sspeed_idt,"%");
				inregs.h.ah=0x2;
				inregs.h.bh=0;
				inregs.h.dh=23;
				inregs.h.dl=0;
				int86(0x10,&inregs,&outregs);
				while(*sspeed_idt)
				{
					inregs.h.ah=0xE;
					inregs.h.bh=0;
					inregs.h.bl=6;
					inregs.h.al=*sspeed_idt++;
					int86(0x10,&inregs,&outregs);
				}
			}
			/*将DOS引导扇区的信息写入到磁盘*/
			dosboot.jmp_instruction[0]=-21;               /*跳转指令*/
			dosboot.jmp_instruction[1]=60;
			dosboot.jmp_instruction[2]=-112;
			strcpy(dosboot.oem_name,"XMG 1.0");            /*软件厂商及版本号*/
			dosboot.bpb.bytes_per_sector=bytes_per_sector; /*每扇区字节数*/
			dosboot.bpb.sectors_per_cluster=sectors_per_cluster;/*每簇扇区数*/
			dosboot.bpb.number_of_reserved_sectors=number_of_reserved_sectors;/*保留扇区数*/
			dosboot.bpb.number_of_FATs=number_of_FATs;     /*文件分配表数*/
			dosboot.bpb.maximum_number_of_root_entries=maximum_number_of_root_entries;/*根目录中目录项数*/
			if(part_size<=32*(1048576/512))               
			{
				dosboot.bpb.total_number_of_sectors=total_number_of_sectors; /*总扇区数*/
				dosboot.bpb.total_huge_sectors=0;          /*巨扇区数*/
			}
			else
			{
				dosboot.bpb.total_number_of_sectors=0;
				dosboot.huge_sectors=total_number_of_sectors;
			}
			dosboot.bpb.media_descriptor=media_descriptor;    /*磁盘介质标志*/
			dosboot.bpb.sectors_per_FAT=sectors_per_FAT;      /*每FAT字节数*/
			dosboot.bpb.sectors_per_track=sectors_per_track;  /*每磁道扇区数*/
			dosboot.bpb.number_of_heads=number_of_heads;      /*磁头树*/
			dosboot.bpb.number_of_hidden_sectors=number_of_hidden_sectors;/*隐藏扇区数*/
			dosboot.drive_no=0x80+drive_no-1;                 /*驱动器号*/
			dosboot.boot_signature=0x29;                      /*扩展标志*/
			dosboot.volume_id=volume_id;                      /*卷序列号*/
			strcpy(dosboot.volume_label,"");                   /*卷标志*/
			strcpy(dosboot.file_system_type,"FAT16");          /*文件系统类型*/
			fp=fopen("\\os\\format\\load.bin","rb");           /* 加载程序*/
			if(fp==NULL)
				printf("\nCan't open load file!\n");
			else 
			{
				fread(dosboot.loader,1,450,fp);
				fclose(fp);
			}
			}
			inregs.h.ah=0x3;
			inregs.h.al=1;
			inregs.h.ch=priboot.part[rpno].beginning_cylinder;
			inregs.h.cl=priboot.part[rpno].beginning_sector;
			inregs.h.dh=priboot.part[rpno].beginning_head;
			inregs.h.dl=0x80+drive_no-1;
			inregs.x.bx=(unsigned)&dosboot;
			segread(&segs);
			int86x(013,&inregs,&outregs,&segs);
			/*初始化目录缓冲区*/
			direntry=(DirEntry*)malloc(bytes_per_sector);
			for(i=0;i<bytes_per_sector/32;i++)
			{
				direntry[i].filename[0]=0x0;
				direntry[i].extension[0]=0x0;
				direntry[i].fileattributes=0x0;
				direntry[i].time_stamp=0;
				direntry[i].data_stamp=0;
				direntry[i].starting_cluster=0;
				direntry[i].file_size=0;
			}
			/*根目录区起始位置*/
			ttcylinder2=bcylinder+(bsector+1+sectors_per_FAT*number_of_FATs-1)/sector_count/head_count;
			tthead2=(bhead+(bsector+1+sectors_per_FAT*number_of_FATs-1)/sector_count)%head_count;
			ttsector2=(bsector+1+sectors_per_FAT*number_of_FATs-1)%sector_count+1;/*初始化根目录区*/
            for(i=0;i<maximum_number_of_root_entries*32/bytes_per_sector;i++)
			{
				inregs.h.ah=0x3;
				inregs.h.al=1;
				inregs.h.ch=ttcylinder2;
				inregs.h.cl=ttsector2;
				inregs.h.dh=tthead2;
				inregs.h.dl=0x80+drive_no-1;
				inregs.x.bx=(unsigned)direntry;
				segread(&segs);
				int86x(0x13,&inregs,&outregs,&segs);
				ttsector2++;
				if(ttsector2>sector_count)
				{
					ttsector2=1;
					tthead2++;
					if(tthead2>head_count-1)
					{
						tthead2=0;
						ttcylinder2++;
					}
				}
			}
		}
		return;
		}

⌨️ 快捷键说明

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