//(2)取 SCSI 硬盘序列号
function TForm1.GetSCSISerialNumber : String;
{$ALIGN ON}
type
TScsiPassThrough = record
Length : Word;
ScsiStatus : Byte;
PathId : Byte;
TargetId : Byte;
Lun : Byte;
CdbLength : Byte;
SenseInfoLength : Byte;
DataIn : Byte;
DataTransferLength : ULONG;
TimeOutValue : ULONG;
DataBufferOffset : DWORD;
SenseInfoOffset : ULONG;
Cdb : Array[0..15] of Byte;
end;
TScsiPassThroughWithBuffers = record
spt : TScsiPassThrough;
bSenseBuf : Array[0..31] of Byte;
bDataBuf : Array[0..191] of Byte;
end;
{ALIGN OFF}
var hDevice : THandle;
dwReturned : DWORD;
len : DWORD;
Buffer : Array[0..255] of Byte;
sptwb : TScsiPassThroughWithBuffers absolute Buffer;
begin
Result := '';
hDevice := CreateFile( PChar('\\.\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;
FillChar(Buffer,SizeOf(Buffer),#0);
with sptwb.spt do
begin
Length := SizeOf(TScsiPassThrough);
CdbLength := 6; // CDB6GENERIC_LENGTH
SenseInfoLength := 24;
DataIn := 1; // SCSI_IOCTL_DATA_IN
DataTransferLength := 192;
TimeOutValue := 2;
DataBufferOffset := PChar(@sptwb.bDataBuf)-PChar(@sptwb);
SenseInfoOffset := PChar(@sptwb.bSenseBuf)-PChar(@sptwb);
Cdb[0] := $12; // OperationCode := SCSIOP_INQUIRY;
Cdb[1] := $01; // Flags := CDB_INQUIRY_EVPD; Vital product data
Cdb[2] := $80; // PageCode Unit serial number
Cdb[4] := 192; // AllocationLength
end;
len := sptwb.spt.DataBufferOffset+sptwb.spt.DataTransferLength;
if DeviceIoControl( hDevice, $0004d004, @sptwb, SizeOf(TScsiPassThrough), @sptwb, len, dwReturned, nil )
and ((PChar(@sptwb.bDataBuf)+1)^=#$80)
then
SetString( Result, PChar(@sptwb.bDataBuf)+4,
Ord((PChar(@sptwb.bDataBuf)+3)^) );
end;
//(3)取 第一分区(C:\) 序列号
function TForm1.GetVolumeSerialNumber : string;
var
i,j:integer;
SerialNum : dword;
a, b : Dword;
Buffer1: array [0..255] of char; //缓冲区
begin
// 取第一分区盘符
GetSystemDirectory(Buffer1,sizeof(Buffer1));
for i := 0 to 255 do
if Buffer1[i] = ':' then
begin
break ;
end;
for j := i+2 to 255 do
Buffer1[j] := #0;
//取 第一分区(C:\) 序列号
if GetVolumeInformation(Buffer1, nil, 0, @SerialNum, b, a, nil, 0) then
result:= IntToStr(SerialNum)
else result:='' ;
end;
//(4)调用 (取 IDE 硬盘序列号 见 http://www.cnblogs.com/luckyjan/articles/70558.html)
function TForm1.getHDDSerialNumber : string;
var SN:string;
begin
SN := GetIDESerialNumber; //取 IDE 硬盘序列号
if SN='' then SN := GetSCSISerialNumber; //取 SCSI 硬盘序列号
if SN='' then SN := GetVolumeSerialNumber; //取 第一分区(C:\) 序列号
end;

浙公网安备 33010602011771号