program ScsiSN;
// 目的:简单的控制台程序来显示SCSI硬盘的序列号
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
//————————————————————-
function GetDeviceHandle sDeviceName : String ) : THandle;
begin
Result := CreateFile PChar’\\.\’+sDeviceName),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0 )
end;
//————————————————————-
function ScsiHddSerialNumber DeviceHandle : THandle ) : 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 dwReturned : DWORD;
len : DWORD;
Buffer : Array[0..255] of Byte;
sptwb : TScsiPassThroughWithBuffers absolute Buffer;
begin
Result := ”;
FillCharBuffer,SizeOfBuffer),#0);
with sptwb.spt do
begin
Length := SizeOfTScsiPassThrough);
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 DeviceHandle, $0004d004, @sptwb, SizeOfTScsiPassThrough), @sptwb, len, dwReturned, nil )
and PChar@sptwb.bDataBuf)+1)^=#$80)
then
SetString Result, PChar@sptwb.bDataBuf)+4,
OrdPChar@sptwb.bDataBuf)+3)^) );
end;
//=============================================================
var
hDevice : THandle = 0;
sSerNum, sDeviceName : String;
begin
sDeviceName := ParamStr1);
if sDeviceName=” then
begin
WriteLn;
WriteLn’Display SCSI-2 device serial number.’);
WriteLn;
WriteLn’Using:’);
WriteLn;
if Win32Platform=VER_PLATFORM_WIN32_NT then // Windows NT/2000
WriteLn’ ScsiSN PhysicalDrive0′)
else
WriteLn’ ScsiSN C:’);
WriteLn’ ScsiSN Cdrom0′);
WriteLn’ ScsiSN Tape0′);
WriteLn;
Exit;
end;
hDevice := GetDeviceHandlesDeviceName);
if hDevice=INVALID_HANDLE_VALUE then
WriteLn’Error on GetDeviceHandle: ‘,SysErrorMessageGetLastError))
else
try
sSerNum := ScsiHddSerialNumberhDevice);
if sSerNum=” then
WriteLn’Error on DeviceIoControl: ‘,
SysErrorMessageGetLastError))
else
WriteLn’Device ‘+sDeviceName
+’ serial number = “‘,sSerNum,'”‘);
finally
CloseHandlehDevice);
end;
end.