我从网上下载了一个得到硬盘ID的DLL,它其中对DELPHI调用是这样说明的:
type mychar=array[0..31] of char;
type TDiskID32=Function(var DiskModel,DiskID:mychar):BOOL;stdcall;请问,这样的说明该怎么调用?谢谢!
type mychar=array[0..31] of char;
type TDiskID32=Function(var DiskModel,DiskID:mychar):BOOL;stdcall;请问,这样的说明该怎么调用?谢谢!
解决方案 »
- delphi2007可不可以使用indy9.0
- 我想做一个视频的广播,就是我在服务器上播放一个视频文件而在客户端上也同样的播放,能时现吗?
- 面向对象的数据库高手:我以下的做法是面向对象的数据库操作吗?
- ClientDataSet 的字段都是程序生成的,怎么生成一个计算字段(CalcFields)呢?
- 求学校教务及学生学籍管理系统的设计方案和资料!分可在加!!
- 急!急!急!大伙快帮帮我吧
- SQL Server和ADO的连接问题,请大伙帮忙解决!
- 急!在线等待!高分相送!谁知道dbgrid某些事件?
- 请问怎样用SQL语句实现模糊查询?我用的是ADOQuey1.
- 用了好久的D7,刚装了个XE7,为什么运算速度还是D7上快
- 怎么样通过消息来关闭窗口?
- 用Qreport控件设计报表。用qrshape控件画线条!为什么用激光打印时线条很模糊?
可以用pchar来输出
var
dk:TDiskID32;
mc:mychar;
begin
dk(mc,mc);
showmessage(mc);
//这样会出错的.
end;cooling(cooling) :可不可以帮我写段代码?我不太懂啊.谢谢
type
MyChar = array[0..31] of char;
TDiskID32 = function(var DiskModel, DiskID: MyChar): BOOL; stdcall;//随便一个过程内const
cDiskID32 = 'DiskID32.dll';
var
LibHandle: THandle;
aDiskModal, aDiskID: MyChar;
GetID: TDiskID32;
begin
LibHandle := LoadLibrary(cDiskID32);
@GetID := GetProcAddress(LibHandle, 'DiskID32');
GetID(aDiskModal, aDiskID);
Showmessage(aDiskModal + aDiskID);
FreeLibrary(LibHandle);
end;
cDiskID32 = 'DiskID32.dll';
type
MyChar = array[0..31] of char;function DiskID32(var DiskModel, DiskID: MyChar): BOOL; stdcall;//implementation关键字内implementationfunction DiskID32; external cDiskID32 name 'DiskID32';//然后随便一个过程var
aDiskModal, aDiskID: MyChar;
begin
DiskID32(aDiskModal, aDiskID);
Showmessage(aDiskModal + aDiskID);
end;
unit hdsn;interfaceuses
Windows,SysUtils;function getIDEHardDiskSN: string;
type
{*******Use in Win2k ****************}
TSrbIoControl = packed record
HeaderLength: ULONG;
Signature: array[0..7] of Char;
Timeout: ULONG;
ControlCode: ULONG;
ReturnCode: ULONG;
Length: ULONG;
end;
SRB_IO_CONTROL = TSrbIoControl;
PSrbIoControl = ^TSrbIoControl;TIDERegs = packed record
bFeaturesReg: Byte; // Used for specifying SMART "commands".
bSectorCountReg: Byte; // IDE sector count register
bSectorNumberReg: Byte; // IDE sector number register
bCylLowReg: Byte; // IDE low order cylinder value
bCylHighReg: Byte; // IDE high order cylinder value
bDriveHeadReg: Byte; // IDE drive/head register
bCommandReg: Byte; // Actual IDE command.
bReserved: Byte; // reserved. Must be zero.
end;
IDEREGS = TIDERegs;
PIDERegs = ^TIDERegs;TSendCmdInParams = packed record
cBufferSize: DWORD;
irDriveRegs: TIDERegs;
bDriveNumber: Byte;
bReserved: array[0..2] of Byte;
dwReserved: array[0..3] of DWORD;
bBuffer: array[0..0] of Byte;
end;
SENDCMDINPARAMS = TSendCmdInParams;
PSendCmdInParams = ^TSendCmdInParams;TIdSector = packed record
wGenConfig: Word;
wNumCyls: Word;
wReserved: Word;
wNumHeads: Word;
wBytesPerTrack: Word;
wBytesPerSector: Word;
wSectorsPerTrack: Word;
wVendorUnique: array[0..2] of Word;
sSerialNumber: array[0..19] of Char;
wBufferType: Word;
wBufferSize: Word;
wECCSize: Word;
sFirmwareRev: array[0..7] of Char;
sModelNumber: array[0..39] of Char;
wMoreVendorUnique: Word;
wDoubleWordIO: Word;
wCapabilities: Word;
wReserved1: Word;
wPIOTiming: Word;
wDMATiming: Word;
wBS: Word;
wNumCurrentCyls: Word;
wNumCurrentHeads: Word;
wNumCurrentSectorsPerTrack: Word;
ulCurrentSectorCapacity: ULONG;
wMultSectorStuff: Word;
ulTotalAddressableSectors: ULONG;
wSingleWordDMA: Word;
wMultiWordDMA: Word;
bReserved: array[0..127] of Byte;
end;
PIdSector = ^TIdSector;{************end Win2k*****************}const
{********** Use in Win2k **********}
IDE_ID_FUNCTION = $EC;
IDENTIFY_BUFFER_SIZE = 512;
DFP_RECEIVE_DRIVE_DATA = $0007C088;
IOCTL_SCSI_MINIPORT = $0004D008;
IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;
DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;
BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;
W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;
{********* End Win2k***************}{********* Use in Win9x ***********}
hookexceptionno = 5;
{********* End in Win9x************}var{********* Use in Win9x ***********}
pw: array[0..255] of Word; // pw[256];
idtr_1: array[0..5] of Byte; //保存中断描述符表寄存器
oldexceptionhook: DWord; //保存原先的中断入口地址
IdeBase: Word;
SelectDisk: Integer;
ErrNo: Integer = 0;
{********* End in Win9x************}implementation{********* Use in Win9x ***********}function inp(rdx: Word): Byte;
asm
mov dx, rdx
in al, dx
end;function inpw(rdx: Word): Word;
asm
mov dx, rdx
in ax, dx
end;procedure outp(ral: Byte; rdx: Word);
asm
mov dx, rdx
mov al, ral
out dx, al
end;function WaitIde: Byte;
var
al: Byte;
begin
repeat
al := inp(IdeBase + 7);
until (al < $80) or (al = $A0); //$a0可能就没有硬盘
WaitIde := al;
end;procedure ReadIDE;
var
al: Byte;
i: Integer;
begin
WaitIde;
outp(SelectDisk, IdeBase + 6);
al := WaitIde;
if ((al and $50) <> $50) then
begin
ErrNo := 1;
exit;
end;
outp(SelectDisk, IdeBase + 6);
outp($EC, IdeBase + 7);
al := WaitIde;
if ((al and $58) <> $58) then
begin
ErrNo := 2;
exit;
end;
for i := 0 to 255 do
begin
pw[i] := inpw(IdeBase);
end;
end;// 新的中断处理程序procedure ReadIt; assembler;
asm
push eax
push ebx
push ecx
push edx
push esi
push edi
// 在这里写读程序
call ReadIDE
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
end;procedure GetSerialNo; assembler;
asm
push eax
// 获取修改的中断的中断描述符(中断门)地址
sidt idtr_1
mov eax,dword ptr idtr_1+02h
add eax,hookexceptionno*08h+04h
// 保存原先的中断入口地址
cli
push ecx
mov ecx,dword ptr [eax]
mov cx,word ptr [eax-04h]
mov dword ptr oldexceptionhook,ecx
pop ecx
// 设置修改的中断入口地址为新的中断处理程序入口地址
push ebx
lea ebx,ReadIt
mov word ptr [eax-04h],bx
shr ebx,10h
mov word ptr [eax+02h],bx
pop ebx
// 执行中断,转到ring 0(与cih 病毒原理相似!)
push ebx
int hookexceptionno
pop ebx
// 恢复原先的中断入口地址
push ecx
mov ecx,dword ptr oldexceptionhook
mov word ptr [eax-04h],cx
shr ecx,10h
mov word ptr [eax+02h],cx
pop ecx
// 结束
sti
pop eax
ret
end;procedure GetIdeDiskSN9X(DriverNo: integer; var s: string);
var
i: Integer;
begin
{如果有多硬盘一般可能有4个硬盘,也可能多至8个硬盘}
ErrNo := 0;
fillchar(pw, sizeof(pw), 0);
s := '';{设置基址,
4,5:IdeBase := $1e8;
6,7:IdeBase := $168;}
case DriverNo of
0, 1: IdeBase := $1F0;
2, 3: IdeBase := $170;
end;{ 指定主从,Driver No 是奇数为$B0,偶数为$A0}
case DriverNo of
0, 2: SelectDisk := $A0;
1, 3: SelectDisk := $B0;
end; GetSerialNo;
if ErrNo <> 0 then
Exit; //读错误
if (pw[0] = 0) then
s := ''
else
for i := 10 to 20 do
begin
s := s + char(pw[i] shr 8) + char(pw[i] and $FF);
end;
end;
{********* End in Win9x************}{*******Use in Win2k ****************}procedure ChangeByteOrder(var Data; Size: Integer);
var
ptr: PChar;
i: Integer;
c: Char;
begin
ptr := @Data;
for i := 0 to (Size shr 1) - 1 do
begin
c := ptr^;
ptr^ := (ptr + 1)^;
(ptr + 1)^ := c;
Inc(ptr, 2);
end;
end;
{ Windows NT, Windows 2000
通过MS的S.M.A.R.T.接口,直接从RING3调用
API DeviceIoControl()来获取硬盘信息
Get SCSI port handle}function GetIdeDiskSNNT: string;
var
hDevice: THandle;
cbBytesReturned: DWORD;
pInData: PSendCmdInParams;
pOutData: Pointer; // PSendCmdOutParams
Buffer: array[0..BufferSize - 1] of Byte;
srbControl: TSrbIoControl absolute Buffer;
begin
Result := '';
FillChar(Buffer, BufferSize, #0); hDevice := CreateFile('\.Scsi0:', 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
srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
System.Move('SCSIDISK', srbControl.Signature, 8);
srbControl.Timeout := 2;
srbControl.Length := DataSize;
srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
pInData := PSendCmdInParams(PChar(@Buffer) + SizeOf(SRB_IO_CONTROL));
pOutData := pInData;
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, IOCTL_SCSI_MINIPORT, @Buffer, BufferSize,
@Buffer, BufferSize, cbBytesReturned, nil) then
Exit;
finally
CloseHandle(hDevice);
end; with PIdSector(PChar(pOutData) + 16)^ do
begin
ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
SetString(Result, sSerialNumber, SizeOf(sSerialNumber));
end;
Result := Trim(Result);
end;
{********* End in Win2k************}function getIDEHardDiskSN: string;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
Result := getIDEDiskSNNT
else if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
getIDEDiskSN9x(0, Result)
else
Result := '';
end;end.