如何判断当前硬盘是IDE硬盘还是SCSI硬盘,并获得磁盘序列号(在线等待)? 如何判断当前硬盘是IDE硬盘还是SCSI硬盘,并获得磁盘序列号(在线等待)? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 查查好象有这样的api函数 给几个函数你,判断IDE还是SCSI我就不知道了!unit my_utility;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Dialogs, StdCtrls, WinTypes, WinProcs, Forms, DB, ComObj, StrUtils;const ID_BIT = $200000;type TCPUID = array[1..4] of Longint; //存放CPU编号的数组 TVendor = array [0..11] of char;{ ======== CPU ID 专用变量 ========== 说明:对586以上机器的CPU都有1至4组编号,通常第3组和第4组编号是唯一的 所以,可利用此编号来给程序定义注册码}function IsCPUID_Available : BOOLEAN; register; //是否可获得CPU编号function GetCPUID : TCPUID; assembler; register; //获得CPU的编号function GetCPUVendor : TVendor; assembler; register; //获得CPU的制造商implementationfunction IsCPUID_Available : BOOLEAN; register;asm PUSHFD POP EAX MOV EDX,EAX XOR EAX,ID_BIT PUSH EAX POPFD PUSHFD POP EAX XOR EAX,EDX JZ @exit MOV AL,TRUE @exit:end;function GetCPUID : TCPUID; assembler; register;asm PUSH EBX PUSH EDI MOV EDI,EAX MOV EAX,1 DW $A20F {CPUID Command} STOSD {CPUID[1]} MOV EAX,EBX STOSD {CPUID[2]} MOV EAX,ECX STOSD {CPUID[3]} MOV EAX,EDX STOSD {CPUID[4]} POP EDI POP EBXend;function GetCPUVendor : TVendor; assembler; register;asm PUSH EBX PUSH EDI MOV EDI,EAX MOV EAX,0 DW $A20F MOV EAX,EBX XCHG EBX,ECX MOV ECX,4@1: STOSB SHR EAX,8 LOOP @1 MOV EAX,EDX MOV ECX,4@2: STOSB SHR EAX,8 LOOP @2 MOV EAX,EBX MOV ECX,4@3: STOSB SHR EAX,8 LOOP @3 POP EDI {Restore registers} POP EBXend; http://www.ahong.net/download/diskinfo.rar试试。 用VC编写的DLL,可以获得硬盘的型号、序列号以及计算机 ID,带Delphi的源程序:http://www.applevb.com/lib/diskio.rar 想得到卷标用GetVolumeInformation.下面方法可以准确的得到硬盘的型号和生产序列号等参数!function GetIdeDiskSerialNumber(var SerialNumber: string; var ModelNumber: string; var FirmwareRev: string; var TotalAddressableSectors: ULong; var SectorCapacity: ULong; var SectorsPerTrack: Word): Boolean; //得到硬盘物理号type 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;const 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;var hDevice: THandle; cbBytesReturned: DWORD; pInData: PSendCmdInParams; pOutData: Pointer; // PSendCmdOutParams Buffer: array[0..BufferSize - 1] of Byte; srbControl: TSrbIoControl absolute Buffer; 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;begin Result := False; FillChar(Buffer, BufferSize, #0); if Win32Platform = VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000// Get SCSI port handle 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; end else begin // Windows 95 OSR2, Windows 98 hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 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 Exit; finally CloseHandle(hDevice); end; end; with PIdSector(PChar(pOutData) + 16)^ do begin ChangeByteOrder(sSerialNumber, sizeof(sSerialNumber)); SetString(SerialNumber, sSerialNumber, sizeof(sSerialNumber)); //硬盘生产序号 ChangeByteOrder(sModelNumber, sizeof(sModelNumber)); SetString(ModelNumber, sModelNumber, sizeof(sModelNumber)); //硬盘型号 ChangeByteOrder(sFirmwareRev, sizeof(sFirmwareRev)); SetString(FirmwareRev, sFirmwareRev, sizeof(sFirmwareRev)); //硬盘硬件版本 Result := True; ChangeByteOrder(ulTotalAddressableSectors, sizeof(ulTotalAddressableSectors)); TotalAddressableSectors := ulTotalAddressableSectors; //硬盘ulTotalAddressableSectors参数 ChangeByteOrder(ulCurrentSectorCapacity, sizeof(ulCurrentSectorCapacity)); SectorCapacity := ulCurrentSectorCapacity; //硬盘wBytesPerSector参数 ChangeByteOrder(wNumCurrentSectorsPerTrack, sizeof(wNumCurrentSectorsPerTrack)); SectorsPerTrack := wNumCurrentSectorsPerTrack; //硬盘wSectorsPerTrack参数 end;end;---------------------------------如果硬盘有多个的话,修改里面的参数就可以查出第二、第三个硬盘的型号、ID等参数。 引用如:procedure TForm1.BitBtn1Click(Sender: TObject);var S1, S2, S3: string; W5: Word; W4, W3: ULong;begin GetIdeDiskSerialNumber(S1, S2, S3, W3, W4, W5); Label1.Caption := '序列号:' + S1; Label2.Caption := '硬盘型号:' + S2; Label3.Caption := '硬件版本:' + S3; Label6.Caption := 'TotalAddressableSectors:' + inttostr(W3); Label7.Caption := 'SectorCapacity:' + inttostr(W4); Label8.Caption := 'SectorsPerTrack:' + inttostr(W5);end; ide的硬盘倒是可以获得序列号,但SCSI就不行。有没有方法呀? 高手进:线程函数传两个参数 发个比晚帖 -_-||| 急,寻求帮助从数据库中读取数据库文件???? ■■如何做到拖动图像控件,FORM也跟着移动???■■ 哎呀,本想明天升星的,庆祝建党83周年。那我就预祝吧。呵呵,大家帮忙接分咯! 有关操作dbgird的问题,请帮忙 String长度有限制吗? 请教关于delphi与sqlserver数据库连i接的一个问题 delphi7.0中DBchart如何代码设置线的粗细? 如何断开modem拨号连接 面向对象初级问题,高分在线急等 Inforpower的wwDBGrid记录保存问题 ?
好象有这样的api函数
unit my_utility;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Dialogs,
StdCtrls, WinTypes, WinProcs, Forms, DB, ComObj, StrUtils;
const
ID_BIT = $200000;
type
TCPUID = array[1..4] of Longint; //存放CPU编号的数组
TVendor = array [0..11] of char;
{
======== CPU ID 专用变量 ==========
说明:对586以上机器的CPU都有1至4组编号,通常第3组和第4组编号是唯一的
所以,可利用此编号来给程序定义注册码
}
function IsCPUID_Available : BOOLEAN; register; //是否可获得CPU编号
function GetCPUID : TCPUID; assembler; register; //获得CPU的编号
function GetCPUVendor : TVendor; assembler; register; //获得CPU的制造商implementationfunction IsCPUID_Available : BOOLEAN; register;
asm
PUSHFD
POP EAX
MOV EDX,EAX
XOR EAX,ID_BIT
PUSH EAX
POPFD
PUSHFD
POP EAX
XOR EAX,EDX
JZ @exit
MOV AL,TRUE
@exit:
end;function GetCPUID : TCPUID; assembler; register;
asm
PUSH EBX
PUSH EDI
MOV EDI,EAX
MOV EAX,1
DW $A20F {CPUID Command}
STOSD {CPUID[1]}
MOV EAX,EBX
STOSD {CPUID[2]}
MOV EAX,ECX
STOSD {CPUID[3]}
MOV EAX,EDX
STOSD {CPUID[4]}
POP EDI
POP EBX
end;function GetCPUVendor : TVendor; assembler; register;
asm
PUSH EBX
PUSH EDI
MOV EDI,EAX
MOV EAX,0
DW $A20F
MOV EAX,EBX
XCHG EBX,ECX
MOV ECX,4
@1:
STOSB
SHR EAX,8
LOOP @1
MOV EAX,EDX
MOV ECX,4
@2:
STOSB
SHR EAX,8
LOOP @2
MOV EAX,EBX
MOV ECX,4
@3:
STOSB
SHR EAX,8
LOOP @3
POP EDI {Restore registers}
POP EBX
end;
下面方法可以准确的得到硬盘的型号和生产序列号等参数!
function GetIdeDiskSerialNumber(var SerialNumber: string; var ModelNumber: string;
var FirmwareRev: string; var TotalAddressableSectors: ULong;
var SectorCapacity: ULong; var SectorsPerTrack: Word): Boolean; //得到硬盘物理号
type
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;const
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;
var
hDevice: THandle;
cbBytesReturned: DWORD;
pInData: PSendCmdInParams;
pOutData: Pointer; // PSendCmdOutParams
Buffer: array[0..BufferSize - 1] of Byte;
srbControl: TSrbIoControl absolute Buffer; 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;begin
Result := False;
FillChar(Buffer, BufferSize, #0);
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin // Windows NT, Windows 2000
// Get SCSI port handle
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;
end
else
begin // Windows 95 OSR2, Windows 98
hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil,
CREATE_NEW, 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 Exit;
finally
CloseHandle(hDevice);
end;
end;
with PIdSector(PChar(pOutData) + 16)^ do
begin
ChangeByteOrder(sSerialNumber, sizeof(sSerialNumber));
SetString(SerialNumber, sSerialNumber, sizeof(sSerialNumber)); //硬盘生产序号 ChangeByteOrder(sModelNumber, sizeof(sModelNumber));
SetString(ModelNumber, sModelNumber, sizeof(sModelNumber)); //硬盘型号 ChangeByteOrder(sFirmwareRev, sizeof(sFirmwareRev));
SetString(FirmwareRev, sFirmwareRev, sizeof(sFirmwareRev)); //硬盘硬件版本
Result := True;
ChangeByteOrder(ulTotalAddressableSectors, sizeof(ulTotalAddressableSectors));
TotalAddressableSectors := ulTotalAddressableSectors; //硬盘ulTotalAddressableSectors参数 ChangeByteOrder(ulCurrentSectorCapacity, sizeof(ulCurrentSectorCapacity));
SectorCapacity := ulCurrentSectorCapacity; //硬盘wBytesPerSector参数 ChangeByteOrder(wNumCurrentSectorsPerTrack, sizeof(wNumCurrentSectorsPerTrack));
SectorsPerTrack := wNumCurrentSectorsPerTrack; //硬盘wSectorsPerTrack参数
end;
end;
---------------------------------
如果硬盘有多个的话,修改里面的参数就可以查出第二、第三个硬盘的型号、ID等参数。
引用如:
procedure TForm1.BitBtn1Click(Sender: TObject);
var
S1, S2, S3: string;
W5: Word;
W4, W3: ULong;
begin
GetIdeDiskSerialNumber(S1, S2, S3, W3, W4, W5);
Label1.Caption := '序列号:' + S1;
Label2.Caption := '硬盘型号:' + S2;
Label3.Caption := '硬件版本:' + S3;
Label6.Caption := 'TotalAddressableSectors:' + inttostr(W3);
Label7.Caption := 'SectorCapacity:' + inttostr(W4);
Label8.Caption := 'SectorsPerTrack:' + inttostr(W5);
end;