用C语言建立多个PRI DOS分区

一、引言

在DOS系统下,在计算机应用培训中因培训要求不同, 对软件的要求也不同,由于学员的误操作,存放在硬盘上的软件和重要数据容易被非法删除或受到损坏。对此,笔者通过对硬盘管理的深入分析和实践,总结出了在硬盘上备份、保护重要数据和软件的一种新的行之有效的方法:建立多个PRI DOS 分区, 不同的培训要求使用不同的PRI DOS分区,在使用时同时只有一个PRI DOS 分区可供使用, 其余PRI DOS分区均被隐含。

二、分区表结构

众所周知,DOS操作系统下,一个硬盘可以分为PRI DOS分区和扩展分区两大部分,而扩展分区中又可进一步建立多个逻辑分区。这些PRI DOS分区和逻辑分区都可象单独的物理硬盘一样使用。那么DOS是怎样实现对这些分区的管理和使用的呢?DOS 管理硬盘的秘密是两个表:硬盘分区表链。系统在启动过程中,DOS 根据硬盘分区表链及分区表提供的分区信息建立了各个分区的磁盘参数表(BPB表),而磁盘参数表是DOS访问硬盘的基础。 因此分区表链及分区表在硬盘存取中具有非常重要的地位。

分区表链存于硬盘上,一般由一个主引导结点和多个普通结点构成。主引导结点同PRI DOS分区对应,为硬盘的0柱面0头1扇区,是硬盘主引导记录扇区。在头结点扇区中,从开始到0DAH的218 字节是一段主引导程序;从0DBH到1BDH共228字节为00H;从1BEH到1FDH处64字节是硬盘的主分区表,共四个表项,每个表项16字节,其中前两个表项分别指示主分区和扩展分区在硬盘中的信息,后两个表项一般不用,全为00H;;扇区最后两个字节是结束标志55H、AAH。

表项的数据结构如下:
相对偏移 长度(BYTE) 含义
0 1 激活标志
1 3 分区起始位置(柱、头、扇)
4 1 分区类型
5 3 分区终止位置(柱、头、扇)
8 4 分区起始扇区的相对序号
12 4 分区大小
表项结构中的激活标志在激活时为80H(否则为00H),所谓起始位置,对于本分区表项而言,是该分区的起始柱1头1扇区;对于扩展表项而言指的是相应的扩展分区的起始柱0头1扇区。分区类型常见值有1、4、6、5等。1表示12位FAT的分区,4表示16位FAT的分区,6 表示容量大于32M的分区,5表示扩展分区。分区大小等于各相应分区从起始扇区到终止扇区的扇区数,对于本分区表项,此值不含隐含扇区,对于扩展表项此值包含隐含扇区,而对PRI DOS 分区里的扩展表项,此值等于各逻辑分区所有扇区包括隐含扇区之和。所谓起始扇区的相对应序号,其相对起点分三种情况:对于本分区表项,序号是相对于该分区的起始柱0头1扇区;对于扩展表项,若是PRI DOS的扩展分区,则相对于PRI DOS分区的主引导记录扇区;若是逻辑分区的扩展, 则一律相对于整个扩展分区的起点,此起点一般就是第一逻辑分区的起始柱0头1扇区。

三、建立多个PRI DOS分区

从上面的分析中我们清楚了分区表由四个表项组成(尽管一般最多只使用两项),并且主分区表的第一表项指向PRI DOS分区,第二个表项指向扩展分区。如果按照正常的使用方法,完全没有必要设置四个表项,既然如此设置,必有其使用的目的。由于主分区表中的扩展表项中的某些项包含了所有扩展分区的有关信息,为此我先用 FDISK建立只有一个逻辑分区的扩展分区。然后将该扩展分区表项的分区类型由5改为6,再将其激活标志由00H改为80H(注意必须同时将原先的PRI DOS分区的激活标志由80H改为00H)。 然后必须重新用软盘启动机器并格式化C盘,则就可用新建立的PRI DOS分区启动机器( 原先的PRI DOS分区的盘符变为D)。这样就建立了两个PRI DOS分区。

四、隐含分区的设置和恢复

我们已经知道硬盘主引导记录扇区中从0DBH到1BDH共228 个字节为00H,在建立了多个PRI DOS分区之后,就可利用这228 个字节的最后64个字节来保存四个表项有内容。选定一个PRI DOS分区, 然后将四个表项中的其它所有分区类型为非扩展分区的表项的内容全部改为00H。这样在硬盘上就只有一个PRI DOS分区,其它被隐含起来。

如要将隐含分区恢复正常,只需将其保存在主硬盘主引导扇区中的内容重新写入到该表项即可。

五、源程序

下面给出源程序:PDOS.CPP。该源程序在编译环境TURBOC++ 3.0下在兼容机上编译。使用方法为在DOS提示符下键入:[D:] [ PATH]
PDOS <C/S/R/1/2/3/4>(S:建立PRI DOS分区;S:对PRI DOS分区表项进行备份;R:收复PRI DOS分区表项;1:只保留PRI DOS分区表项的第一项,其余均隐含;2:只保留PRI DOS分区表项的第二项;3: 只保留PRI DOS分区表项的第三项;4:只保留PRI DOS分区表项的最后一项)。

以下为PDOS.CPP程序清单:

#include<dos.h>
#include<bios.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
struct HSC
{char hd,sc,cy;};
struct PartitionTable
{char Flag; /* 激活标志 */
HSC begin; /* 开始位置 */
char TYpe; /* 分区类型 */
HSC end; /* 结束位置 */
long id; /* 开始扇区的相对序号 */
long size; /* 分区大小 */
};
struct note /* 结点结构 */
{char boot1[366];
PartitionTable PT[1];
PartitionTable PT1[4];
PartitionTable PT2[4]; /* 主DOS分区表项 */
char f[2];
}dosboot;
void create_pri_dos(); /* 建立(将扩展分区修改成)主DOS分区 */
void set_hidde_dos(); /* 对主DOS分区表项进行备份 */
void recall_dos(); /* 恢复主DOS分区表项 */
void change_dos(char n); /* 只保留一个主DOS分区,其余均隐含 */
main(int argc,char *argv[])
{
char n;
if (argc!=2)
{ printf("Bad connamd !");
return 0;
};
strlwr(argv[1]); /* 将参数中的大写字母转换成小写字母 */
while((*(argv[1]++))==0); /* 搜寻第一个非空格字符 */
n=*(--argv[1]);
switch(n){
case 'c':
create_pri_dos();
break;
case 's':
set_hidde_dos();
break;
case 'r':
recall_dos();
break;
case '1': /* 只保留主DOS分区表项中的第一项,其余主DOS分区表项均隐含 */
change_dos(n);
break;
case '2': /* 只保留主DOS分区表项中的第二项 */
change_dos(n);
break;
case '3': /* 只保留主DOS分区表项上的第三项 */
change_dos(n);
break;
case '4': /* 只保留主DOS分区表项上的第四项 */
change_dos(n);
break;
default:
return 0;
};
return 0;
}
void create_pri_dos()
{int i;
biosdisk(2,0x80,0,0,1,1,&dosboot);
for (i=0;i<4;i++)
{if ((dosboot.PT2[i].TYpe!=0)&&(dosboot.PT2[i].TYpe!=5))
{dosboot.PT2[i].Flag=0x00;};
if (dosboot.PT2[i].TYpe==5)
{dosboot.PT2[i].TYpe=6;
dosboot.PT2[i].Flag=0x80;};
};
biosdisk(3,0x80,0,0,1,1,&dosboot);
return;
};

void set_hidde_dos()
{
int i;
biosdisk(2,0x80,0,0,1,1,&dosboot);
for(i=0;i<4;i++)
{if ((dosboot.PT2[i].TYpe!=0)&&(dosboot.PT2[i].TYpe!=5))
{dosboot.PT1[i]=dosboot.PT2[i];};
};
biosdisk(3,0x80,0,0,1,1,&dosboot);
return;
};
void recall_dos()
{
int i;
biosdisk(2,0x80,0,0,1,1,&dosboot);
for (i=0;i<4;i++)
{if (dosboot.PT1[i].TYpe!='0')
{
dosboot.PT2[i]=dosboot.PT1[i];
dosboot.PT1[i]=dosboot.PT[0];
};
};
biosdisk(3,0x80,0,0,1,1,&dosboot);
return;
};

void change_dos(char n)
{
int i,m;
m=n-49;
biosdisk(2,0x80,0,0,1,1,&dosboot);
if (dosboot.PT1[m].TYpe!=0)
{ for (i=0;i<4;i++)
{if (dosboot.PT1[i].TYpe!=0)
{dosboot.PT2[i]=dosboot.PT[0];};
};
dosboot.PT2[m]=dosboot.PT1[m];
dosboot.PT2[m].Flag=0x80;
};
biosdisk(3,0x80,0,0,1,1,&dosboot);
return;
};

六、举例及注意事项

在1.2G的硬盘上建立三个PRI DOS分区,大小分别为300Mb, 400M和500MB的例子:

首先用FDISK建立一个300MB的PRI DOS分区和400MB的扩展分区,并激活PRI DOS分区,用软盘启动计算机并格式化C盘,执行PDOS S命令,使扩展分区变成PRI DOS分区,再用软盘启动计算机并格式化C盘,原先的PRI DOS分区的盘符变为D。然后用FDISK建立500MB的扩展分区,在执行PDOS S命令后,再用软盘启动计算机并格式化C盘, 这样就建立了三个PRI DOS分区。其盘符和容量的对应关系为C:500MB; D :300MB;E:400MB。

由于在PRI DOS 分区表项之间切换时只保留一个表项可供使用,因此必须将PDOS.EXE程序拷贝到所有PRI DOS分区中。另个读者在应用本程序时一定要准确无误地输入源程序,以防破坏硬盘上的数据。

时间: 2025-01-01 20:01:47

用C语言建立多个PRI DOS分区的相关文章

iOS开发:Unity3D 使用C#语言建立本地数据库

  首先你需要得到Mono.Data.Sqlite.dll 文件 与System.Data.dll文件.如果你在Mac 操作系统下使用Unity那么很悲剧,找不到这两个文件,至少我没能找到.后来我在Windows下的Unity安装路径中找到了它.为了方便大家我将这两个文件上传至网盘中,如果没有这两个文件的朋友请下载.Unity数据库文件.zip .zip文件下载完毕后直接解压,然后将Mono.Data.Sqlite.dll 文件 与System.Data.dll文件放在Unity工程中的Asse

写入时冲突-用c语言建立一个顺序表,并且对表进行操作

问题描述 用c语言建立一个顺序表,并且对表进行操作 写了个小程序,目的要求:用c语言建立一个顺序表,表中元素为学生,每个学生信息包含姓名.学号和成绩三部分,对该表实现:① 输出.② 插入.③ 删除.④ 查找功能,并计算出平均成绩和总成绩 感觉我的代码没什么问题,编译也正常通过,但是每次运行都会出现这样的问题,不知道是什么原因,希望又高手能帮忙解答下,谢了 #include#include void chu(int a); void zhao(int a);void cha(int a); voi

c语言建立二叉树怎么输入多组数据

问题描述 c语言建立二叉树怎么输入多组数据 #include #include typedef struct BiTNode { char data; struct BiTNode *lchild,*rchild; } BiTNode,*BiTree;//定义结点类型 BiTree CreateBiTree()//创建树 { char p;BiTree T; scanf("%c",&p); if(p == '$') T=NULL; else { T=(BiTNode *)mal

struct-自己编的c语言建立二叉树的代码,运行时出错了,自己找不到错误,求大神帮忙,指点,急.

问题描述 自己编的c语言建立二叉树的代码,运行时出错了,自己找不到错误,求大神帮忙,指点,急. 自己编的c语言建立二叉树的代码,运行时出错了,自己找不到错误,求大神帮忙,指点,急. #include #include typedef struct tnode Tnode; struct tnode { Tnode *left; Tnode *right; int data; }; Tnode *new_tnode(int data) { Tnode *new = malloc(sizeof(Tn

c语言-C语言建立单链表的问题

问题描述 C语言建立单链表的问题 #include<stdio.h> #include<stdlib.h> struct node { int num; int L; struct node *next; }; typedef struct node LN; typedef struct { int num1[100]; int L1; }S; void Creat1(S &p); void Creat(LN *p); void main() { S p; LN *h; p

用C# 语言建立word索引,求源代码。。。

问题描述 用C# 语言建立word索引,求源代码... 各位大神,求用C# 语言建立word索引得源代码啊,急用啊.....有重谢啊.. 导入一篇word文档,自己选择关键词,然后再文档里面搜索关键字的位置,比如页码数和行数,标记下来,然后在文档的下面,显示该关键字在哪几页出现过.. 如这种形式: 解决方案 你能详细点说明你的要求吗?我有这方面的资料;你说详细点,我看看是不是你需要的,如果是你需要的就发给你 解决方案二: 我有C#与World操作的代码,可是你说的索引是怎么回事: 解决方案三:

c语言-建立N个城市的最小代价通讯网络

问题描述 建立N个城市的最小代价通讯网络 要求:输入N个城市相互之间建立通讯的代价,并存储在文件中:构造一个通讯网络,使得N个城市能够连通并且代价最小(可以使用prim算法实现). 在处理题目时,要求从分析题目的需求入手,按设计抽象数据类型.构思算法.通过类的设计实现抽象数据类型.编制上机程序和上机调试等若干步骤完成题目,最终写出完整的分析报告.前期准备工作完备与否直接影响到后序上机调试工作的效率.在程序设计阶段应尽量利用已有的标准函数,加大代码的重用率. 设计出的系统要有一个易于使用人机界面.

Go语言建立一个最简单的服务端点

handlers/handlers.go package handlers import ( "encoding/json" "net/http" ) func Routes() { http.HandleFunc("/sendjson", SendJSON) } func SendJSON(rw http.ResponseWriter, r *http.Request) { u := struct { Name string Email str

如何在win7电脑中建立一个隐藏的磁盘分区?

  自己的电脑.自己的磁盘,自然也就有一些自己的东西,这些东西往往是不希望被别人看到的,不管是私人的还是工作的,都是如此,那么大家是否有想到好的办法可以让这些文件资料隐身起来呢?下面,小编就来说说自己的经验之谈,不妨在win7 64位旗舰版中建立一个隐藏的分区,将这些文件全部放进去,这样就能神不知鬼不觉了! 1.首先,咱们返回到电脑桌面,找到计算机图标,右键点击,进入管理界面,然后在管理界面中点击左侧菜单中的磁盘管理. 2.接下来咱们看右侧窗口中出现的磁盘分区,选择一个比较适合的分区,然后右键点