谁有读硬盘序列号的源代码

解决方案 »

  1.   

    getvolumeinformation()就可以得到硬盘的序列号
      

  2.   

    http://search.csdn.net/expert/topic/53/5301/2001/2/2/63762.htm
      

  3.   

    上面那篇有详细说明多使用论坛的搜索功能->http://search.csdn.net/advsch.asp
      

  4.   

    我有封装过一个DLL,如果要到ahong.net下载吧。
      

  5.   

    Unit HardDisk;
    INTERFACE
    FUNCTION  GetHardDiskNaam  : STRING;
    FUNCTION  GetHardDiskSerieNummer        : STRING;
    FUNCTION  GetHardDiskControlleNummer    : STRING;
    PROCEDURE GetHardDiskGegevens;
    CONST
      CodeerTabel : ARRAY[0..24] OF BYTE =
    (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);
    TYPE
      CharArray = ARRAY[0..24] OF CHAR;
    VAR
      HardDiskGegevens          : ARRAY[1..256] OF INTEGER;
      HardDiskNaam  : CharArray;
      SerieNummer  : CharArray;
      ControlleNummer          : CharArray;
      C_HardDiskNaam: STRING;
      C_HardDiskSerieNummer    : STRING;
      C_HardDiskControlleNummer : STRING;
      C_LicentieNaam: STRING;
    IMPLEMENTATION
    FUNCTION GetHardDiskNaam : STRING;
    VAR
      Teller : INTEGER;
      Lus    : INTEGER;
    BEGIN
        GetHardDiskNaam := '';
        Teller := 1;
        FOR Lus := 1 TO 18 DO
        BEGIN
          HardDiskNaam[Teller] := CHR( ( HardDiskGegevens[27+Lus] DIV 256 ));
          Inc(Teller);
          HardDiskNaam[Teller] := CHR( ( HardDiskGegevens[27+Lus] MOD 256 ));
          Inc(Teller);
        END;
        GetHardDiskNaam := HardDiskNaam;
    END;
    FUNCTION GetHardDiskSerieNummer : STRING;
    VAR
      Teller : INTEGER;
      Lus    : INTEGER;
    BEGIN
        GetHardDiskSerieNummer := '';
        Teller := 1;
        FOR Lus := 1 TO 8 DO
        BEGIN
          SerieNummer[Teller] := CHR( ( HardDiskGegevens[10+Lus] DIV 256 ));
          Inc(Teller);
          SerieNummer[Teller] := CHR( ( HardDiskGegevens[10+Lus] MOD 256 ));
          Inc(Teller);
        END;
        GetHardDiskSerieNummer := SerieNummer;
    END;
    FUNCTION GetHardDiskControlleNummer : STRING;
    VAR
      Teller : INTEGER;
      Lus    : INTEGER;
    BEGIN
        GetHardDiskControlleNummer := '';
        Teller := 1;
        FOR Lus := 1 TO 3 DO
        BEGIN
          ControlleNummer[Teller] := CHR( ( HardDiskGegevens[23+Lus] DIV 256 ));
          Inc(Teller);
          ControlleNummer[Teller] := CHR( ( HardDiskGegevens[23+Lus] MOD 256 ));
          Inc(Teller);
        END;
        GetHardDiskControlleNummer := ControlleNummer;
    END;
    PROCEDURE GetHardDiskGegevens;
    VAR
      Lus    : INTEGER;
    BEGIN
      WHILE ( Port[$1f7] <> $50) DO ;
      Port[$1F6] := $A0 ;
      Port[$1F7] := $EC ;
      WHILE ( Port[$1f7] <> $58 ) DO ;
      FOR Lus := 1 TO 256 DO
      BEGIN
        HardDiskGegevens[Lus] := Portw[$1F0] ;
      END;
    END;
    END.
      

  6.   

    还有另一个,我没测试,不过应该可以用
    function GetHDSerialNumber(Drv : String): String;
    var
      VolumeSerialNumber : DWORD;
      MaximumComponentLength : DWORD;
      FileSystemFlags : DWORD;
    begin
      if Drv[Length(Drv)] =':' then Drv := Drv + '\';
      GetVolumeInformation(pChar(Drv),
                           nil,
                           0,
                           @VolumeSerialNumber,
                           MaximumComponentLength,
                           FileSystemFlags,
                           nil,
                           0);
      Result := IntToHex(HiWord(VolumeSerialNumber), 4) +
                '-' +
                IntToHex(LoWord(VolumeSerialNumber), 4);
    end;
    **********************************
    function GetHardDiskSerial(const DriveLetter: Char): string; 
    var 
      NotUsed:     DWORD; 
      VolumeFlags: DWORD; 
      VolumeInfo:  array[0..MAX_PATH] of Char; 
      VolumeSerialNumber: DWORD; 
    begin 
      GetVolumeInformation(PChar(DriveLetter + ':\'), 
        nil, SizeOf(VolumeInfo), @VolumeSerialNumber, NotUsed, 
        VolumeFlags, nil, 0); 
      Result := Format('Label = %s   VolSer = %8.8X', 
        [VolumeInfo, VolumeSerialNumber]) 
    end; 
    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
      ShowMessage(GetHardDiskSerial('c')); 
    end; 
      

  7.   

    斑竹用VC编写的DLL,可以获得硬盘的型号、序列号以及计算机 ID,带Delphi的源程序:函数以及定义:
    function ReadPhysicalDrive(driveID:integer;buffer:Pointer;bufLen:integer):integer; stdcall; external 'DiskID.dll' name 'ReadPhysicalDriveInNT';
    获得WinNT下的硬盘型号以及序列号。参数driveID为硬盘的位置,IDE1上的主盘为0,类推到IDE2上的从盘的driveID为3。
    function ReadPhysicalDrive9X(driveID:integer;buffer:Pointer;bufLen:integer):integer; stdcall; external 'DiskID.dll' name 'ReadDrivePortsInWin9X'; 
    获得Win9X下的硬盘型号以及序列号。参数同上
    function getHardDriveComputerID:int64; stdcall; external 'DiskID.dll' name 'getHardDriveComputerID';
    获得计算机的ID http://www.applevb.com/lib/diskio.rar
      

  8.   

    下面方法可以准确的得到硬盘的型号和生产序列号等参数!
    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;
      

  9.   

    {=========================================================================
      功  能:  得到硬盘序列号
      参  数:
      返回值:  硬盘序列号
      备  注: ===========================================================================}
    function GetIdeDiskSerialNumber : String;
    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 := '';
      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(Result,sSerialNumber,SizeOf(sSerialNumber));
        end;
    end;
      

  10.   

    楼上的方法在Win2003下不能通过,请问谁知道如何在2003下读硬盘序列号。如果有用汇编编的,与操作系统无关的代码就好了...