|
在VB中对硬盘的底层操作大全(一)VB / API 提问
在VB中对硬盘的底层操作大全(一)
近段时间硬盘烧了两个,现在这个又总是出毛病,于是就产生研究硬盘的念头,先是用螺丝刀拆开一个硬盘,发现里面
有个Disk,很漂亮,现在已经成为一面镜子了。另外还有一个强力磁铁,真的很强喔,弄到我的显示器还有家里的电视机
现在还红一块紫一块。最后觉得不过瘾,很想学学制造病毒的哥哥,用“软”的方法弄一弄别人的硬盘,
好让心理平衡一点(真变态)。现在将学习过程中的一些冬冬贴出来让大伙look look。
一、硬盘基础知识
先讲讲硬盘的几个参数。
1、磁头数(Heads),就是硬盘总共有几个磁头咯,也就是有几面盘片*2,最大值为 256。
2、柱面数(Cylinders),硬盘每一面盘片上有几条磁道(同心圆)呀, 由于以前硬盘大多数是多个盘片的层叠在
一起的,(我拆的这个是单片装的呢)多个盘片的同一个磁道就形成了一个圆柱了,因此称为柱面。最值大为 1024。
3、扇区数(Sectors) 表示一条磁道上有几个扇区, 最大值为63。一个扇区一般是 512个字节
以前硬盘容量的计算公式为:x GB= (Heads * Cylinders * Sectors * BytePerSectors)/(1024 * 1024 * 1024)
例如上述各参数都取最大值时硬盘容量为:(256 * 1024 * 63 * 512) / (1024 * 1024 * 1024) = 7.9 GB
可是制作硬盘的JS的公式是:x GB= (Heads * Cylinders * Sectors * BytePerSectors)/(1000 * 1000 * 1000)
这样同一个硬盘就成8.4GB了,欺骗我们善良的心灵。真是无商不J。
这也是CHS寻址方式的硬盘容量的极限,在CHS寻址方式中, 磁头, 柱面, 扇区的取值范围分别为 0 到 Heads-1,
0 到 Cylinders-1, 1 到 Sectors per track。
为了突破这个容量的极限,后来就出现了 LBA,LARGE 等寻址方式。
二、硬盘的数据结构
1、硬盘上的0磁头、0柱面、1扇区是最重要的一个扇区,称之为:Boot Sector。
Boot Sector主要由 MBR (Master Boot Record,主引导记录),DPT (Disk Partition Table,分区表)等组成。
MBR占用前446字节(&H0 到 &H1BD),存放系统主引导程序。
DPT占用 64 个字节(&H1BE to &H1FD),记录了磁盘的主分区信息。主分区表分为四个分区项, 每项 16 字节,分别记录了每个主分区的信息,所以最多可以有四个主分区。
最后还有两个字节,分别储存&H55和&HAA,这是判别引导区是否合法的标志。
2、Boot Sector 的具体结构如下图(其实是文字来的,将就以下啦)所示:
0000 |------------------------------------------------|
| |
| |
| Master Boot Record |
| |
| |
| 主引导记录(446字节) |
| |
| |
| |
01BD | |
01BE |------------------------------------------------|
| |
01CD | 分区信息 1(16字节) |
01CE |------------------------------------------------|
| |
01DD | 分区信息 2(16字节) |
01DE |------------------------------------------------|
| |
01ED | 分区信息 3(16字节) |
01EE |------------------------------------------------|
| |
01FD | 分区信息 4(16字节) |
|------------------------------------------------|
| 01FE | 01FF |
| 55 | AA |
|------------------------------------------------|
MBR中包含了硬盘的一系列参数和一段引导程序。其中的硬盘引导程序的主要作用是检查分区表是否正确并且在系统硬件完成自检以后引导具有激活标志的分区上的操作系统,并将控制权交给启动程序。MBR是由分区程序(如Fdisk.com)所产生的,它不依赖任何操作系统,而且硬盘引导程序也是可以改变的,从而实现多系统共存。所以这里就不讲这部分数据的意思咯,嗬嗬。
3、DPT(16个字节)中数据的意义
BYTE State : 分区状态, 0 = 未激活, 0x80 = 激活
BYTE StartHead : 分区起始磁头号
WORD StartSC : 分区起始扇区和柱面号, 底字节的低6位为扇区号,
高2位为柱面号的第 9,10 位, 高字节为柱面号的低 8 位
BYTE Type : 分区类型, 如 0x0B = FAT32, 0x83 = Linux 等, 00 表示此项未用
BYTE EndHead : 分区结束磁头号
WORD EndSC : 分区结束扇区和柱面号, 定义同前
DWORD Relative : 在线性寻址方式下的分区相对扇区地址(对于基本分区即为绝对地址)
DWORD Sectors : 分区大小 (总扇区数)
例:80 01 01 00 0B FE BF FC 3F 00 00 00 7E 86 BB 00
最前面的"80"是一个分区的激活标志,表示系统可引导;"01 01 00"表示分区开始的磁头号为01,开始的扇区号为01,开始的柱面号为00;"0B"表示分区的系统类型是FAT32,其他比较常用的有04(FAT16)、07(NTFS);"FE BF FC"表示分区结束的磁头号为254,分区结束的扇区号为63、分区结束的柱面号为764;"3F 00 00 00"表示首扇区的相对扇区号为63;"7E 86 BB 00"表示总扇区数为12289622。
三、用VB直接读取硬盘的数据
硬盘上Boot sector的数据是如此的重要,因此我们就不能用平常的方法去读取了,例如:
open "hdd0" for binary as #1 这样只能是读读文件上的数据而已,那么怎样直接读取硬盘的数据呢?
呵呵,这就要用到几个API咯。
首先用 CreateFile API打开一个物理的硬盘,系统中第一个硬盘的名称为 \\.\PHYSICALDRIVE0,第二个硬盘的名称
为\\.\PHYSICALDRIVE1,如果成功地打开,则返回一个指向物理硬盘的句柄,否则返回INVALID_HANDLE_VALUE。
下面的代码可以帮我们找到系统上有多少个物理的硬盘。其中hDevice为物理硬盘的句柄。
dim hDevice as long
dim nDevice as long
Do
hDevice = CreateFile("\\.\PHYSICALDRIVE" & CStr(nDevice), _
0&, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
ByVal 0&, _
OPEN_EXISTING, _
0&, 0&)
If hDevice <> INVALID_HANDLE_VALUE Then
'//在这里可以添加读取硬盘数据的代码。(*)
CloseHandle hDevice
nDevice = nDevice + 1
Else
If Err.LastDllError = ERROR_FILE_NOT_FOUND Then
'No more physical drives.
Exit Do
Else
'GetPhysicalDrives error
Exit Do
End If
End If
Loop
debug.pring "硬盘总数为:" nDevice
当获取了物理硬盘的句柄hDevice之后,就可用 ReadFile Api读取里面的数据了,例如:在上面(*)那里插入下面的语句,
即可读取 BootSector 的内容。
dim Buffer(1 to 512) as Byte
dim hadRead as long
dim RetVal as long
dim i as long
RetVal = ReadFile(hDevice, Buffer(1), 512, hadRead, 0)
If RetVal And (hadRead = UBound(Buffer)) Then
for i=1 to 512
debug.print Hex$(Buffer(i)),
next
Else
'Error reading the drive.
End If |
|