如何提取硬盘ID号?(100分)

  • 主题发起人 主题发起人 scylzh
  • 开始时间 开始时间
S

scylzh

Unregistered / Unconfirmed
GUEST, unregistred user!
最近编写一个程序,想提取硬盘ID号,如何实现呢?
 
Function GetHardDiskSerieNummer : string;
var
Teller : integer;
Lus : integer;
SerieNummer : array[0..24] of char;
begin
result := '';
Teller := 1;
for Lus := 1 to 8 do
begin
SerieNummer[Teller] := chr((HardDiskGegevens[10+Lus] div 256 ));
inc(Teller);
SerieNummer[Teller] := CHR((HardDiskGegevens[10+Lus] mod 256 ));
inc(Teller);
end;
result := SerieNummer;
end;
 
HardDiskGegevens是什么?
 
HardDiskGegevens这是个什么函数,请详细说明
 
上面那位兄台的方法不对头,还是下载另一位老兄的控件或者DLL
http://tj-gmjf.com/dandy/
这是迄今为止最好的解决方案了
 
请教如何安装这个控件呢?
 
我摘别人的,名字忘记了,我没试过,你试试吧。。。
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
type
TGate = record
Off2,op,seg,off1:WORD;
end;

const
_dsnlen=20; //硬盘序列号的位数,10个Word,必须是偶数
_dtplen=40; //硬盘生产厂家型号的位数,18个Word
_dcllen=8; //硬盘控制号的位数

var
IDTR : INT64;
SavedGate : TGate;
OurGate : TGate;
dd : array [0..256] of word;

dsn : array [0.._dsnlen-1] of char; //存放硬盘序列号
dtp : array [0.._dtplen-1] of char; //存放硬盘型号
dcl : array [0.._dcllen-1] of char;

// Ring0 中断服务例程 Ring0Proc ,通过端口读取硬盘参数
procedure Ring0Proc();
asm
// Wait for controller not busy
mov dx,01f7h
@1:in al,dx
cmp al,050h
jne @1

// Get first/second drive
dec dx //mov dx,01f6h
mov al,0a0h
out dx,al

// Get drive info data
inc dx //mov dx,01f7h
mov al,0ech
out dx,al
nop
nop

// Wait for data ready
@2:in al,dx
cmp al,058h
jne @2
nop
nop

// Read sector
xor ecx,ecx
mov dx,01f0h
@3:in ax,dx
mov word ptr dd[ecx*2],ax
inc ecx
cmp ecx,256
jne @3

iretd //中断返回
end;

//改变程序运行的特权级,以调用自定义中断程序 Ring0Proc
procedure Change2Ring0();
asm
mov eax, offset Ring0Proc
mov OurGate.off2, ax //将中断函数的地址填入新造的中断门描述符
shr eax, 16
mov OurGate.off1, ax
mov OurGate.op,0028h
mov OurGate.seg,0ee00h
mov ebx,offset IDTR
sidt [ebx]
//将中断描述符表寄存器(IDTR)的内容取出
mov ebx, dword ptr [IDTR+2]
//取出中断描述符表(IDT)基地址
add ebx, 8*3
//计算Int 3 的描述符应放置的地址选用
//Int3 是因为它在Win32 保护模式下未占用
mov edi, offset SavedGate
mov esi, ebx
movsd //保存原来的Int 9 描述符到SavedGate 以便恢复
movsd

mov edi, ebx
mov esi, offset OurGate
cli
movsd //替换原来的中断门描述符以安装中断服务例程
movsd
sti
mov eax,6200h
//用以测试放在EAX 中的数据能否正确传到 Ring0 中断
mov ecx,0
{用以测试放在 ECX 中的数据能否正确传到 Ring0 中断
因为很多VxD 服务都用此二寄存器传递参数}
int 3h
{人为触发中断, 平时会出现保护错误蓝屏或非法操作对话框,
现在安装了中断服务例程后,
就会通过 VMM 在Ring0 调用中断服务例程Ring0Proc}
mov edi, ebx
mov esi, offset SavedGate
cli
movsd //恢复原来的中断门描述符
movsd
sti
end;

//截取硬盘出厂参数:控制号,型号,序列号
procedure GetParameter;
begin
{硬盘的序列号存放于 dd[10] 开始的10个WORD中,使用时需要将每个WORD的
高低字节颠倒一下}
asm
xor ecx,ecx
mov ebx,offset dd[10*2]
@1:mov ax,[ebx]
cmp ah, 0 //
je @2 //
mov byte ptr dsn[ecx],ah
cmp al, 0 //
je @2 //
inc ecx
mov byte ptr dsn[ecx],al
inc ebx
inc ebx
inc ecx
cmp ecx, _dsnlen
jne @1
@2:
end;

{硬盘的型号存放于 dd[27] 开始的18个WORD中}
asm
xor ecx,ecx
mov ebx,offset dd[27*2]
@1:mov ax,[ebx]
cmp ah, 0 //
je @2 //
mov byte ptr dtp[ecx],ah
cmp al, 0 //
je @2 //
inc ecx
mov byte ptr dtp[ecx],al
inc ebx
inc ebx
inc ecx
cmp ecx, _dtplen
jne @1
@2:
end;

{硬盘的控制号存放于 dd[23] 开始的3个WORD中}
asm
xor ecx,ecx
mov ebx,offset dd[23*2]
@1:mov ax,[ebx]
cmp ah, 0 //
je @2 //
mov byte ptr dcl[ecx],ah
cmp al, 0 //
je @2 //
inc ecx
mov byte ptr dcl[ecx],al
inc ebx
inc ebx
inc ecx
cmp ecx, _dcllen
jne @1
@2:
end;
end;


end.
 
无须控件
var
VolumeSerialNumber: DWORD;
MaximumComponentLength: DWORD;
FileSystemFlags: DWORD;
SerialNumber: string;
begin
GetVolumeInformation('C:/',
nil,
0,
@VolumeSerialNumber,
MaximumComponentLength,
FileSystemFlags,
nil,
0);

SerialNumber := inttostr(HiWord(VolumeSerialNumber) + LoWord(VolumeSerialNumber));
//serialNumber 就是返回的序号
 
你可去
http://vip.6to23.com/songdai/DiskSerial.html看看,
会有收获的!
 
lw86朋友,我去了并下了,可以用,但要授权使用,
在我和程序中,就造成了不便。有没有比这更好的呢?
asiasmm朋友,我试过你说的方法了。但提取出来的不是我的硬盘ID呀!
 
我给你发过来了,给分呀!
 
接受答案了.
 

Similar threads

后退
顶部