如何读取SCSI硬盘的SerialNumber

解决方案 »

  1.   

      {$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.
      

  2.   

    to  hongqi162(失踪的月亮) :
      为什么必须Project1.exe C:呢,Project1.exe D:的时候报错,不能自动获取吗