除了GetVolumeInformation的函数外,还有什么函数可以获得硬盘的序列号。
GetVolumeInformation只能获得盘卷符号,不能获得序列号。

解决方案 »

  1.   

    转一个给你,我收藏的,还没有试过  unit Unit1; interface uses 
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, StdCtrls; type 
      TForm1 = class(TForm) 
        Button1: TButton; 
        Label1: TLabel; 
        procedure Button1Click(Sender: TObject); 
      private 
        { Private declarations } 
      public 
        { Public declarations } 
      end; var 
      Form1: TForm1; implementation {$R *.dfm} 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;  procedure TForm1.Button1Click(Sender: TObject); 
    begin 
      Label1.Caption:=GetIdeDiskSerialNumber; 
    end; end.
      

  2.   

    网上有一个,不过是VC的,你看看
    http://asp.6to23.com/nowcan/tech/diskid.htm
    --------------------------------------
    看!
    那支正飞向太阳的蛾子.....
    就是我!
    --------------------------------------
      

  3.   

    不错,我不明白你们为什么都在搞这些无用的东西干吗,
    干吗不学学有用的东西那,比如:
    数据库3层,c/s,b/s,进程,等等................
      

  4.   

    哪个API都不能
    同意响马,楼主讲的这些只是些小技巧,因该掌握大的概念,技巧当然要,但绝大多数是在网上几分钟半小时就能找到答案的。而大的概念可以扩展你的设计的思路。越学越觉得自已浅薄
      

  5.   

    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
      

  6.   

    VC源程序:
    http://www.applevb.com/DiskID.rar