如何读取SCSI硬盘的SerialNumber 如何读取SCSI硬盘的SerialNumber 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 {$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 := ''; 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( DeviceHandle, $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; //============================================================= var hDevice : THandle = 0; sSerNum, sDeviceName : String; begin sDeviceName := ParamStr(1); 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 := GetDeviceHandle(sDeviceName); if hDevice=INVALID_HANDLE_VALUE then WriteLn('Error on GetDeviceHandle: ',SysErrorMessage(GetLastError)) else try sSerNum := ScsiHddSerialNumber(hDevice); if sSerNum='' then WriteLn('Error on DeviceIoControl: ', SysErrorMessageGetLastError)) else WriteLn('Device '+sDeviceName +' serial number = "',sSerNum,'"'); finally CloseHandle(hDevice); end; end. to hongqi162(失踪的月亮) : 为什么必须Project1.exe C:呢,Project1.exe D:的时候报错,不能自动获取吗 delphi 7 fastreport 3.0使用 CHART的问题 做过gis车辆监控的请进来看一下 当点击 listview 某行前面的checkbox 给该行打勾时,发生什么事件? QQ的数据库文件:QQwry.dat 怎样编写以特定的Windows帐户运行的程序 Delphi中与VB的DoEvents相对应的是哪个? 如何连接同一数据库中不同用户所属的表? 找一个随机数生成算法吧,急用!!!谢谢各位大侠了先!!!!最好delphi的呀! 有关window状态区的编程 有关打印的问题 怎样在程序中动态添加/删除数据库字段?(Delphi) 关于自动填写网页编辑框
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 := '';
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( DeviceHandle, $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;
//=============================================================
var
hDevice : THandle = 0;
sSerNum, sDeviceName : String;
begin
sDeviceName := ParamStr(1);
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 := GetDeviceHandle(sDeviceName);
if hDevice=INVALID_HANDLE_VALUE then
WriteLn('Error on GetDeviceHandle: ',SysErrorMessage(GetLastError))
else
try
sSerNum := ScsiHddSerialNumber(hDevice);
if sSerNum='' then
WriteLn('Error on DeviceIoControl: ',
SysErrorMessageGetLastError))
else
WriteLn('Device '+sDeviceName
+' serial number = "',sSerNum,'"');
finally
CloseHandle(hDevice);
end;
end.
为什么必须Project1.exe C:呢,Project1.exe D:的时候报错,不能自动获取吗