不懂。。 百度学习了下。。 
http://zhidao.baidu.com/question/141259956.html

解决方案 »

  1.   

    XP,98下倒是没问题,不过我是在D7下的,其他系统没试过
      

  2.   

    看来现在用delphi2010的,很少了,难道delphi2010不能实现获取硬盘的物理序列号吗?
      

  3.   

    如果delphi2010不能获取硬盘物理序列号的话,能获取cpu的物理序列号吗》?
      

  4.   

    和用那个版本的delphi关系不大吧?api就那些。
    获取序列号麻烦的是sata硬盘没有物理号的,只是为了兼容ide硬盘,配置了兼容接口。
    还有如果几个系统接了几个ide/sata设备怎么获取?
    如果系统还上了RAID,通过RAID介面卡怎么获取,这些才是麻烦问题。
    在windows下获得简单的单一的ide硬盘的序列号,这个问题很容易,网上一大推的。
      

  5.   

    硬盘都有“序列号”,所以对DELPHI版本没有关系,
    网上有很多关于代码
      

  6.   

    我在delphi7 用了一下代码,能正常获取硬盘的序列号: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));   
              Result   :=   Trim(Result);   
          end;   
      end;但是 delphi2010 这个代码不能获取硬盘序列号,什么都没有呢?
    现在我认为有些代码在net上不能正常使用的,
    那位高手知道这个问题,如果知道提供原理解决我的问题,我当然会重谢的!
    要多少钱就没问题的!
      

  7.   

    取硬盘序列号跟delphi哪个版本有什么关系?还必须用delphi 2010版本。
      

  8.   

    注意:2010是Unicode的
    2010下:char=widechar; string = widestring
    d7下:char=ansichar; string = ansistring
      

  9.   

    我有VB6.0下的,给你参考一下:
    http://download.csdn.net/source/1894321
      

  10.   

    读取硬件ID  
    如硬盘ID  function GetIdeSerialNumber: pchar;  
    const IDENTIFY_BUFFER_SIZE = 512;  
    type  
      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;  
      TSendCmdInParams = packed record  
      // Buffer size in bytes  
      cBufferSize: DWORD;  
      // Structure with drive register values.  
      irDriveRegs: TIDERegs;  
      // Physical drive number to send command to (0,1,2,3).  
      bDriveNumber: BYTE;  
      bReserved: array[0..2] of Byte;  
      dwReserved: array[0..3] of DWORD;  
      bBuffer: array[0..0] of Byte; // Input buffer.  
      end;  
      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: DWORD;  
      wMultSectorStuff: Word;  
      ulTotalAddressableSectors: DWORD;  
      wSingleWordDMA: Word;  
      wMultiWordDMA: Word;  
      bReserved: array[0..127] of BYTE;  
      end;  
      PIdSector = ^TIdSector;  
      TDriverStatus = packed record  
      // 驱动器返回的错误代码,无错则返回0  
      bDriverError: Byte;  
      // IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效  
      bIDEStatus: Byte;  
      bReserved: array[0..1] of Byte;  
      dwReserved: array[0..1] of DWORD;  
      end;  
      TSendCmdOutParams = packed record  
      // bBuffer的大小  
      cBufferSize: DWORD;  
      // 驱动器状态  
      DriverStatus: TDriverStatus;  
      // 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定  
      bBuffer: array[0..0] of BYTE;  
      end;  
    var  
      hDevice: Thandle;  
      cbBytesReturned: DWORD;  
      SCIP: TSendCmdInParams;  
      aIdOutCmd: array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE - 1) - 1] of Byte;  
      IdOutCmd: TSendCmdOutParams absolute aIdOutCmd;  
    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 := ''; // 如果出错则返回空串  
    if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000  
    // 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '\\.\PhysicalDrive1\'  
    hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,  
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);  
    end else // Version Windows 95 OSR2, Windows 98  
    hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);  
    if hDevice = INVALID_HANDLE_VALUE then Exit;  
    try  
    FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0);  
    FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0);  
    cbBytesReturned := 0;  
    // Set up data structures for IDENTIFY command.  
    with SCIP do begin  
    cBufferSize := IDENTIFY_BUFFER_SIZE;  
    // bDriveNumber := 0;  
    with irDriveRegs do begin  
    bSectorCountReg := 1;  
    bSectorNumberReg := 1;  
    // if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0  
    // else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);  
    bDriveHeadReg := $A0;  
    bCommandReg := $EC;  
    end;  
    end;  
    if not DeviceIoControl(hDevice, $0007C088, @SCIP, SizeOf(TSendCmdInParams) - 1,  
    @aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil) then Exit;  
    finally  
    CloseHandle(hDevice);  
    end;  
    with PIdSector(@IdOutCmd.bBuffer)^ do begin  
    ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));  
    (Pchar(@sSerialNumber) + SizeOf(sSerialNumber))^ := #0;  
    Result := Pchar(@sSerialNumber);  
    end;  
    end; 
      

  11.   

    delphi2010没用过,但是我用的是DELPHI7测试这个是没有问题的,把钱打给我吧
      

  12.   

    网上取硬盘的代码用在D2010中要修改下 
    一般就是ansistring和widestring的问题
      

  13.   

    测不出来硬盘ID?我的用DELPHI7测试时都能测试出来如下:
    WD-WCANK1247357
    STA207MV02UT0D
    9VMFGBHL
    WD-WMAV34298667
    WD-WCAYUD491157 
    K137T0AG
    4MT1Z064
    WD-WCAYUD688775
    SB25DBH6GRJTVN
    K134ETRG
    9QFAYVBF
    6VM1CPBN
      

  14.   

    我试过了好多个硬盘序列号的代码,delphi 7 可以正常使用,但delphi 2009和delphi 2010力不能正常的读取序列号  
    我看又有一些代码,和dll 文件 在delphi 2010上不能正常使用的,这些代码如何转换成delphi2010的代码呢?
    你先把这些代码转换成delphi2010或delphi2011后在跟我联系,如果测试通过了 ,我马上给你付款 
      

  15.   

    这个问题终于解决了,我把vb做的ocx控件导入到delphi2010,然后调用就可以正常获取硬盘物理序列号
      

  16.   

    你试试raid的盘行不行。我看不行
      

  17.   

    var
    disksn:string;
    begin
    disksn:=StrPas(PAnsiChar(GetIdeSerialNumber()));这样转换一下就行了。