社区
Delphi
帖子详情
获取硬盘号
supershan
2000-01-10 11:28:00
有谁知道获取硬盘号的API函数,请举例说明!
...全文
238
3
打赏
收藏
获取硬盘号
有谁知道获取硬盘号的API函数,请举例说明!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
3 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
supershan
2000-01-10
打赏
举报
回复
感谢二位对以上问题的回答特别感谢tiger对上述问题做的详细回答不过我要的是label,
所以不能给你分再次表示感谢。
渤海海峡
2000-01-10
打赏
举报
回复
function GetHDSerialNumber: LongInt;
{$IFDEF WIN32}
var
pdw : pDWord;
mc, fl : dword;
{$ENDIF}
begin
{$IfDef WIN32}
New(pdw);
GetVolumeInformation(nil,nil,0,pdw,mc,fl,nil,0);
Result := pdw^;
dispose(pdw);
{$ELSE}
Result := GetWinFlags;
{$ENDIF}
end;
tiger
2000-01-10
打赏
举报
回复
你说的是序列号还是label?
label的话有GetVolumeInformation.
序列号的话, 可能没有现成的api, 用汇编吧.
取得ring0级权限, 调用中断
请看下面的例子, DING KAI的作品(www.nease.net/~dingkai/)
硬盘的序列号是厂家设定的,且只能用I/O指令读取,所以,这在以前的DOS时代
根本不是什么问题.方法非常简单,如下面的代码所示:
static int WaitIde()
{
int al;
while ((al=inp(0x1F7))>=0x80) ;
return al;
}
static void ReadIDE()
{
int al;
int i;
WORD pw[256];
WaitIde();
outp(0x1F6,0xA0);
al = WaitIde();
if ((al&0x50)!=0x50) return;
outp(0x1F6,0xA0);
outp(0x1F7,0xEC);
al = WaitIde();
if ((al&0x58)!=0x58) return;
for (i=0;i<256;i++) {
pw[i] = inpw(0x1F0);
}
}
至此,关于IDE硬盘的信息已经在 pw 数组中了,需要注意的是该数组是一个 WORD
类型,硬盘的序列号存放于 pw[10] 开始的10个WORD中,使用时需要将每个WORD的
高低字节颠倒一下。
真正有点麻烦的是在Windows 95/98下,I/O指令作为特权指令在应用程序级别,即
Ring 3是不可使用的,所以上面的代码在执行到 WaitIde()时会陷到死循环中,原
因就是 IN 0x1F7 总是返回 0xFF
容易想到的解决办法是写一个VxD,因为VxD运行Ring 0级别上,即最高特权级上,所以
所有的指令都是可用的。当然,这没有任何问题,事实上我已经写了这样的 VxD,效果
是明显的,如果哪位有兴趣,可与我联系。
如果你是一个编程高手,这没有什么难度,所以不必看下去。
如果你连VxD也不会写,请参阅拙作"VxD入门教程"。
当然,如果连象读取硬盘序列号这样小的问题都要写个VxD,确实是一件令人生厌的事,
且不说既要额外装个Win 95 DDK,又要防止VxD出现错误使系统崩溃这种多余的工作
和担心,旦旦是发行程序时带个这么小的东东就让人看着扎眼(读硬盘序列号无非是为了
防止拷贝,这个小东东明显会提示别人应该如何破解)。
所以我推荐的方法是真接从 Ring 3 完成该功能,即在你的EXE文件中处理这件事,这
样一方面减小了编程难度,另一方面有利于实现防止拷贝的目的。
实现的方法出人意料的简单,不过,也还是需要 100 行左右的代码。
唯一的一个技术难点就是利用 CPU 的异常从 Ring 3 直接切换到 Ring 0。如果解决了
这个问题,那么整个程序就非常简单了,值得一提的是,由于该技术将代码切换到
Ring 0 运行,所以,....., 不用我多说了吧?
不象在实模式下,中断向量表位于内存地址的0:0处,每当中断发生时,无论是硬中断还
是软中断,CPU都会从该表中查找中断的入口位置,并执行相应的中断程序。在保护模式
下(包括V86方式),物理内存0:0处不再有中断向量表,甚至"0:0"这种表示方式也发生了
变化,原来的段址不复存在,代之以段选择器,中断向量也用中断描述符表(IDT)取代了,
这意味着当发生中断或异常时(异常只在保护模式下存在,可以把它当作中断看待),CPU
查找的是IDT,然后再根据查到的入口地址执行相应的中断处理程序。
关于这部分内容请参阅80386 (或以上) CPU的技术手册。
从上面可以看出,虽然查找的内容及方法发生了变化,但原理并没有变,如果要修改中
断入口,所需要修改的地方无非是变成了IDT而已。更妙的是,中断处理程序是运行在
CPU最高特权级Ring 0上,这就使得我们从Ring 3进行Ring 0级别的操作成为可能。
具体方法可以归结如下:
首先,取得系统 IDT,这可用 SIDT 指令一步到位,且不受特权级限制;
然后,修改 IDT 中某一中断的入口,使其指向我们自己的处理程序;虽然理论上IDT表
中的所有中断都可以使用,但我建议使用中断 3, 这个中断是给调试器用的,平常没啥
用(修改的方法请参阅IDT的格)。
最后,执行该中断。可以直接执行代码 INT 3,当然,在 Ring 3 上执行该指令必然会导
致CPU异常,于是,我们的处理程序就这样轻易而举地得到了控制权。
一旦得到CPU最高特权级的控制权,中断处理程序就可以进行任何平常在 Ring 3 级别上
不能够进行的操作了,当然也包括本文的主题:读取硬盘序列号。
说得再具体一些,就是将本文前面提到的代码放到中断处理程序中即可全部搞定了。
至于用 C 语言或是汇编语言,那就完全视个人情况了。
我采用的方法是用 C 语言加上内嵌的汇编,完整的程序代码不列在此处了,需要的话请
直接与本人联系(也省得有人未经允许抄俺的程序 :Q)
最后,需要说明的是,这种方法不可以在 Windows NT 下使用。是什么原因我就不多说
了。
一些题外话,实际上我写这篇文章的目的并不完全是为了读取硬盘的序列号(这东东毕竟
没多大用途,有些硬盘,如三星的 32543A 根本就没有序列号),主要的目的是想在从
Ring 3 获取 Ring 0 特权这个问题上做些尝试,希望有兴趣的朋友能够参予进来,公开
你所掌握的技术,大家共同提高编程水平。
c++实现
获取
硬盘
号
c++实现
获取
硬盘
号类,win2000/win2003/win7/win8/ 64位,32位都测试过可以
获取
到产商及序列号。
C++
获取
硬盘
序列号 mac地址
底层函数
获取
windows磁盘序列号 mac地址。
硬盘
序列号,英文名:Hard Disk Serial Number,该号是
硬盘
厂家为区别产品而设置的,是唯一的。网上搜索一下,发现
获取
硬盘
序列号的代码遍地都是,但很多是错误的。典型代表就是使用GetVolumeInformation函数
获取
序列号。这种方法
获取
的是卷的序列号,即Volume Serial Number。
硬盘
格式化后,这种序列号将发生变化。本文描述的是
获取
硬盘
唯一的物理序列号的方法。
vb.rar_VB
硬盘
加密_读取
硬盘
号
用于读取
硬盘
号,可做更改后用于文件加密认证号
labview
获取
硬盘
号
labview读取GetHW.dll文件
获取
数据
获取
硬盘
物理序列号 获得唯一
硬盘
序列号 唯一标识 纯API方法,没有DLL,没有控件,另外给出了WMI方法的结果作为比较
1.VB.NET 2008开发环境的工程文件,纯API方法
获取
硬盘
物理序列号,也就是所谓全球唯一标识的号,通常用这个号作为软件注册的唯一标识;写到一个函数中,非常方便移植代码! 2.使用说明:打开程序后,点按钮后,三个TEXTBOX分别显示全球唯一标识的
硬盘
物理序列号、WMI方法
获取
的
硬盘
序列号、WMI方法
获取
的CPU序列号 3.WMI方法被很多人诟病,有说读不出来什么的,我测试了几台机器确实有读不出来的,结果为0;WMI
获取
CPU序列号速度比较慢,有将近1秒的延时。 4.总之,大家根据自己需求移植代码。 5.谢谢支持。
Delphi
5,392
社区成员
262,731
社区内容
发帖
与我相关
我的任务
Delphi
Delphi 开发及应用
复制链接
扫一扫
分享
社区描述
Delphi 开发及应用
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章