DiskInf 1.0
Leer el número serial de Fábrica y modelo del HDD

 

Fecha: 08/Oct/2001 (07/Oct/2001)
Autor: Miguelacho ( jmferrer@telcel.net.ve )


Hola Guille, aquí te mando un ejemplo sencillo pero muy interesante, en especial para quienes quieran crear un sistema de seguridad para sus proyectos, se trata de una aplicación que permite leer el numero serial del disco duro, pero el numero REAL, el de fábrica. No el del Volumen, además de esto, lee el modelo y marca del disco, y el número de revisión, la idea de este código es brindar a los programadores la posibilidad de capturar estas informaciones, para crear un sistema de procesamiento bien sea de una licencia única, o la protección de un sistema para que solo pueda ser ejecutado en una máquina específica. Mucho te agradecería a ti y a los colegas que usen este código, me informen de las posibilidades que se puedan introducir, en especial porque lamentablemente, solo corre bajo Windows 95, 98, 98 SE, y Me, no he logrado que corra en NT, ni en 2000, y no lo he probado en XP, aunque estoy trabajando con un colega quien está haciendo modificaciones, así como introduciendo nuevas funciones de seguridad, posiblemente él o ambos, complementemos esta información.

Este es el código fuente de la DLL:

(La misma está escrita en Delphi, y es propiedad de Lucy o MAC (mac@encomix.es), la verdad nunca pude contactarme con esta persona, los códigos los saqué de aquí: http://skyscraper.fortunecity.com/virtuosity/452/)

 


DSIdeInf.DPR:

{$A-} (* ¡¡¡ IMPORTANT: DON'T ALIGN REGISTER FIELDS !!! *)

// --------------------------------------------------------

LIBRARY DSIdeInf;

USES Windows,

  SysUtils;

// ------------- DATA - handling of the VxD ----------------

    (* VxD Functions *)

CONST

  cVxDfunction_IdesDinfo = 1;

  (* Output Bbuffer for the VxD (rt_IdeDinfo record) *)

TYPE

  at_DRawInfo = array [0..255] of word;

  rt_IdeDInfo = record

    IdeExists: array [1..4] of byte;

    DiskExists: array [1..8] of byte;

    DisksRawInfo: array [1..8] of at_DRawInfo;

  end; {rIdeDInfo}

  pt_IdeDInfo = ^rt_IdeDInfo; // pointer for dynamic allocation

VAR

  VxDHandle: THandle;

  POutBufVxD: pt_IdeDInfo;

  lpBytesReturned: DWord;

// ---------- DATA - Handling of IdeDinfo (DLL) ---------

CONST

  bit00 = $00000001; bit01 = $00000002; bit02 = $00000004; bit03 = $00000008;

  bit04 = $00000010; bit05 = $00000020; bit06 = $00000040; bit07 = $00000080;

  bit08 = $00000100; bit09 = $00000200; bit10 = $00000400; bit11 = $00000800;

  bit12 = $00001000; bit13 = $00002000; bit14 = $00004000; bit15 = $00008000;

      (* IdeDinfo "data fields" *)

TYPE

  rt_DiskInfo =  record

    DiskExists: boolean;

    ATAdevice: boolean;

    RemovableDevice: boolean;

    TotLogCyl: word;

    TotLogHeads: word;

    TotLogSPT: word;

    SerialNumber: string[20];

    FirmwareRevision: string[8];

    ModelNumber: string[40];

    CurLogCyl: word;

    CurLogHeads: word;

    CurLogSPT: word;

  end;

VAR

  vp_Valid: boolean;

  vp_IdeExists: array [1..4] of boolean;

  vp_DisksInfo: array [1..8] of rt_DiskInfo;

// ----------- CODE - VxD function handling --------------

PROCEDURE IdeDInfo;

  Var

    Ide, MoS, Disk: byte;

    fi, fj: byte; {FOR counters}

Begin

  (* 1. Make an output buffer for the VxD *)

  POutBufVxD:= AllocMem(SizeOf(rt_IdeDInfo));

  (* 2. Run VxD function *)

  DeviceIoControl

    (VxDHandle, cVxDfunction_IdesDInfo,

    NIL, 0,                                           {In}

    POutBufVxD, SizeOf(POutBufVxD^), lpBytesReturned, {Out}

    NIL);

    (* 3. Translate and store data *)

  // Ide - Disk exists

  for Ide:= 1 to 4 do

  begin

    vp_IdeExists[Ide]:= Odd(POutBufVxD^.IdeExists[Ide]);

    for MoS:= 1 to 2 do

    begin

      Disk:= (Ide-1)*2 + MoS;

      vp_DisksInfo[Disk].DiskExists:= Odd(POutBufVxD^.DiskExists[Disk])

    end; // for MoS

  end; // for Ide

  for Ide:= 1 to 4 do

  begin

    if Not vp_IdeExists[Ide] then continue;

    (* Ide Exists - Go on *)

    for MoS:= 1 to 2 do

    begin

      Disk:= (Ide-1)*2 + MoS;

      if Not vp_DisksInfo[Disk].DiskExists then continue;

      (* Disk Exists - Go on *)

      { --- ATAdevice --- }

      if (POutBufVxD^.DisksRawInfo[Disk][0] And bit15) = 0 then

        vp_DisksInfo[Disk].ATAdevice:= True;

      { --- Removable Device --- }

      if LongBool(POutBufVxD^.DisksRawInfo[Disk][0] And bit07) then

        vp_DisksInfo[Disk].RemovableDevice:= True;

      { --- Total number of Logical Cylinders --- }

      vp_DisksInfo[Disk].TotLogCyl:= POutBufVxD^.DisksRawInfo[Disk][1];

      { --- Total number of Logical Heads --- }

      vp_DisksInfo[Disk].TotLogHeads:= POutBufVxD^.DisksRawInfo[Disk][3];

      { --- Total Logical Sectors per Logical Track --- }

      vp_DisksInfo[Disk].TotLogSPT:= POutBufVxD^.DisksRawInfo[Disk][6];

      { -- Serial Number --- }

      for fi:=10 to 19 do

      begin

        fj:= 1+ (fi-10)*2;

        vp_DisksInfo[Disk].SerialNumber[fj]:=

          Chr( Hi(POutBufVxD^.DisksRawInfo[Disk][fi]) );

        vp_DisksInfo[Disk].SerialNumber[fj+1]:=

          Chr( Lo(POutBufVxD^.DisksRawInfo[Disk][fi]) );

      end; // for fi

      // Let's adjust its length

      for fi:=1 to 20 do

        if vp_DisksInfo[Disk].SerialNumber[fi] = Chr(0) then

          break

        else

          vp_DisksInfo[Disk].SerialNumber[0]:= Chr(fi);

      { -- Firmware Revision --- }

      for fi:=23 to 26 do

      begin

        fj:= 1+ (fi-23)*2;

        vp_DisksInfo[Disk].FirmwareRevision[fj]:=

          Chr( Hi(POutBufVxD^.DisksRawInfo[Disk][fi]) );

        vp_DisksInfo[Disk].FirmwareRevision[fj+1]:=

          Chr( Lo(POutBufVxD^.DisksRawInfo[Disk][fi]) );

      end; // for fi

      // Let's adjust its length

      for fi:=1 to 8 do

        if vp_DisksInfo[Disk].FirmwareRevision[fi] = Chr(0) then

          break

        else

          vp_DisksInfo[Disk].FirmwareRevision[0]:= Chr(fi);

      { -- Model Number --- }

      for fi:=27 to 46 do

      begin

        fj:= 1+ (fi-27)*2;

        vp_DisksInfo[Disk].ModelNumber[fj]:=

          Chr( Hi(POutBufVxD^.DisksRawInfo[Disk][fi]) );

        vp_DisksInfo[Disk].ModelNumber[fj+1]:=

          Chr( Lo(POutBufVxD^.DisksRawInfo[Disk][fi]) );

      end; // for fi

      // Let's adjust its length

      for fi:=1 to 40 do

        if vp_DisksInfo[Disk].ModelNumber[fi] = Chr(0) then

          break

        else

          vp_DisksInfo[Disk].ModelNumber[0]:= Chr(fi);

      { --- Current Logical Cylinders --- }

      vp_DisksInfo[Disk].CurLogCyl:= POutBufVxD^.DisksRawInfo[Disk][54];

      { --- Current Logical Heads --- }

      vp_DisksInfo[Disk].CurLogHeads:= POutBufVxD^.DisksRawInfo[Disk][55];

      { --- Current Logical Sectors per Logical Track --- }

      vp_DisksInfo[Disk].CurLogSPT:= POutBufVxD^.DisksRawInfo[Disk][56];

    end; // NEXT MoS

  end; // NEXT Ide

  (* 4. Free the VxD output buffer memory *)

  ReallocMem (POutBufVxD, 0);

End; {IdeDInfo}

// ---------  CODE - DSIdeInf exported functions/procedures -----

FUNCTION Valid : byte; Stdcall;

Begin

  If vp_Valid then

    Valid:= 1

  else

    Valid:= 0;

End; {Valid}

FUNCTION IdeExists (a_Ide: byte) : byte; Stdcall;

Begin

  if (a_Ide < 1) or (a_Ide > 4) then  // If Invalid Ide Argument

  begin

      IdeExists:= 0;

      Exit;

  end;

  If vp_IdeExists[a_Ide] then

    IdeExists:= 1

  else

    IdeExists:= 0;

End; {IdeExists}

{ Not exported Function. Handles data as boolean type.

  Exported value is byte type}

FUNCTION bool_DiskExists (a_Disk: byte) : boolean;

Begin

  if (a_Disk < 1) or (a_Disk > 8) then

      bool_DiskExists:= False // If Invalid Disk Argument

  else

      bool_DiskExists:= vp_DisksInfo[a_Disk].DiskExists;

End; {bool_DiskExists}

FUNCTION DiskExists(a_Disk: byte) : byte; Stdcall;

Begin

  if bool_DiskExists (a_Disk) then

    DiskExists:= 1

  else

    DiskExists:= 0;

End; {DiskExists}

FUNCTION ATAdevice(a_Disk: byte) : byte; Stdcall;

Begin

  if NOT bool_DiskExists(a_Disk) then

  begin

    ATAdevice:= 0;

    Exit;

  end;

  if vp_DisksInfo[a_Disk].ATAdevice then

    ATAdevice:= 1

  else

    ATAdevice:= 0;

End; {ATAdevice}

FUNCTION RemovableDevice (a_Disk: byte): byte; Stdcall;

Begin

  if NOT bool_DiskExists (a_Disk) then

    begin

      RemovableDevice:= 0;

      Exit;

    end;

  if vp_DisksInfo[a_Disk].RemovableDevice then

    RemovableDevice:= 1

  else

    RemovableDevice:= 0;

End; {RemovableDevice}

FUNCTION TotLogCyl (a_Disk: byte): word; Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    TotLogCyl:= vp_DisksInfo[a_Disk].TotLogCyl

  else

    TotLogCyl:= 0;

End; {TotLogCyl}

FUNCTION TotLogHeads (a_Disk: byte): word; Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    TotLogHeads:= vp_DisksInfo[a_Disk].TotLogHeads

  else

    TotLogHeads:= 0;

End; {TotLogHeads}

FUNCTION TotLogSPT (a_Disk: byte): word; Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    TotLogSPT:= vp_DisksInfo[a_Disk].TotLogSPT

  else

    TotLogSPT:= 0;

End; {TotLogSPT}

PROCEDURE SerialNumber(a_Disk: byte; aP_SerialNumber: PChar); Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    StrPCopy (aP_SerialNumber, vp_DisksInfo[a_Disk].SerialNumber)

  else

    aP_SerialNumber:= '';

End; {SerialNumber}

PROCEDURE FirmwareRevision(a_Disk: byte; aP_FirmwareRevision: PChar); Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    StrPCopy (aP_FirmwareRevision, vp_DisksInfo[a_Disk].FirmwareRevision)

  else

    aP_FirmwareRevision:= '';

End; {FirmwareRevision}

PROCEDURE ModelNumber(a_Disk: byte; aP_ModelNumber: Pchar); Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    StrPCopy (aP_ModelNumber, vp_DisksInfo[a_Disk].ModelNumber)

  else

    aP_ModelNumber:= '';

End; {ModelNumber}

FUNCTION CurLogCyl (a_Disk: byte): word; Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    CurLogCyl:= vp_DisksInfo[a_Disk].CurLogCyl

  else

    CurLogCyl:= 0;

End; {CurLogCyl}

FUNCTION CurLogHeads (a_Disk: byte): word; Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    CurLogHeads:= vp_DisksInfo[a_Disk].CurLogHeads

  else

    CurLogHeads:= 0;

End; {CurLogHeads}

FUNCTION CurLogSPT (a_Disk: byte): word; Stdcall;

Begin

  if bool_DiskExists(a_Disk) then

    CurLogSPT:= vp_DisksInfo[a_Disk].CurLogSPT

  else

    CurLogSPT:= 0;

End; {CurLogSPT}

// -----------------------------------------------------------

EXPORTS

  Valid,

  IdeExists,

  DiskExists,

  ATAdevice,

  RemovableDevice,

  TotLogCyl,

  TotLogHeads,

  TotLogSPT,

  SerialNumber,

  FirmwareRevision,

  ModelNumber,

  CurLogCyl,

  CurLogHeads,

  CurLogSPT;

// --------------- CODE - DLL Initialization ----------------

BEGIN

  (* 1. Try to load the VxD *)

  VxDHandle:= CreateFile

    (PChar('\\.\DSIdeInf.VXD'), 0, 0, NIL, 0, FILE_FLAG_DELETE_ON_CLOSE, 0);

  (* 2. If loading was succesful, run its function,

          interpret and store the info, and then unload the VxD *)

    If VxDHandle <> INVALID_HANDLE_VALUE then

    begin

      vp_Valid:= True;

      IdeDInfo;     // Call VxD function, interpret and store info

      (* Unload VxD *)

      CloseHandle (VxDHandle);

    end; // If valid

END.

DSIdeinf Import Unit:

UNIT DSIdeInf_DLL_Import_Unit;

INTERFACE

FUNCTION Valid : byte;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION IdeExists (a_Ide: byte) : byte;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION DiskExists(a_Disk: byte) : byte;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION ATAdevice(a_Disk: byte) : byte;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION RemovableDevice (a_Disk: byte): byte;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION TotLogCyl (a_Disk: byte): word;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION TotLogHeads (a_Disk: byte): word;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION TotLogSPT (a_Disk: byte): word;

         Stdcall; external 'DSIdeInf.DLL';

PROCEDURE SerialNumber(a_Disk: byte; aP_SerialNumber: PChar);

         Stdcall; external 'DSIdeInf.DLL';

PROCEDURE FirmwareRevision(a_Disk: byte; aP_FirmwareRevision: PChar);

         Stdcall; external 'DSIdeInf.DLL';

PROCEDURE ModelNumber(a_Disk: byte; aP_ModelNumber: PChar);

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION CurLogCyl (a_Disk: byte): word;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION CurLogHeads (a_Disk: byte): word;

         Stdcall; external 'DSIdeInf.DLL';

FUNCTION CurLogSPT (a_Disk: byte): word;

         Stdcall; external 'DSIdeInf.DLL';

IMPLEMENTATION

END.

Y este es el fuente del archivo VXD que está en ASSEMBLER:

DSIdeInf.ASM:

TITLE DSIdeInf.asm - VxD retrieves information from IDEs

.386P

 

.NOLIST

  Include Vmm.inc

  Include VWin32.inc

  Include Shell.inc

.LIST

 

; *****  EQUATES  *****

 

  ; --- Bits ---

  cBit00 EQU 0000000000000001b

  cBit02 EQU 0000000000000100b

  cBit07 EQU 0000000010000000b

 

  ; --- Tests ---

  cERR   EQU cBit00

  cBusy  EQU cBit07

 

  ; --- Area offsets in buffer ---

  cDisk0_Exists = 4

  cDisk0_RawInfo =12

 

  ; --- GDI commands ---

  cATA_GDIcmd    EQU 0ECh    ; GDI command for ATA

  cATAPI_GDIcmd  EQU 0A1h    ; GDI command for ATAPI

 

 

; ****  MACROS  *****

 

; wPort0 has to be initialized according to IDE

WaitWhileBusy MACRO

  LOCAL LoopWhileBusy

 

    MOV   DX, [wPort0]

    ADD   DX, 7           ; DX = Port0 +7

 

  LoopWhileBusy:

    IN    AL, DX

    TEST  AX, cBusy

    JNZ LoopWhileBusy

ENDM  ; (WaitWhileBusy)

 

; wPort0 has to be initialized according to IDE

; bDevSelCmd has to be initialized according to MoS

SelectDevice MACRO

    MOV   DX, [wPort0]

    ADD   DX, 6                 ; DX = Port0 +6

    MOV   AL, [bDevSelCmd]      ; AL = DevSelCmd

 

    OUT   DX, AL

ENDM  ; (SelectDevice)

 

; wPort0 has to be initialized according to IDE

; Parameter 'GDIcmd' is GDI command (ATA or ATAPI)

SendGDIcmd MACRO GDIcmd

    MOV   DX, [wPort0]

    ADD   DX, 7                 ; DX = Port0 +7

    MOV   AL, GDIcmd

 

    OUT   DX, AL

ENDM  ; (SendGDIcmd)

 

 

; -------------------------------

; --- Device Descriptor Block ---

; -------------------------------

 

DECLARE_VIRTUAL_DEVICE \

  DSIDEINF, 1, 0, DSIDEINF_Control,\

  UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER

 

 

; ----------------------------------------

; --- Prepare Device Control Procedure ---

; ----------------------------------------

 

Begin_control_dispatch DSIDEINF

  Control_Dispatch w32_DeviceIoControl, On_DeviceIoControl

End_control_dispatch DSIDEINF

 

; ************

; **  CODE  **

; ************

 

VxD_LOCKED_CODE_SEG

 

  ; === DEVICE CONTROL PROCEDURE ===

 

  BeginProc On_DeviceIoControl

    ASSUME ESI:PTR DIOCParams

 

    .if [esi].dwIoControlCode==DIOC_Open

 

      xor eax,eax

 

    .elseif [esi].dwIoControlCode==1

 

      CALL IdesInfo

      xor eax, eax

 

    .endif

 

    RET

  EndProc On_DeviceIoControl

 

  ; Meaning of registers:

  ;   ESI: pointer to output buffer

  ;   EDI: pointer to section of 1 disk info, in output buffer

  ;   EBX: IDE (0..3)

  ;   ECX: MasterOrSlave (0..1)

 

  ;  IDE controllers:

  ;   Range: 0..3

  ;   Address of IdeExists(n) byte in output buffer

  ;     = ESI + Ide = ESI + EBX

 

  ; DISCs:

  ;   Range: 0..7

  ;   Disk = Ide*2 + MoS = EBX*2 + ECX

  ;   Address of DiskExists(n) byte in output buffer

  ;     = ESI + cDisk0_Exists + Disk

  ;   Address of Disc raw info first byte in output buffer

  ;     = ESI + cDisk0_RawInfo + Disk*512

 

  BeginProc IdesInfo

    ASSUME ESI:PTR DIOCParams

 

    ; --- Preserve registers and flags ---

 

      PUSHAD

      PUSHFD

 

    ; --- Initialize ESI as pointer to output buffer ---

 

      MOV   ESI, [ESI.lpvOutBuffer]

 

    ; --------------------------------------

    ; --- Process to get the information ---

    ; --------------------------------------

 

      ; Initialize FOR_Ide counter

      MOV   EBX, 3            ; EBX = Ide no 3

 

    FOR_Ide:                  ; FOR EBX=3 DOWNTO 0

 

    ; --- Initialize wPort0 for this IDE ---

 

      MOV   DX, [wPorts_table + EBX*2]

      MOV   wPort0, DX

 

    ; --- Check if IDE exists ---

 

      ;MOV    DX, [wPort0]

      ADD   DX, 7                 ; DX = Port0 +7

 

      IN    AL, DX

 

    ;Test0FFh

      CMP    AL, 0FFh

      JNE    Test07Fh

      JMP   NEXT_Ide              ; If AL = 0FFh, IDE not present

                                  ;   -> NEXT_Ide

 

    Test07Fh:

      CMP   AL, 07Fh

      JNE   IdeExists

      JMP   NEXT_Ide              ; If AL = 07Fh, IDE not present

                                  ;   -> NEXT_Ide

 

    IdeExists:

 

    ; --- Set value at the IdeExists area in output buffer ---

 

      MOV   BYTE PTR [ESI + EBX], 1     ; Ide_Exists = True

 

    ; --- Prepare MoS (Master or Slave) loop ---

 

      ; Initialize FOR_MoS counter

      MOV   ECX, 1                ; ECX = Slave

 

    FOR_MoS:                      ; FOR MoS=1 DOWNTO 0

 

    ; --- Get bDevSelCmd for this disc ---

 

      MOV   DL, [bDevSelCmd_table + ECX]      ; DL = DevSelCmd

      MOV   bDevSelCmd, DL

 

    ; --- Check if Disc exists ---

 

      WaitWhileBusy

      SelectDevice

      WaitWhileBusy

 

      CMP   AL, 0

      JNZ   DiskExists

      JMP   NEXT_MoS            ; If AL = 0, Disc not present

                                ;   -> NEXT_MoS

 

    DiskExists:

 

    ; Compute Disk (= Ide*2 + MoS = EBX*2 + ECX)

 

      MOV   EAX, EBX        ; EAX = Ide

      SHL   EAX, 1          ; EAX = Ide*2

      ADD   EAX, ECX        ; EAX = Disk

 

    ; --- Set value at the DiscExists area in output buffer ---

      MOV   BYTE PTR [ESI + cDisk0_Exists + EAX], 1 ; Disk_Exists = True

 

    ; --- Prepare EDI as pointer

    ; to the area where info is to be stored --

 

    ; Compute Disk*512 (knowing that 512 = 2 ^9)

 

      XCHG  AH, AL      ; Was: AL = Disk , Now: AH = Disk

                        ;   -> EAX = Disk* 2^8

      SHL   EAX, 1      ; EAX = Disk* 2^9

 

      MOV   EDI, ESI              ; EDI = @Output buffer

      ADD   EDI, cDisk0_RawInfo   ; EDI = @beginning of raw info area in output buffer

      ADD   EDI, EAX              ; EDI = @raw info section for this Disc

 

    ; ----------------- Retrieve ---------

 

      WaitWhileBusy

      SelectDevice

      SendGDIcmd cATA_GDIcmd

      WaitWhileBusy

 

      ; check error status

      MOV   DX, [wPort0]

      ADD   DX, 7                 ; DX = Port0 +7

 

      IN    AL, DX

 

      TEST  AL, cBit00

      JZ    RetrieveInfo

 

      ; ERR=1 -> try ATAPI GDI command

      WaitWhileBusy

      SelectDevice

      SendGDIcmd cATAPI_GDIcmd

      WaitWhileBusy

 

    RetrieveInfo:

      PUSH  ECX                   ; keep MoS value

 

      MOV   ECX, 256

      MOV   DX, [wPort0]

      CLD

 

      REP   INSW                  ; Retrieve (finally!)

 

      POP ECX                     ; restore MoS value

 

    NEXT_Mos:

 

      ;LOOP FOR_MoS

      CMP   ECX, 0

      JE    NEXT_Ide

      DEC   ECX

      JMP   FOR_MoS

 

    NEXT_Ide:

      ;LOOP FOR_Ide

      CMP   EBX, 0

      JE    Exit_IdeLoop

      DEC   EBX

      JMP   FOR_Ide

 

    Exit_IdeLoop:

 

    ; --- Restore flags and registers ---

 

      POPFD

      POPAD

 

      RET

  EndProc IdesInfo

 

VxD_LOCKED_CODE_ENDS

 

; ************

; **  DATA  **

; ************

 

VxD_LOCKED_DATA_SEG

 

  ; --- Tables ---

  wPorts_table      WORD  1F0h, 170h, 1E8h, 168h  ; IDE 1 - 4

  bDevSelCmd_table  BYTE  0A0h, 0B0h              ; Master - Slave

 

  ; --- Variables ---

  wPort0            WORD  ?   ; Port 0

  bDevSelCmd        BYTE  ?

 

VxD_LOCKED_DATA_ENDS

 

END

DSIdeInf.DEF:

VXD DSIDEINF DYNAMIC

SEGMENTS

         _LTEXT                            CLASS 'LCODE'                            PRELOAD NONDISCARDABLE

         _LDATA                           CLASS 'LCODE'                            PRELOAD NONDISCARDABLE

EXPORTS DSIDEINF_DDB  @1


Y Finalmente, el Código en VB:



Private Declare Function Valid Lib "DSIdeInf.DLL" _

  () As Byte

Private Declare Function IdeExists Lib "DSIdeInf.DLL" _

  (ByVal a_Ide As Byte) As Byte

Private Declare Function DiskExists Lib "DSIdeInf.DLL" _

  (ByVal a_Disk As Byte) As Byte

Private Declare Function ATAdevice Lib "DSIdeInf.DLL" _

  (ByVal a_Disk As Byte) As Byte

Private Declare Function RemovableDevice Lib "DSIdeInf.DLL" _

  (ByVal a_Disk As Byte) As Byte

Private Declare Sub SerialNumber Lib "DSIdeInf.DLL" _

  (ByVal a_Disk As Byte, ByVal aP_SerialNumber As String)

Private Declare Sub FirmwareRevision Lib "DSIdeInf.DLL" _

  (ByVal a_Disk As Byte, ByVal aP_FirmwareRevision As String)

Private Declare Sub ModelNumber Lib "DSIdeInf.DLL" _

  (ByVal a_Disk As Byte, ByVal aP_ModelNumber As String)

Private Sub btn_End_Click()

    End

End Sub

Private Sub Form_Load()

    Dim Ide, Disk As Byte

    Dim sSerialNumber As String * 21

    Dim sFirmwareRevision As String * 9

    Dim sModelNumber As String * 41

    Dim sCurLogCyl As String

  

    If Valid = 0 Then

        Mensaje = MsgBox("No se puede cargar el Archivo DSIdeInf.VXD, este archivo es necesario para la ejecución del programa, verifique que existe en la misma carpeta de el ejecutable. El programa se cerrará", vbExclamation + vbOKOnly + vbDefaultButton1 + vbApplicationModal, "No se Encuentra el archivo VXD")

        End

    End If

    

    Disk = 1

    

    ' == Serial Number ===

    Call SerialNumber(Disk, sSerialNumber)

    Text1(0).Text = sSerialNumber

    

    ' == Firmware Revision ===

    Call FirmwareRevision(Disk, sFirmwareRevision)

    Text1(1).Text = sFirmwareRevision

    

    ' == Model ===

    Call ModelNumber(Disk, sModelNumber)

    Text1(2).Text = sModelNumber

End Sub


ir al índice

Fichero con el código en Delphi, Assambler y VB (DiskInf1.zip - 42.1 KB)