看看这个硬盘信息读取程序!怎么在WIN98下不能读取新信息?(100分)

  • 主题发起人 interguycn
  • 开始时间
I

interguycn

Unregistered / Unconfirmed
GUEST, unregistred user!
在CREATE了SMARTVSD这个设备后,不能读取出数据?哪里的问题??是不是设备CREATE错了?除了SMARTVSD还可以有什么设备可以读取?
begin // Windows 95 OSR2, Windows 98

hDevice := CreateFile( '//./SMARTVSD:',
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0 );
if HDevice=INVALID_HANDLE_VALUE then Exit;
TRY
PinData:=PsendCMDInParams(@Buffer);
PoutData:=@pInData^.bBuffer;
with pInData^ do
begin
CBufferSize:=IDENTIFY_BUFFER_SIZE;
bDriveNumber:=0;
with irDriveREgs do
begin
bFEAturesReg:=0;
bSectorCountReg:=1;
bSectorNumberReg:=1;
bCylLowReg:=0;
bCylHighReg:=0;
bDriveHeadReg:=$A0;
bCommandReg:=IDE_ID_FUNCTION;
end;
end;
if not DEviceioControl(hDevice,DFP_RECEIVE_DRIVE_DATA,pInData,SIzeof(TsendCMDInparams)-1,pOutData,W9XBUfferSize,cbBytesReturned,nil) then result:=false;
finally
closehandle(hDevice);
end;
 
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
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;

//Read

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin

change2ring0;
GetParameter;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin

label1.Caption:='控制号:'+trim(dcl)+',厂家型号:'+trim(dtp)
+',出厂序号:'+trim(dsn);

end;

end.
 
[?][?]我使用了这个程序,但是在一些WIN98下面读取不出来信息啊?不是三星的硬盘。[?][?][^]
 
顶部