如何取得本机的硬盘序列号?(100分)

  • 主题发起人 主题发起人 bumpiness
  • 开始时间 开始时间
B

bumpiness

Unregistered / Unconfirmed
GUEST, unregistred user!
如何取得本机的硬盘序列号?[?][?]
 
对于IDE硬盘,你可以使用S.M.A.R.T. API的函数来获取序列号。但对SCSI硬盘,它无法工作。<br>但可以使用DeviceIoControl来获取DeviceIoControl设备序列号. &nbsp;<br><br><br>program ScsiSN;<br><br>&nbsp;<br><br>&nbsp; // 目的:简单的控制台程序来显示SCSI硬盘的序列号<br><br>&nbsp;<br><br>&nbsp; {$APPTYPE CONSOLE}<br><br>&nbsp;<br><br>&nbsp; uses<br><br>&nbsp; Windows, SysUtils;<br><br>&nbsp;<br><br>&nbsp; //-------------------------------------------------------------<br><br>&nbsp; function GetDeviceHandle( sDeviceName : String ) : THandle;<br><br>&nbsp; begin<br><br>&nbsp; Result := CreateFile( PChar('//./'+sDeviceName),<br><br>&nbsp; GENERIC_READ or GENERIC_WRITE,<br><br>&nbsp; FILE_SHARE_READ or FILE_SHARE_WRITE,<br><br>&nbsp; nil, OPEN_EXISTING, 0, 0 )<br><br>&nbsp; end;<br><br>&nbsp;<br><br>&nbsp; //-------------------------------------------------------------<br><br>&nbsp; function ScsiHddSerialNumber( DeviceHandle : THandle ) : String;<br><br>&nbsp; {$ALIGN ON}<br><br>&nbsp; type<br><br>&nbsp; TScsiPassThrough = record<br><br>&nbsp; Length : Word;<br><br>&nbsp; ScsiStatus : Byte;<br><br>&nbsp; PathId : Byte;<br><br>&nbsp; TargetId : Byte;<br><br>&nbsp; Lun : Byte;<br><br>&nbsp; CdbLength : Byte;<br><br>&nbsp; SenseInfoLength : Byte;<br><br>&nbsp; DataIn : Byte;<br><br>&nbsp; DataTransferLength : ULONG;<br><br>&nbsp; TimeOutValue : ULONG;<br><br>&nbsp; DataBufferOffset : DWORD;<br><br>&nbsp; SenseInfoOffset : ULONG;<br><br>&nbsp; Cdb : Array[0..15] of Byte;<br><br>&nbsp; end;<br><br>&nbsp; TScsiPassThroughWithBuffers = record<br><br>&nbsp; spt : TScsiPassThrough;<br><br>&nbsp; bSenseBuf : Array[0..31] of Byte;<br><br>&nbsp; bDataBuf : Array[0..191] of Byte;<br><br>&nbsp; end;<br><br>&nbsp; {ALIGN OFF}<br><br>&nbsp; var dwReturned : DWORD;<br><br>&nbsp; len : DWORD;<br><br>&nbsp; Buffer : Array[0..255] of Byte;<br><br>&nbsp; sptwb : TScsiPassThroughWithBuffers absolute Buffer;<br><br>&nbsp; begin<br><br>&nbsp; Result := '';<br><br>&nbsp; FillChar(Buffer,SizeOf(Buffer),#0);<br><br>&nbsp; with sptwb.spt do<br><br>&nbsp; begin<br><br>&nbsp; Length := SizeOf(TScsiPassThrough);<br><br>&nbsp; CdbLength := 6; // CDB6GENERIC_LENGTH<br><br>&nbsp; SenseInfoLength := 24;<br><br>&nbsp; DataIn := 1; // SCSI_IOCTL_DATA_IN<br><br>&nbsp; DataTransferLength := 192;<br><br>&nbsp; TimeOutValue := 2;<br><br>&nbsp; DataBufferOffset := PChar(@sptwb.bDataBuf)-PChar(@sptwb);<br><br>&nbsp; SenseInfoOffset := PChar(@sptwb.bSenseBuf)-PChar(@sptwb);<br><br>&nbsp; Cdb[0] := $12; // OperationCode := SCSIOP_INQUIRY;<br><br>&nbsp; Cdb[1] := $01; // Flags := CDB_INQUIRY_EVPD; Vital product data<br><br>&nbsp; Cdb[2] := $80; // PageCode Unit serial number<br><br>&nbsp; Cdb[4] := 192; // AllocationLength<br><br>&nbsp; end;<br><br>&nbsp; len := sptwb.spt.DataBufferOffset+sptwb.spt.DataTransferLength;<br><br>&nbsp; if DeviceIoControl( DeviceHandle, $0004d004, @sptwb, SizeOf(TScsiPassThrough), @sptwb, len, dwReturned, nil )<br><br>&nbsp; and ((PChar(@sptwb.bDataBuf)+1)^=#$80)<br><br>&nbsp; then<br><br>&nbsp; SetString( Result, PChar(@sptwb.bDataBuf)+4,<br><br>&nbsp; Ord((PChar(@sptwb.bDataBuf)+3)^) );<br><br>&nbsp; end;<br><br>&nbsp;<br><br>&nbsp;<br><br>&nbsp; //=============================================================<br><br>&nbsp; var<br><br>&nbsp; hDevice : THandle = 0;<br><br>&nbsp; sSerNum, sDeviceName : String;<br><br>&nbsp;<br><br>&nbsp; begin<br><br>&nbsp; sDeviceName := ParamStr(1);<br><br>&nbsp; if sDeviceName='' then<br><br>&nbsp; begin<br><br>&nbsp; WriteLn;<br><br>&nbsp; WriteLn('Display SCSI-2 device serial number.');<br><br>&nbsp; WriteLn;<br><br>&nbsp; WriteLn('Using:');<br><br>&nbsp; WriteLn;<br><br>&nbsp; if Win32Platform=VER_PLATFORM_WIN32_NT then // Windows NT/2000<br><br>&nbsp; WriteLn(' ScsiSN PhysicalDrive0')<br><br>&nbsp; else<br><br>&nbsp; WriteLn(' ScsiSN C:');<br><br>&nbsp; WriteLn(' ScsiSN Cdrom0');<br><br>&nbsp; WriteLn(' ScsiSN Tape0');<br><br>&nbsp; WriteLn;<br><br>&nbsp; Exit;<br><br>&nbsp; end;<br><br>&nbsp; hDevice := GetDeviceHandle(sDeviceName);<br><br>&nbsp; if hDevice=INVALID_HANDLE_VALUE then<br><br>&nbsp; WriteLn('Error on GetDeviceHandle: ',SysErrorMessage(GetLastError))<br><br>&nbsp; else<br><br>&nbsp; try<br><br>&nbsp; sSerNum := ScsiHddSerialNumber(hDevice);<br><br>&nbsp; if sSerNum='' then<br><br>&nbsp; WriteLn('Error on DeviceIoControl: ',<br><br>&nbsp; SysErrorMessageGetLastError))<br><br>&nbsp; else<br><br>&nbsp; WriteLn('Device '+sDeviceName<br><br>&nbsp; +' serial number = "',sSerNum,'"');<br><br>&nbsp; finally<br><br>&nbsp; CloseHandle(hDevice);<br><br>&nbsp; end;<br><br>&nbsp; end.<br>
 
Unit HardDisk; <br>INTERFACE <br>FUNCTION &nbsp;GetHardDiskNaam &nbsp;: STRING; <br>FUNCTION &nbsp;GetHardDiskSerieNummer &nbsp; &nbsp; &nbsp; &nbsp;: STRING; <br>FUNCTION &nbsp;GetHardDiskControlleNummer &nbsp; &nbsp;: STRING; <br>PROCEDURE GetHardDiskGegevens; <br>CONST <br>&nbsp; CodeerTabel : ARRAY[0..24] OF BYTE = <br>(3,1,2,1,4,1,3,2,6,4,6,5,1,2,6,4,2,6,3,4,6,2,4,1,2); <br>TYPE <br>&nbsp; CharArray = ARRAY[0..24] OF CHAR; <br>VAR <br>&nbsp; HardDiskGegevens : ARRAY[1..256] OF INTEGER; <br>&nbsp; HardDiskNaam &nbsp;: CharArray; <br>&nbsp; SerieNummer &nbsp;: CharArray; <br>&nbsp; ControlleNummer : CharArray; <br>&nbsp; C_HardDiskNaam: STRING; <br>&nbsp; C_HardDiskSerieNummer : STRING; <br>&nbsp; C_HardDiskControlleNummer : STRING; <br>&nbsp; C_LicentieNaam: STRING; <br>IMPLEMENTATION <br>FUNCTION GetHardDiskNaam : STRING; <br>VAR <br>&nbsp; Teller : INTEGER; <br>&nbsp; Lus : INTEGER; <br>BEGIN <br>&nbsp; &nbsp; GetHardDiskNaam := ''; <br>&nbsp; &nbsp; Teller := 1; <br>&nbsp; &nbsp; FOR Lus := 1 TO 18 DO <br>&nbsp; &nbsp; BEGIN <br>&nbsp; &nbsp; &nbsp; HardDiskNaam[Teller] := CHR( ( HardDiskGegevens[27+Lus] DIV 256 )); <br>&nbsp; &nbsp; &nbsp; Inc(Teller); <br>&nbsp; &nbsp; &nbsp; HardDiskNaam[Teller] := CHR( ( HardDiskGegevens[27+Lus] MOD 256 )); <br>&nbsp; &nbsp; &nbsp; Inc(Teller); <br>&nbsp; &nbsp; END; <br>&nbsp; &nbsp; GetHardDiskNaam := HardDiskNaam; <br>END; <br>FUNCTION GetHardDiskSerieNummer : STRING; <br>VAR <br>&nbsp; Teller : INTEGER; <br>&nbsp; Lus : INTEGER; <br>BEGIN <br>&nbsp; &nbsp; GetHardDiskSerieNummer := ''; <br>&nbsp; &nbsp; Teller := 1; <br>&nbsp; &nbsp; FOR Lus := 1 TO 8 DO <br>&nbsp; &nbsp; BEGIN <br>&nbsp; &nbsp; &nbsp; SerieNummer[Teller] := CHR( ( HardDiskGegevens[10+Lus] DIV 256 )); <br>&nbsp; &nbsp; &nbsp; Inc(Teller); <br>&nbsp; &nbsp; &nbsp; SerieNummer[Teller] := CHR( ( HardDiskGegevens[10+Lus] MOD 256 )); <br>&nbsp; &nbsp; &nbsp; Inc(Teller); <br>&nbsp; &nbsp; END; <br>&nbsp; &nbsp; GetHardDiskSerieNummer := SerieNummer; <br>END; <br>FUNCTION GetHardDiskControlleNummer : STRING; <br>VAR <br>&nbsp; Teller : INTEGER; <br>&nbsp; Lus &nbsp; &nbsp;: INTEGER; <br>BEGIN <br>&nbsp; &nbsp; GetHardDiskControlleNummer := ''; <br>&nbsp; &nbsp; Teller := 1; <br>&nbsp; &nbsp; FOR Lus := 1 TO 3 DO <br>&nbsp; &nbsp; BEGIN <br>&nbsp; &nbsp; &nbsp; ControlleNummer[Teller] := CHR( ( HardDiskGegevens[23+Lus] DIV 256 )); <br>&nbsp; &nbsp; &nbsp; Inc(Teller); <br>&nbsp; &nbsp; &nbsp; ControlleNummer[Teller] := CHR( ( HardDiskGegevens[23+Lus] MOD 256 )); <br>&nbsp; &nbsp; &nbsp; Inc(Teller); <br>&nbsp; &nbsp; END; <br>&nbsp; &nbsp; GetHardDiskControlleNummer := ControlleNummer; <br>END; <br>PROCEDURE GetHardDiskGegevens; <br>VAR <br>&nbsp; Lus &nbsp; &nbsp;: INTEGER; <br>BEGIN <br>&nbsp; WHILE ( Port[$1f7] &lt;&gt; $50) DO ; <br>&nbsp; Port[$1F6] := $A0 ; <br>&nbsp; Port[$1F7] := $EC ; <br>&nbsp; WHILE ( Port[$1f7] &lt;&gt; $58 ) DO ; <br>&nbsp; FOR Lus := 1 TO 256 DO <br>&nbsp; BEGIN <br>&nbsp; &nbsp; HardDiskGegevens[Lus] := Portw[$1F0] ; <br>&nbsp; END; <br>END; <br>END. <br><br>
 
var<br>&nbsp; SerialNum : pdword;<br>&nbsp; a, b : dword;<br>&nbsp; Buffer &nbsp;: array [0..255] of char;<br>begin<br>&nbsp; if GetVolumeInformation('c:/', Buffer, SizeOf(Buffer), SerialNum, a, b, nil, 0) then<br>&nbsp; &nbsp; Label1.Caption := IntToStr(SerialNum^);<br>end;
 
多人接受答案了。
 
后退
顶部