首页  编辑  

硬盘参数信息

Tags: /超级猛料/Hardware.硬件相关/驱动器相关/硬盘/   Date Created:

下面是一位前辈写的代码

IDE.PAS (IDE硬盘参数检测)

 ?Programmed by: 刘 杰  

 ?nbsp;Designed     : 04/11/92

 ?nbsp;Last modified: 01/26/95

 ?请使用 Turbo Pascal 7.0 编译.

const

  { read/write --------------------------- }

  HDC_DATA    = $01F0;

  HDC_ERROR   = $01F1;

  HDC_SECCOU  = $01F2;

  HDC_SECNUM  = $01F3;

  HDC_CYLLOW  = $01F4;

  HDC_CYLHIGH = $01F5;

  HDC_SDH     = $01F6;

  { read --------------------------------- }

  HDC_STATUS  : Word = $01F7;

  HDC_ALTSTA  = $03F6;

  { write -------------------------------- }

  HDC_COMMAND = $01F7;

  HDC_FIXED   = $03F6;

  { commands ----------------------------- }

  HDC_COMMAND_RESTORE = $10;

  HDC_COMMAND_SEEK    = $70;

  HDC_COMMAND_READ    = $20;

  HDC_COMMAND_WRITE   = $30;

  HDC_COMMAND_FORMAT  = $50;

  HDC_COMMAND_READVER = $90;

  HDC_COMMAND_DIAG    = $90;

  HDC_COMMAND_SETPAR  = $91;

  HDC_COMMAND_WRSTACK = $E8;

  HDC_COMMAND_RDSTACK = $E4;

  HDC_COMMAND_READPAR = $EC;

  HDC_COMMAND_POWER   = $E0;

  HDC_FIXED_IRQ       = $02;

  HDC_FIXED_RESET     = $04;

  HDC_STATUS_ERROR    = $01;

  HDC_STATUS_INDEX    = $02;

  HDC_STATUS_ECC      = $04;

  HDC_STATUS_DRQ      = $08;

  HDC_STATUS_COMPLETE = $10;

  HDC_STATUS_WRFAULT  = $20;

  HDC_STATUS_READY    = $40;

  HDC_STATUS_BUSY     = $80;

type

  TIdeTypes = record

     Cylinders,

     Heads,

     Sectors: Word;

     Name: String[38];

  end;

  PIdeInfo = ^TIdeInfo;

  TIdeInfo = record

     genconf,

     fixcyls,

     remcyls,

     heads,

     bytetrack,                     { bytes per track }

     bytesector,                    { bytes per sector }

     sectors,                      { sectors per track }

     byteisg,                      { bytes intesector gap }

     byteplo,                      { bytes in sync }

     worduniq: Word;                { words unique status }

     serial: array[1..20] of Char;

     contype,                       { controller type }

     bufsiz,                      { buffer size in 512 byte blocks }

     byteecc: Word;              { ECC bytes trasferred in read/write long  

}

     firmware: array[1..8] of Char; { firmware revision }

     model: array[1..40] of Char;   { model ID }

     secsint,                      { number of sectors transferred per inte

rrupt }

     dblword,                      { double word transfer flag }

     writepro: Word;                { write protect }

  end;

const

  IdesInDataBase = 17;

  IdeTypes: array[1..IdesInDataBase] of TIdeTypes =

  ((Cylinders:667;  Heads:4;  Sectors:33; Name:'Fujitsu M2611T (42.9 MB)'),

   (Cylinders:667;  Heads:8;  Sectors:33; Name:'Fujitsu M2612T (85.9 MB)'),

   (Cylinders:667;  Heads:12; Sectors:33; Name:'Fujitsu M2613T (128.9 MB)')

,

   (Cylinders:667;  Heads:16; Sectors:33; Name:'Fujitsu M2614T (171.9 MB)')

,

   (Cylinders:782;  Heads:2;  Sectors:27; Name:'Western Digital WD93024-A (

20.6 MB)'),

   (Cylinders:782;  Heads:4;  Sectors:27; Name:'Western Digital WD93044-A (

41.2 MB)'),

   (Cylinders:845;  Heads:3;  Sectors:35; Name:'Toshiba MK232FC (45.4 MB'),

   (Cylinders:845;  Heads:7;  Sectors:35; Name:'Toshiba MK234FC (106 MB'),

   (Cylinders:965;  Heads:5;  Sectors:17; Name:'Quantum ProDrive 40AT (40 M

B)'),

   (Cylinders:965;  Heads:10; Sectors:17; Name:'Quantum ProDrive 80AT (80 M

B)'),

   (Cylinders:1050; Heads:2;  Sectors:40; Name:'Teac SD-340 (41 MB)'),

   (Cylinders:776;  Heads:8;  Sectors:33; Name:'Conner CP-3104 (100 MB)'),

   (Cylinders:745;  Heads:4;  Sectors:28; Name:'Priam 3804M (40.7 MB)'),

   (Cylinders:980;  Heads:10; Sectors:17; Name:'Western Digitial Caviar AC2

80 (81 MB)'),

   (Cylinders:560;  Heads:6;  Sectors:26; Name:'Seagate ST157A (42 MB)'),

   (Cylinders:732;  Heads:8;  Sectors:35; Name:'ALPS ELECTRIC Co.,LTD. DR31

1C (102 MB)'),

   (Cylinders:0;    Heads:0;  Sectors:0;  Name:''));

type

  parray = ^tarray;

  tarray = array[1..256] of Word;

var

  secbuf: parray;

  drive: Byte;

  drv: String[1];

procedure printinfo;

var

  id: TIdeInfo;

  capacity: Word;

  types: String;

  i: Integer;

  function zo(const value: Byte): String;

  begin

     if Boolean(value) then

        zo := ''

     else

        zo := 'not';

  end;

  function ToStr(value: LongInt): String;

  var

     S: String;

  begin

     Str(value, S);

     ToStr := S;

  end;

  function ConvertHex(Value: Word): String;

  const

     hexTable: array[0..15] of Char = '0123456789ABCDEF';

  begin

     ConvertHex := hexTable[Hi(Value) shr 4] + hexTable[Hi(Value) and $f] +

                   hexTable[Lo(Value) shr 4] + hexTable[Lo(Value) and $f];

  end;

  procedure SwapBytes(var Source, Dest; Len: Byte); assembler;

  asm

      push  ds

      lds   si, Source

      les   di, Dest

      mov   cl, len

      xor   ch, ch

  @1: mov   ax, ds:[si]

      xchg  ah, al

      mov   es:[di], ax

      inc   si

      inc   si

      inc   di

      inc   di

      loop  @1

      pop    ds

  end;

begin

  id := PIdeInfo(secbuf)^;

  { get disk type by characteristics }

  i := 1;

  while IdeTypes[i].Cylinders <> 0 do

     Begin

 if (IdeTypes[i].cylinders = id.fixcyls) and

    (IdeTypes[i].heads = id.heads) and

    (IdeTypes[i].sectors = id.sectors) then

           Begin

              types := IdeTypes[i].name;

              break;

           end;

        inc(i);

     end;

  { unknown disk }

  if (IdeTypes[i].cylinders = 0) then

     Begin

        types := ' ';

        { calculate capacity in MB }

 capacity := (LongInt(id.fixcyls) * id.heads * id.sectors) div 2048;

        types := types + ToStr(capacity);

        types := types + ' Mbytes';

     end;

  { swap bytes in ASCII fields except for WD disks }

  if (i <> 4) and (i <> 5) then

     Begin

        SwapBytes(id.serial, id.serial, 10);

        SwapBytes(id.firmware, id.firmware, 4);

        SwapBytes(id.model, id.model, 20);

     end;

  WriteLn('Drive ', drive-2, '     :', types);

  WriteLn('Drive ID    : ', ConvertHex(id.genconf));

  WriteLn('Cylinders   : ', id.fixcyls{, ' ' id.remcyls, ' removables'});

  WriteLn('Heads       : ', id.heads);

  Writeln('Sectors     : ', id.sectors);

  WriteLn('Serial No.  : ', id.serial);

  WriteLn('Firmware    : ', id.firmware);

  WriteLn('Model       : ', id.model);

{   WriteLn('Bytes per track         : ', id.bytetrack);

  Writeln('Bytes per sector        : ', id.bytesector);

  WriteLn('Bytes of intersector gap: ', id.byteisg);

  Writeln('Bytes of sync           : ', id.byteplo);

  WriteLn('Controller type         : ', id.contype);}

  Writeln('Buffer      : ', id.bufsiz div 2, ' KBytes');

  WriteLn('Bytes of ECC: ', id.byteecc);

end;

procedure readsect; assembler;

asm

{ poll DRQ }

@1: mov   dx, HDC_STATUS

   in    al, dx

   and   al, HDC_STATUS_BUSY

   or    al, al

   jne   @1

{ read up sector }

   mov   cx, 256

   mov   dx, HDC_DATA

   les   di, secbuf

@2: in    ax, dx

   mov   es:[di], ax

   inc   di

   inc   di

   loop  @2

end;

function DriveValid(Drive: Char; var Drv: Byte): Boolean; assembler;

asm

   mov   ah, 19h      { Save the current drive in BL }

   int   21h

   mov   bl, al

   mov   dl, Drive    { Select the given drive }

   sub   dl, 'A'

   les   di, DRV

   mov   es:[di], dl

   mov   ah, 0Eh

   int   21h

   mov   ah, 19h      { Retrieve what DOS thinks is current }

   int   21h

   mov   cx, 0        { Assume false }

   cmp   al, dl       { Is the current drive the given drive? }

   jne   @1

   mov   cx, 1        { It is, so the drive is valid }

   mov   dl, bl       { Restore the old drive }

   mov   ah, 0eh

   int   21h

@1: xchg  ax, cx       { Put the return value into AX }

end;

function CurDisk: Byte; assembler;

{ Returns current drive }

asm

   mov   ah, 19h

   int   21h

end;

begin

  Writeln('IDE ver 1.2  (c) 1995 Keenvim software workgroup, Inc.');

  writeln('Programmed by  Mr. LiuJie'#13#10);

  if ParamCount > 0 then

     Begin

        drv := ParamStr(1);

        drv[1] := UpCase(drv[1]);

        if not DriveValid(drv[1], Drive) or not (drv[1] in ['C'..'Z']) then

           Begin

              WriteLn('There isn''t such drive or drive invalid!');

              Halt(1);

           end;

     end

  else

     drive := CurDisk;

  { disable interrupt from drive }

  Port[HDC_FIXED] := HDC_FIXED_IRQ;

  { set up task file parameter }

  Port[HDC_SDH] := $A0 + (drive shl 4);

  { issue read parameters }

  Port[HDC_COMMAND] := HDC_COMMAND_READPAR;

  GetMem(secbuf, SizeOf(secbuf));

  { read up sector }

  readsect;

  { print out info }

  printinfo;

  FreeMem(secbuf, SizeOf(secbuf));

end.

********************

程序是编译过了,可是一运行就死机,帮我看看如何

unit Getsn;

interface

uses

 Windows, SysUtils, Classes;

type

 TGetsn = class(TComponent)

 private

 protected

   { Protected declarations }

 public

   { Public declarations }

 published

   { Published declarations }

 end;

var

 pw:array[1..256] of word;

 idt,int_idt:dword;

 Base:dword;

 Entry:word;

 function inp(rdx:WORD):byte;

 function inpw(rdx:WORD):word;

 procedure outp(rdx:WORD;ral:integer);

 function WaitIde:integer;

 procedure ReadIDE;

 procedure NowInRing0;

 procedure GetIDEInfo;

 function harddisksn:string;

implementation

function inp(rdx:WORD):byte;Assembler;

asm

 xor eax, eax

 mov dx, rdx

 in al, dx

 mov result,al

end;

function inpw(rdx:WORD):word;Assembler;

asm

 xor eax, eax

 mov dx, rdx

 in  ax, dx

 mov result,ax;

end;

procedure outp(rdx:WORD;ral:integer);Assembler;

asm

 mov dx, rdx

 mov eax, ral

 out dx, al

end;

function WaitIde:integer;

var

 al:word;

begin

 al:=inp($1F7);

 while (al<$80)do

   al:=inp($1F7);

 result:=al;

end;

procedure ReadIDE;

var

 al,i:byte;

begin

 WaitIde;

 outp($1F6,$A0);

 al:= WaitIde;

 if ((al and $50)<>$50) then exit;

 outp($1F6,$A0);

 outp($1F7,$EC);

 al:=WaitIde;

 if ((al and $58)<>$58) then exit;

 for i:=0 to 255 do

   pw[i]:=inpw($1F0);

end;

procedure NowInRing0;Assembler;

asm

 push  ebp

 mov   ebp,esp

 call  ReadIDE;

 cli

 mov     ebx, int_idt

 mov     ax, Entry

 mov     word ptr[ebx-4], ax

 mov     eax, Base

 shr          eax, 16

 mov          [ebx+2], ax

 sti

 leave

 iretd

end;

procedure GetIDEInfo;Assembler;

var

 dwExcept:DWORD;

begin

dwexcept:=dword(addr(nowinring0));

asm

 mov     eax, fs:[0]

 push        eax

 sidt    [esp-02h]

 pop     ebx

 mov     idt, ebx

 add     ebx, $1C

 mov     int_idt, ebx

 mov     eax, [ebx]

 mov     [Base], eax

 mov     ax, [ebx-4]

 mov     [Entry], ax

 cli

 mov     esi, dwExcept

 push        esi

 mov            [ebx-4], si

 shr            esi, 16

 mov            [ebx+2], si

 pop            esi

 sti           //到这里死机

 int     3

end;

end;

function harddisksn:string;

var

 s:array[1..80] of char;

 i,j:integer;

begin

 GetIDEInfo;

 j:=0;

 for i:=0 to 9 do

   while (j<=19) do

   begin

     s[j]:=chr(pw[10+i]shr 8);

     j:=j+1;

     s[j]:=chr(pw[10+i]and $FF);

     j:=j+1;

   end;

 s[j]:=chr(0);

 result:=s;

end;

end.

*****************

一个读取硬盘SN号的C程序,我已经转了差不多了,只是一运行就死机,但C程序绝对正确.

C程序在下.

#include

#include

WORD    pw[256];

static  DWORD   idt, int_idt;

static  DWORD   Base;

static  WORD    Entry;

#pragma warning (disable:4035)

static int inp(WORD rdx)

{

   _asm xor eax, eax

   _asm mov dx, rdx

   _asm in al, dx

}

static WORD inpw(WORD rdx)

{

   _asm xor eax, eax

   _asm mov dx, rdx

   _asm in  ax, dx

}

static void outp(WORD rdx, int ral)

{

   _asm mov dx, rdx

   _asm mov eax, ral

   _asm out dx, al

}

static int WaitIde()

{

  int   al;

  while ((al=inp(0x1F7))>=0x80) ;

  return al;

}

static void ReadIDE()

{

  int   al;

  int   i;

  WaitIde();

  outp(0x1F6,0xA0);

  al = WaitIde();

  if ((al&0x50)!=0x50) return;

  outp(0x1F6,0xA0);

  outp(0x1F7,0xEC);

  al = WaitIde();

  if ((al&0x58)!=0x58) return;

  for (i=0;i<256;i++) {

     pw[i] = inpw(0x1F0);

  }

}

static void __declspec( naked ) NowInRing0()

{

   _asm {

       push    ebp      

       mov     ebp,esp

       call    ReadIDE

       cli

       mov     ebx, int_idt

       mov     ax, Entry

               mov            word ptr [ebx-4], ax

       mov     eax, Base

               shr            eax, 16        

               mov            [ebx+2], ax

       sti

       leave  

       iretd

   }

}

void GetIDEInfo()

{

   DWORD   dwExcept;

   dwExcept = (DWORD)NowInRing0;

   _asm {

       mov     eax, fs:[0]

           push        eax                

       sidt    [esp-02h]  

       pop     ebx            

       mov     idt, ebx

       add     ebx, 0x1C

       mov     int_idt, ebx

       mov     eax, [ebx]  

       mov     [Base], eax

       mov     ax, [ebx-4]

       mov     [Entry], ax

       cli

       mov     esi, dwExcept

               push        esi

               mov            [ebx-4], si

           shr            esi, 16                

               mov            [ebx+2], si        

               pop            esi

       sti

       int     3

   }

}

main()

{

   char    s[80];

   register i,j;

   GetIDEInfo();

   for (i=0,j=0;i<10;i++) {

       s[j++]=pw[10+i]>>8;

       s[j++]=pw[10+i]&0xFF;

   }

   s[j] = 0;

   printf("Serial=%s\n", s);

   return 0;

}