如何判断当前硬盘是IDE硬盘还是SCSI硬盘,并获得磁盘序列号(在线等待)?

解决方案 »

  1.   

    查查
    好象有这样的api函数
      

  2.   

    给几个函数你,判断IDE还是SCSI我就不知道了!
    unit my_utility;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Dialogs,
      StdCtrls, WinTypes, WinProcs, Forms, DB, ComObj, StrUtils;
    const
       ID_BIT = $200000;
    type
       TCPUID = array[1..4] of Longint;     //存放CPU编号的数组
       TVendor = array [0..11] of char;
    {
      ======== CPU ID 专用变量 ==========
      说明:对586以上机器的CPU都有1至4组编号,通常第3组和第4组编号是唯一的
         所以,可利用此编号来给程序定义注册码
    }
    function IsCPUID_Available : BOOLEAN; register;        //是否可获得CPU编号
    function GetCPUID : TCPUID; assembler; register;       //获得CPU的编号
    function GetCPUVendor : TVendor; assembler; register;  //获得CPU的制造商implementationfunction IsCPUID_Available : BOOLEAN; register;
    asm
      PUSHFD
      POP     EAX
      MOV     EDX,EAX
      XOR     EAX,ID_BIT
      PUSH    EAX
      POPFD
      PUSHFD
      POP     EAX
      XOR     EAX,EDX
      JZ      @exit
      MOV     AL,TRUE
      @exit:
    end;function GetCPUID : TCPUID; assembler; register;
    asm
      PUSH    EBX
      PUSH    EDI
      MOV     EDI,EAX
      MOV     EAX,1
      DW      $A20F       {CPUID Command}
      STOSD             {CPUID[1]}
      MOV     EAX,EBX
      STOSD               {CPUID[2]}
      MOV     EAX,ECX
      STOSD               {CPUID[3]}
      MOV     EAX,EDX
      STOSD               {CPUID[4]}
      POP     EDI
      POP     EBX
    end;function GetCPUVendor : TVendor; assembler; register;
    asm
      PUSH    EBX
      PUSH    EDI
      MOV     EDI,EAX
      MOV     EAX,0
      DW      $A20F
      MOV     EAX,EBX
      XCHG   EBX,ECX
      MOV   ECX,4
    @1:
      STOSB
      SHR     EAX,8
      LOOP    @1
      MOV     EAX,EDX
      MOV   ECX,4
    @2:
      STOSB
      SHR     EAX,8
      LOOP    @2
      MOV     EAX,EBX
      MOV   ECX,4
    @3:
      STOSB
      SHR     EAX,8
      LOOP    @3
      POP     EDI      {Restore registers}
      POP     EBX
    end;
      

  3.   

    http://www.ahong.net/download/diskinfo.rar试试。
      

  4.   

    用VC编写的DLL,可以获得硬盘的型号、序列号以及计算机 ID,带Delphi的源程序:http://www.applevb.com/lib/diskio.rar
      

  5.   

    想得到卷标用GetVolumeInformation.
    下面方法可以准确的得到硬盘的型号和生产序列号等参数!
    function GetIdeDiskSerialNumber(var SerialNumber: string; var ModelNumber: string;
     var FirmwareRev: string; var TotalAddressableSectors: ULong;
     var SectorCapacity: ULong; var SectorsPerTrack: Word): Boolean; //得到硬盘物理号
    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. Must be zero.
     end;
     IDEREGS = TIDERegs;
     PIDERegs = ^TIDERegs; TSendCmdInParams = packed record
       cBufferSize: DWORD;
       irDriveRegs: TIDERegs;
       bDriveNumber: Byte;
       bReserved: array[0..2] of Byte;
       dwReserved: array[0..3] of DWORD;
       bBuffer: array[0..0] of Byte;
     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; // PSendCmdOutParams
     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 := False;
     FillChar(Buffer, BufferSize, #0);
     if Win32Platform = VER_PLATFORM_WIN32_NT then
     begin // Windows NT, Windows 2000
    // Get SCSI port handle
       hDevice := CreateFile('\\.\Scsi0:',
         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 := @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(SerialNumber, sSerialNumber, sizeof(sSerialNumber)); //硬盘生产序号   ChangeByteOrder(sModelNumber, sizeof(sModelNumber));
       SetString(ModelNumber, sModelNumber, sizeof(sModelNumber)); //硬盘型号   ChangeByteOrder(sFirmwareRev, sizeof(sFirmwareRev));
       SetString(FirmwareRev, sFirmwareRev, sizeof(sFirmwareRev)); //硬盘硬件版本
       Result := True;
       ChangeByteOrder(ulTotalAddressableSectors, sizeof(ulTotalAddressableSectors));
       TotalAddressableSectors := ulTotalAddressableSectors; //硬盘ulTotalAddressableSectors参数   ChangeByteOrder(ulCurrentSectorCapacity, sizeof(ulCurrentSectorCapacity));
       SectorCapacity := ulCurrentSectorCapacity; //硬盘wBytesPerSector参数   ChangeByteOrder(wNumCurrentSectorsPerTrack, sizeof(wNumCurrentSectorsPerTrack));
       SectorsPerTrack := wNumCurrentSectorsPerTrack; //硬盘wSectorsPerTrack参数
     end;
    end;
    ---------------------------------
    如果硬盘有多个的话,修改里面的参数就可以查出第二、第三个硬盘的型号、ID等参数。 
    引用如:
    procedure TForm1.BitBtn1Click(Sender: TObject);
    var
     S1, S2, S3: string;
     W5: Word;
     W4, W3: ULong;
    begin
       GetIdeDiskSerialNumber(S1, S2, S3, W3, W4, W5);
       Label1.Caption := '序列号:' + S1;
       Label2.Caption := '硬盘型号:' + S2;
       Label3.Caption := '硬件版本:' + S3;
       Label6.Caption := 'TotalAddressableSectors:' + inttostr(W3);
       Label7.Caption := 'SectorCapacity:' + inttostr(W4);
       Label8.Caption := 'SectorsPerTrack:' + inttostr(W5);
    end;
      

  6.   

    ide的硬盘倒是可以获得序列号,但SCSI就不行。有没有方法呀?