我的思路是转移中断向量地址到指定位置,但不知道如何在DELPHI中实现

解决方案 »

  1.   

    function GetIdeDiskSerialNumber : String;
    var
      hDevice : THandle;
      cbBytesReturned : DWORD;
      pInData : PSendCmdInParams;
      pOutData : Pointer; // PSendCmdOutParams
      Buffer : Array[0..BufferSize-1] of Byte;
      srbControl : TSrbIoControl absolute Buffer;
    begin
      Result := '';
      FillChar(Buffer,BufferSize,#0);  if Win32Platform=VER_PLATFORM_WIN32_NT then
      begin
        // Windows NT, Windows 2000
        //通过MS的S.M.A.R.T.接口,直接从RING3调用
        //API DeviceIoControl()来获取硬盘信息
        // 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;
        with PIdSector(PChar(pOutData)+16)^ do
        begin
          ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
          SetString(Result,sSerialNumber,SizeOf(sSerialNumber));
        end;
      end else
      begin
        // Windows 95 OSR2, Windows 98
        //使用类似CIH利用中断异常方法从Ring3转入Ring0层读取DiskSN
        //change2ring0;
        Result:=dsn;
      end;
    end;
      

  2.   

    取得硬盘出厂序列号 
    type
      MIDPtr = ^MIDRec;
      MIDRec = Record
        InfoLevel: word;
        SerialNum: LongInt;
        VolLabel: Packed Array [0..10] of Char;
        FileSysType: Packed Array [0..7] of Char;
      end;function GetDriveSerialNum(MID: MIDPtr; drive: Word): Boolean; assembler;
    asm
      push  DS    { Just for safety, I dont think its really needed }
      mov   ax,440Dh { Function Get Media ID }
      mov   bx,drive    { drive no (0-Default, 1-A ...) }
      mov   cx,0866h  { category and minor code }
      lds   dx,MID      { Load pointeraddr. }
      call  DOS3Call   { Supposed to be faster than INT 21H }
      jc    @@err
      mov   al,1           { No carry so return TRUE }
      jmp   @@ok
     @@err:
      mov   al,0           { Carry set so return FALSE }
     @@ok:
      pop   DS            { Restore DS, were not supposed to change it }
    end;procedure TForm1.NrBtnClick(Sender: TObject);
    var
      Info: MIDRec;
    begin
      Info.InfoLevel:=0; { Information Level }
      If GetDriveSerialNum(@Info,0) then  { Do something with it... }
        ListBox.Items.Add(IntToStr(Info.SerialNum)+' '+Info.VolLabel);
    end;
      

  3.   

    读出硬盘的出厂物理序列号
      function GetHDSerialNumber: LongInt;
    {$IFDEF WIN32}
    var
      pdw : pDWord;
      mc, fl : dword;
    {$ENDIF}
    begin
      {$IfDef WIN32}
      New(pdw);
      GetVolumeInformation(nil,nil,0,pdw,mc,fl,nil,0);
      Result := pdw^;
      dispose(pdw);
      {$ELSE}
      Result := GetWinFlags;
      {$ENDIF}
    end; program IdeSN; 
      
      // 目的:简单的控制台程序以获取第一个IDE硬盘的序列号
      
      {$APPTYPE CONSOLE} 
      
      uses 
        Windows, 
        SysUtils; // only for Win32Platform and SysErrorMessage 
      
      //------------------------------------------------------------- 
      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 
            // 获取 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; 
      
      
      //============================================================= 
      var s : String; 
          rc : DWORD; 
      begin 
        s := GetIdeDiskSerialNumber; 
        if s='' then 
          begin 
            rc := GetLastError; 
            if rc=0 then WriteLn('IDE drive is not support SMART feature') 
            else WriteLn(SysErrorMessage(rc)); 
          end 
        else WriteLn('Disk serial number: ''', s,''''); 
      end. 
    确定你的系统中有smartvsd.vxd
      

  4.   

    WinNT下截API, Win9X下监视中断调用.
      

  5.   

    修改中断向量表,Ring(0)级的程序还是读出来了或者有没有其它办法?
      

  6.   

    不装IDE驱动,不装INTEL应用程序加速器。