有提取SCSI硬盘序列号的源码吗?

解决方案 »

  1.   


    var
         VolumeSerialNumber : DWORD;
         MaximumComponentLength : DWORD;
         FileSystemFlags : DWORD;
    begin
         GetVolumeInformation('c:\',nil,0,@VolumeSerialNumber,MaximumComponentLength,FileSystemFlags,nil,0);
         showmessage(inttostr(Volumeserialnumber));
    end;
      

  2.   

    用这个函数包用
    function GetIdeDiskSerialNumber(ScsiID:integer): string;  //硬盘ID号
    type
      TSrbIoControl = packed record
        HeaderLength: ULONG;
        Signature: array[0..7] of Char;
        Timeout: ULONG;
        ControlCode: ULONG;
        ReturnCode: ULONG;
        Length: ULONG;
      end;
      SRB_IO_CONTROL = TSrbIoControl;
      PSrbIoControl = ^TSrbIoControl;
      TIDERegs = packed record
        bFeaturesReg: Byte; // Used for specifying SMART "commands".
        bSectorCountReg: Byte; // IDE sector count register
        bSectorNumberReg: Byte; // IDE sector number register
        bCylLowReg: Byte; // IDE low order cylinder value
        bCylHighReg: Byte; // IDE high order cylinder value
        bDriveHeadReg: Byte; // IDE drive/head register
        bCommandReg: Byte; // Actual IDE command.
        bReserved: Byte; // reserved for future use.  Must be zero.
      end;
      IDEREGS = TIDERegs;
      PIDERegs = ^TIDERegs;
      TSendCmdInParams = packed record
        cBufferSize: DWORD; // Buffer size in bytes
        irDriveRegs: TIDERegs; // Structure with drive register values.
        bDriveNumber: Byte; // Physical drive number to send command to (0,1,2,3).
        bReserved: array[0..2] of Byte; // Reserved for future expansion.
        dwReserved: array[0..3] of DWORD; // For future use.
        bBuffer: array[0..0] of Byte; // Input buffer.
      end;
      SENDCMDINPARAMS = TSendCmdInParams;
      PSendCmdInParams = ^TSendCmdInParams;
      TIdSector = packed record
        wGenConfig: Word;
        wNumCyls: Word;
        wReserved: Word;
        wNumHeads: Word;
        wBytesPerTrack: Word;
        wBytesPerSector: Word;
        wSectorsPerTrack: Word;
        wVendorUnique: array[0..2] of Word;
        sSerialNumber: array[0..19] of Char;
        wBufferType: Word;
        wBufferSize: Word;
        wECCSize: Word;
        sFirmwareRev: array[0..7] of Char;
        sModelNumber: array[0..39] of Char;
        wMoreVendorUnique: Word;
        wDoubleWordIO: Word;
        wCapabilities: Word;
        wReserved1: Word;
        wPIOTiming: Word;
        wDMATiming: Word;
        wBS: Word;
        wNumCurrentCyls: Word;
        wNumCurrentHeads: Word;
        wNumCurrentSectorsPerTrack: Word;
        ulCurrentSectorCapacity: ULONG;
        wMultSectorStuff: Word;
        ulTotalAddressableSectors: ULONG;
        wSingleWordDMA: Word;
        wMultiWordDMA: Word;
        bReserved: array[0..127] of Byte;
      end;
      PIdSector = ^TIdSector;
    const
      IDE_ID_FUNCTION = $EC;
      IDENTIFY_BUFFER_SIZE = 512;
      DFP_RECEIVE_DRIVE_DATA = $0007C088;
      IOCTL_SCSI_MINIPORT = $0004D008;
      IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;
      DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;
      BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;
      W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;
    var
      hDevice: THandle;
      cbBytesReturned: DWORD;
      pInData: PSendCmdInParams;
      pOutData: Pointer;  //PSendCmdInParams;
      Buffer: array[0..BufferSize - 1] of Byte;
      srbControl: TSrbIoControl absolute Buffer;
      procedure ChangeByteOrder(var Data; Size: Integer);
      var ptr: PChar;
        i: Integer;
        c: Char;
      begin
        ptr := @Data;
        for i := 0 to (Size shr 1) - 1 do begin
          c := ptr^;
          ptr^ := (ptr + 1)^;
          (ptr + 1)^ := c;
          Inc(ptr, 2);
        end;
      end;
    begin
      Result := '';
      FillChar(Buffer, BufferSize, #0);
      if Win32Platform = VER_PLATFORM_WIN32_NT then
      begin // Windows NT, Windows 2000
          // Get SCSI port handle
        hDevice := CreateFile(pchar('\\.\Scsi'+inttostr(ScsiID)+':'), GENERIC_READ or GENERIC_WRITE,
        FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
        if hDevice = INVALID_HANDLE_VALUE then Exit;
        try
          srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
          System.Move('SCSIDISK', srbControl.Signature, 8);
          srbControl.Timeout := 2;
          srbControl.Length := DataSize;
          srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
          pInData := PSendCmdInParams(PChar(@Buffer) + SizeOf(SRB_IO_CONTROL));
          pOutData := pInData;
          with pInData^ do begin
            cBufferSize := IDENTIFY_BUFFER_SIZE;
            bDriveNumber := 0;
            with irDriveRegs do begin
              bFeaturesReg := 0;
              bSectorCountReg := 1;
              bSectorNumberReg := 1;
              bCylLowReg := 0;
              bCylHighReg := 0;
              bDriveHeadReg := $A0;
              bCommandReg := IDE_ID_FUNCTION;
            end;
          end;
          if not DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil) then Exit;
        finally
          CloseHandle(hDevice);
        end;
      end
      else begin // Windows 95 OSR2, Windows 98
        hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);
        if hDevice = INVALID_HANDLE_VALUE then Exit;
        try
          pInData := PSendCmdInParams(@Buffer);
          pOutData := PChar(@pInData^.bBuffer);
          with pInData^ do begin
            cBufferSize := IDENTIFY_BUFFER_SIZE;
            bDriveNumber := 0;
            with irDriveRegs do begin
              bFeaturesReg := 0;
              bSectorCountReg := 1;
              bSectorNumberReg := 1;
              bCylLowReg := 0;
              bCylHighReg := 0;
              bDriveHeadReg := $A0;
              bCommandReg := IDE_ID_FUNCTION;
            end;
          end;
          if not DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, pInData, SizeOf(TSendCmdInParams) - 1, pOutData, W9xBufferSize, cbBytesReturned, nil) then Exit;
        finally
          CloseHandle(hDevice);
        end;
      end;
      with PIdSector(PChar(pOutData) + 16)^ do begin
        ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
        SetString(Result, sSerialNumber, SizeOf(sSerialNumber));
      end;
      Result := Trim(Result);
    end;
      

  3.   

    author:dandy读硬盘出厂序列号控件
    可配合程序加密
    全面支持WIN9X/ME/NT/2K/XP
    可配合D4,D5,D6,CB4,CB5使用。http://www.csdn.net/cnshare/soft/9/9092.shtm
      

  4.   

    var
      HardDiskSN : String;....
    for i:=0 to 4 do begin
       HardDiskSN := GetIdeDiskSerialNumber(ScsiID:integer);  
       if HardDiskSN<>'' then break;
    end;
    就取到了!!从0开始,0表示0#SCSI接口
      

  5.   

    95,98 需要带上SMARTVSD.vxd文件。