其实现原理很简单,众所周知,几乎所有与磁盘操作有关的调用,最后都要转到BIOS中的INT13。因此我们只需编制一小段内存驻留程序接管INT13,使所有的磁盘操作都必须先经过该驻留程序的检测,若是写操作则拦截之,若为读操作则调用原INT13使之正常运行。
还有一个问题就是硬盘常常被分为多个逻辑分区,用户可能只想对其中一个或几个分区实现写保护。为此,我们得分析一下INT13的入口参数及硬盘分区表链。
INT13的入口参数有:
AHΚ功能号(其中3、5、7、0BH、0FH、13H、19H为写操作)
ALΚ要读/写的扇区数
CHΚ柱面号
CLΚ扇区号
DHΚ磁头号
DLΚ驱动器号(其中0为A:,1为B:,80H为第一个硬盘)
从AH中判断是否为写操作而决定是否拦截之,从DL中可以判断是软盘还是硬盘,最后一个问题就是怎样判断是逻辑C区还是D区、E区……它们是不是应该写保护的盘。
我们用DEBUG输入一小段汇编程序
MOVDL,80;驱动器号
MOVDH,0;磁头号0
MOVCH,0;柱面号0
MOVCL,1;扇区1
MOVAL,1;扇区数
MOVBX,2000
MOVAH,2;读磁盘
INT13
INT3
读出C盘0头0柱1扇区的内容
XXXX:21BE80010100 01031168 ......
XXXX:21CE00000169 ......
偏移1BF?1C1是C区的起始磁头(简称H)、起始扇区(简称S)、起始柱面(简称C)
偏移1C3?1C5是C区的终止H、终止S、终止C
偏移1CF?1D1是D区的起始H、起始S、起始C
我们可把1CF?1D1的数据分别代入上面汇编程序的DH,CL,CH,同样可读出D区的分区信息。
XXXX.21BE00010169 010311CC ......
XXXX.21CE000001CD 05......
其中,偏移1BF?1C1是D区的起始H、起始S、起始C;偏移1C3?1C5是D区的终止H、终止S、终止C;偏移1CF?1D1是E区的起始H、起始S、起始C。同样的道理,我们可读出E区、F区……的分区信息。这便是硬盘分区表链。
我们可由分区表链取得要写保护分区的起始、终止H、S、C,但有一点要注意的是S中的高2位与C中的8位组合成的10位二进制数方是真正的C,去掉高2位的S方是真正的S。例从某分区读出的终止S、C分别为51H、30H。
可见S截掉高2位后为11H,C加上2位后为130H。
把变化后的起始和终止S、C及H保存起来,作为真正的起始和终止H、S、C。同样的道理INT13的CL、CH中的S、C也应作相应的变化。这时我们便可以确定下面不等式的成立与否。
保存的真正起始H,S,C〈ΚINT13的真正H,S,CΙΚ保存的真正终止H,S,C若成立则应写保护,从而解决了怎样判断哪个分区是写保护分区的问题。
但实际上,硬盘的分区是先按柱面分,再按磁头分,最后按扇区分的。因此我们的判断顺序应该是这样的:先判断
保存的真正起始C〈ΚINT13的真正CΙΚ保存的真正终止C
若INT13的C恰好等于保存的终止C,则应进一步判断H;若INT13的H值小于保存的终止H,则表明在写保护盘内;若INT13的H大于保存的终止H,则表明超出了写保护盘的范围,若等于则应进一步确定S;若INT13的S值大于保存的终止S值则是超出了写保护盘,反之,小于、等于则是在写保护盘内。根据以上原理,我们不难把程序编制出来,源程序在此省略。编译成可执行文件后键入命令行:
WRTPRT[DRIVER1][DRIVER2][DRIVER3][DRIVER4][DRIVER5]
例:要对C:和D:写保护则键入命令行
WRIPRTC:D:
其中不带参数的WRTPRT默认为对C:写保护。

